summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-03-17 01:25:47 +0000
committermckusick <mckusick@FreeBSD.org>2002-03-17 01:25:47 +0000
commit14dd08fd153468502c32dc2d9c1e25a6c2d761d1 (patch)
treeee06559e7b5061e6fc6cf074dfca793dd31c681b /sys/gnu
parent34dcf8975d103d034d7e8b6788c0645cc93af254 (diff)
downloadFreeBSD-src-14dd08fd153468502c32dc2d9c1e25a6c2d761d1.zip
FreeBSD-src-14dd08fd153468502c32dc2d9c1e25a6c2d761d1.tar.gz
Add a flags parameter to VFS_VGET to pass through the desired
locking flags when acquiring a vnode. The immediate purpose is to allow polling lock requests (LK_NOWAIT) needed by soft updates to avoid deadlock when enlisting other processes to help with the background cleanup. For the future it will allow the use of shared locks for read access to vnodes. This change touches a lot of files as it affects most filesystems within the system. It has been well tested on FFS, loopback, and CD-ROM filesystems. only lightly on the others, so if you find a problem there, please let me (mckusick@mckusick.com) know.
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_alloc.c2
-rw-r--r--sys/gnu/ext2fs/ext2_ihash.c18
-rw-r--r--sys/gnu/ext2fs/ext2_lookup.c15
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c9
-rw-r--r--sys/gnu/ext2fs/ext2_vnops.c2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_alloc.c2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_lookup.c15
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c9
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c2
9 files changed, 49 insertions, 25 deletions
diff --git a/sys/gnu/ext2fs/ext2_alloc.c b/sys/gnu/ext2fs/ext2_alloc.c
index 5b04196..f078e04 100644
--- a/sys/gnu/ext2fs/ext2_alloc.c
+++ b/sys/gnu/ext2fs/ext2_alloc.c
@@ -399,7 +399,7 @@ ext2_valloc(pvp, mode, cred, vpp)
if (ino == 0)
goto noinodes;
- error = VFS_VGET(pvp->v_mount, ino, vpp);
+ error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) {
UFS_VFREE(pvp, ino, mode);
return (error);
diff --git a/sys/gnu/ext2fs/ext2_ihash.c b/sys/gnu/ext2fs/ext2_ihash.c
index d1537af..d31add3 100644
--- a/sys/gnu/ext2fs/ext2_ihash.c
+++ b/sys/gnu/ext2fs/ext2_ihash.c
@@ -93,15 +93,19 @@ ufs_ihashlookup(dev, inum)
* Use the device/inum pair to find the incore inode, and return a pointer
* to it. If it is in core, but locked, wait for it.
*/
-struct vnode *
-ufs_ihashget(dev, inum)
+int
+ufs_ihashget(dev, inum, flags, vpp)
dev_t dev;
ino_t inum;
+ int flags;
+ struct vnode **vpp;
{
struct thread *td = curthread; /* XXX */
struct inode *ip;
struct vnode *vp;
+ int error;
+ *vpp = NULL;
loop:
mtx_lock(&ufs_ihash_mtx);
LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
@@ -109,13 +113,17 @@ loop:
vp = ITOV(ip);
mtx_lock(&vp->v_interlock);
mtx_unlock(&ufs_ihash_mtx);
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td))
+ error = vget(vp, flags | LK_INTERLOCK, td);
+ if (error == ENOENT)
goto loop;
- return (vp);
+ if (error)
+ return (error);
+ *vpp = vp;
+ return (0);
}
}
mtx_unlock(&ufs_ihash_mtx);
- return (NULL);
+ return (0);
}
/*
diff --git a/sys/gnu/ext2fs/ext2_lookup.c b/sys/gnu/ext2fs/ext2_lookup.c
index b2e1511..50479e0 100644
--- a/sys/gnu/ext2fs/ext2_lookup.c
+++ b/sys/gnu/ext2fs/ext2_lookup.c
@@ -601,7 +601,8 @@ found:
*vpp = vdp;
return (0);
}
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
/*
* If directory is "sticky", then user must own
@@ -638,7 +639,8 @@ found:
*/
if (dp->i_number == dp->i_ino)
return (EISDIR);
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
@@ -669,7 +671,8 @@ found:
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0) {
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
return (error);
}
@@ -683,7 +686,8 @@ found:
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp, 0, td);
@@ -1064,7 +1068,8 @@ ext2_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino)
break;
vput(vp);
- if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp)) != 0) {
+ if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino,
+ LK_EXCLUSIVE, &vp)) != 0) {
vp = NULL;
break;
}
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index 15a94d9..8a7cc07 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -80,7 +80,7 @@ static int ext2_sbupdate __P((struct ufsmount *, int));
static int ext2_statfs __P((struct mount *, struct statfs *, struct thread *));
static int ext2_sync __P((struct mount *, int, struct ucred *, struct thread *));
static int ext2_unmount __P((struct mount *, int, struct thread *));
-static int ext2_vget __P((struct mount *, ino_t, struct vnode **));
+static int ext2_vget __P((struct mount *, ino_t, int, struct vnode **));
static int ext2_vptofh __P((struct vnode *, struct fid *));
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@@ -982,9 +982,10 @@ loop:
* done by the calling routine.
*/
static int
-ext2_vget(mp, ino, vpp)
+ext2_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
register struct ext2_sb_info *fs;
@@ -999,7 +1000,9 @@ ext2_vget(mp, ino, vpp)
ump = VFSTOUFS(mp);
dev = ump->um_dev;
restart:
- if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
+ if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
+ return (error);
+ if (*vpp != NULL)
return (0);
/*
diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c
index ad60728..a90c20f 100644
--- a/sys/gnu/ext2fs/ext2_vnops.c
+++ b/sys/gnu/ext2fs/ext2_vnops.c
@@ -285,7 +285,7 @@ ext2_mknod(ap)
(*vpp)->v_type = VNON;
ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) {
*vpp = NULL;
return (error);
diff --git a/sys/gnu/fs/ext2fs/ext2_alloc.c b/sys/gnu/fs/ext2fs/ext2_alloc.c
index 5b04196..f078e04 100644
--- a/sys/gnu/fs/ext2fs/ext2_alloc.c
+++ b/sys/gnu/fs/ext2fs/ext2_alloc.c
@@ -399,7 +399,7 @@ ext2_valloc(pvp, mode, cred, vpp)
if (ino == 0)
goto noinodes;
- error = VFS_VGET(pvp->v_mount, ino, vpp);
+ error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) {
UFS_VFREE(pvp, ino, mode);
return (error);
diff --git a/sys/gnu/fs/ext2fs/ext2_lookup.c b/sys/gnu/fs/ext2fs/ext2_lookup.c
index b2e1511..50479e0 100644
--- a/sys/gnu/fs/ext2fs/ext2_lookup.c
+++ b/sys/gnu/fs/ext2fs/ext2_lookup.c
@@ -601,7 +601,8 @@ found:
*vpp = vdp;
return (0);
}
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
/*
* If directory is "sticky", then user must own
@@ -638,7 +639,8 @@ found:
*/
if (dp->i_number == dp->i_ino)
return (EISDIR);
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
@@ -669,7 +671,8 @@ found:
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0) {
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
return (error);
}
@@ -683,7 +686,8 @@ found:
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
+ &tdp)) != 0)
return (error);
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp, 0, td);
@@ -1064,7 +1068,8 @@ ext2_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino)
break;
vput(vp);
- if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp)) != 0) {
+ if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino,
+ LK_EXCLUSIVE, &vp)) != 0) {
vp = NULL;
break;
}
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index 15a94d9..8a7cc07 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -80,7 +80,7 @@ static int ext2_sbupdate __P((struct ufsmount *, int));
static int ext2_statfs __P((struct mount *, struct statfs *, struct thread *));
static int ext2_sync __P((struct mount *, int, struct ucred *, struct thread *));
static int ext2_unmount __P((struct mount *, int, struct thread *));
-static int ext2_vget __P((struct mount *, ino_t, struct vnode **));
+static int ext2_vget __P((struct mount *, ino_t, int, struct vnode **));
static int ext2_vptofh __P((struct vnode *, struct fid *));
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@@ -982,9 +982,10 @@ loop:
* done by the calling routine.
*/
static int
-ext2_vget(mp, ino, vpp)
+ext2_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
register struct ext2_sb_info *fs;
@@ -999,7 +1000,9 @@ ext2_vget(mp, ino, vpp)
ump = VFSTOUFS(mp);
dev = ump->um_dev;
restart:
- if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
+ if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
+ return (error);
+ if (*vpp != NULL)
return (0);
/*
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index ad60728..a90c20f 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -285,7 +285,7 @@ ext2_mknod(ap)
(*vpp)->v_type = VNON;
ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) {
*vpp = NULL;
return (error);
OpenPOWER on IntegriCloud