summaryrefslogtreecommitdiffstats
path: root/sys/ufs
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/ufs
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/ufs')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c6
-rw-r--r--sys/ufs/ffs/ffs_extern.h2
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c3
-rw-r--r--sys/ufs/ffs/ffs_softdep.c67
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c9
-rw-r--r--sys/ufs/ffs/softdep.h1
-rw-r--r--sys/ufs/ifs/ifs_lookup.c2
-rw-r--r--sys/ufs/ifs/ifs_vfsops.c10
-rw-r--r--sys/ufs/ufs/ufs_extern.h3
-rw-r--r--sys/ufs/ufs/ufs_ihash.c18
-rw-r--r--sys/ufs/ufs/ufs_lookup.c50
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c4
-rw-r--r--sys/ufs/ufs/ufs_vnops.c2
13 files changed, 96 insertions, 81 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 93e8c99..374c0b9 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -629,7 +629,7 @@ ffs_valloc(pvp, mode, cred, vpp)
(allocfcn_t *)ffs_nodealloccg);
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);
@@ -1977,7 +1977,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
cmd.size);
}
#endif /* DEBUG */
- if ((error = VFS_VGET(mp, (ino_t)cmd.value, &vp)) != 0)
+ if ((error = VFS_VGET(mp, (ino_t)cmd.value, LK_EXCLUSIVE, &vp)))
break;
ip = VTOI(vp);
ip->i_nlink += cmd.size;
@@ -1996,7 +1996,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
cmd.size);
}
#endif /* DEBUG */
- if ((error = VFS_VGET(mp, (ino_t)cmd.value, &vp)) != 0)
+ if ((error = VFS_VGET(mp, (ino_t)cmd.value, LK_EXCLUSIVE, &vp)))
break;
ip = VTOI(vp);
ip->i_blocks += cmd.size;
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index cfcdcbd..1da7153 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -93,7 +93,7 @@ int ffs_update __P((struct vnode *, int));
int ffs_valloc __P((struct vnode *, int, struct ucred *, struct vnode **));
int ffs_vfree __P((struct vnode *, ino_t, int));
-int ffs_vget __P((struct mount *, ino_t, struct vnode **));
+int ffs_vget __P((struct mount *, ino_t, int, struct vnode **));
int ffs_vptofh __P((struct vnode *, struct fid *));
extern vop_t **ffs_vnodeop_p;
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index faca50f..a14fbea 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -1177,7 +1177,8 @@ ffs_snapshot_mount(mp)
for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) {
if (fs->fs_snapinum[snaploc] == 0)
return;
- if ((error = VFS_VGET(mp, fs->fs_snapinum[snaploc], &vp)) != 0){
+ if ((error = VFS_VGET(mp, fs->fs_snapinum[snaploc],
+ LK_EXCLUSIVE, &vp)) != 0){
printf("ffs_snapshot_mount: vget failed %d\n", error);
continue;
}
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 475ba17..5110b8c 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -165,7 +165,7 @@ static void initiate_write_filepage __P((struct pagedep *, struct buf *));
static void handle_written_mkdir __P((struct mkdir *, int));
static void initiate_write_inodeblock __P((struct inodedep *, struct buf *));
static void handle_workitem_freefile __P((struct freefile *));
-static void handle_workitem_remove __P((struct dirrem *));
+static void handle_workitem_remove __P((struct dirrem *, struct vnode *));
static struct dirrem *newdirrem __P((struct buf *, struct inode *,
struct inode *, int, struct dirrem **));
static void free_diradd __P((struct diradd *));
@@ -580,7 +580,7 @@ softdep_process_worklist(matchmnt)
struct mount *matchmnt;
{
struct thread *td = curthread;
- int matchcnt, loopcount;
+ int cnt, matchcnt, loopcount;
long starttime;
/*
@@ -618,7 +618,10 @@ softdep_process_worklist(matchmnt)
loopcount = 1;
starttime = time_second;
while (num_on_worklist > 0) {
- matchcnt += process_worklist_item(matchmnt, 0);
+ if ((cnt = process_worklist_item(matchmnt, 0)) == -1)
+ break;
+ else
+ matchcnt += cnt;
/*
* If a umount operation wants to run the worklist
@@ -675,7 +678,6 @@ process_worklist_item(matchmnt, flags)
int flags;
{
struct worklist *wk;
- struct dirrem *dirrem;
struct mount *mp;
struct vnode *vp;
int matchcnt = 0;
@@ -687,13 +689,19 @@ process_worklist_item(matchmnt, flags)
* inodes, we have to skip over any dirrem requests whose
* vnodes are resident and locked.
*/
+ vp = NULL;
LIST_FOREACH(wk, &softdep_workitem_pending, wk_list) {
+ if (wk->wk_state & INPROGRESS)
+ continue;
if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
break;
- dirrem = WK_DIRREM(wk);
- vp = ufs_ihashlookup(VFSTOUFS(dirrem->dm_mnt)->um_dev,
- dirrem->dm_oldinum);
- if (vp == NULL || !VOP_ISLOCKED(vp, curthread))
+ wk->wk_state |= INPROGRESS;
+ FREE_LOCK(&lk);
+ VFS_VGET(WK_DIRREM(wk)->dm_mnt, WK_DIRREM(wk)->dm_oldinum,
+ LK_NOWAIT | LK_EXCLUSIVE, &vp);
+ ACQUIRE_LOCK(&lk);
+ wk->wk_state &= ~INPROGRESS;
+ if (vp != NULL)
break;
}
if (wk == 0) {
@@ -713,7 +721,7 @@ process_worklist_item(matchmnt, flags)
"process_worklist_item");
if (mp == matchmnt)
matchcnt += 1;
- handle_workitem_remove(WK_DIRREM(wk));
+ handle_workitem_remove(WK_DIRREM(wk), vp);
break;
case D_FREEBLKS:
@@ -2280,8 +2288,9 @@ handle_workitem_freeblocks(freeblks, flags)
* to see if the block count needs to be adjusted.
*/
if (freeblks->fb_chkcnt != blocksreleased &&
- (fs->fs_flags & FS_UNCLEAN) != 0 && (flags & LK_NOWAIT) == 0 &&
- VFS_VGET(freeblks->fb_mnt, freeblks->fb_previousinum, &vp) == 0) {
+ (fs->fs_flags & FS_UNCLEAN) != 0 &&
+ VFS_VGET(freeblks->fb_mnt, freeblks->fb_previousinum,
+ (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp) == 0) {
ip = VTOI(vp);
ip->i_blocks += freeblks->fb_chkcnt - blocksreleased;
ip->i_flag |= IN_CHANGE;
@@ -2742,7 +2751,7 @@ softdep_setup_remove(bp, dp, ip, isrmdir)
prevdirrem, dm_next);
dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino;
FREE_LOCK(&lk);
- handle_workitem_remove(dirrem);
+ handle_workitem_remove(dirrem, NULL);
}
}
@@ -3033,8 +3042,9 @@ softdep_releasefile(ip)
* If the link count reaches zero, the file is removed.
*/
static void
-handle_workitem_remove(dirrem)
+handle_workitem_remove(dirrem, xp)
struct dirrem *dirrem;
+ struct vnode *xp;
{
struct thread *td = curthread;
struct inodedep *inodedep;
@@ -3043,7 +3053,9 @@ handle_workitem_remove(dirrem)
ino_t oldinum;
int error;
- if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
+ if ((vp = xp) == NULL &&
+ (error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, LK_EXCLUSIVE,
+ &vp)) != 0) {
softdep_error("handle_workitem_remove: vget", error);
return;
}
@@ -3112,7 +3124,7 @@ handle_workitem_remove(dirrem)
check_inode_unwritten(inodedep)) {
FREE_LOCK(&lk);
vput(vp);
- handle_workitem_remove(dirrem);
+ handle_workitem_remove(dirrem, NULL);
return;
}
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
@@ -4228,16 +4240,19 @@ softdep_fsync(vp)
/*
* We prevent deadlock by always fetching inodes from the
* root, moving down the directory tree. Thus, when fetching
- * our parent directory, we must unlock ourselves before
- * requesting the lock on our parent. See the comment in
- * ufs_lookup for details on possible races.
+ * our parent directory, we first try to get the lock. If
+ * that fails, we must unlock ourselves before requesting
+ * the lock on our parent. See the comment in ufs_lookup
+ * for details on possible races.
*/
FREE_LOCK(&lk);
- VOP_UNLOCK(vp, 0, td);
- error = VFS_VGET(mnt, parentino, &pvp);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- if (error != 0)
- return (error);
+ if (VFS_VGET(mnt, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp)) {
+ VOP_UNLOCK(vp, 0, td);
+ error = VFS_VGET(mnt, parentino, LK_EXCLUSIVE, &pvp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+ if (error != 0)
+ return (error);
+ }
/*
* All MKDIR_PARENT dependencies and all the NEWBLOCK pagedeps
* that are contained in direct blocks will be resolved by
@@ -4735,7 +4750,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
inum = dap->da_newinum;
if (dap->da_state & MKDIR_BODY) {
FREE_LOCK(&lk);
- if ((error = VFS_VGET(mp, inum, &vp)) != 0)
+ if ((error = VFS_VGET(mp, inum, LK_EXCLUSIVE, &vp)))
break;
if ((error=VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td)) ||
(error=VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td))) {
@@ -4999,7 +5014,7 @@ clear_remove(td)
FREE_LOCK(&lk);
if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
continue;
- if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
+ if ((error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &vp))) {
softdep_error("clear_remove: vget", error);
vn_finished_write(mp);
return;
@@ -5072,7 +5087,7 @@ clear_inodedeps(td)
FREE_LOCK(&lk);
if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
continue;
- if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
+ if ((error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &vp)) != 0) {
softdep_error("clear_inodedeps: vget", error);
vn_finished_write(mp);
return;
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index ce4198c..025d30a 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -158,7 +158,6 @@ ffs_mount(mp, path, data, ndp, td)
if ((error = ffs_mountfs(rootvp, mp, td, M_FFSNODE)) != 0)
return (error);
-
(void)VFS_STATFS(mp, &mp->mnt_stat, td);
return (0);
}
@@ -1143,9 +1142,10 @@ static int ffs_inode_hash_lock;
static struct mtx ffs_inode_hash_mtx;
int
-ffs_vget(mp, ino, vpp)
+ffs_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
struct fs *fs;
@@ -1159,9 +1159,10 @@ ffs_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);
- }
/*
* Lock out the creation of new entries in the FFS hash table in
diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h
index 5610bdc..cdb1f68 100644
--- a/sys/ufs/ffs/softdep.h
+++ b/sys/ufs/ffs/softdep.h
@@ -101,6 +101,7 @@
#define IOSTARTED 0x0200 /* inodedep & pagedep only */
#define SPACECOUNTED 0x0400 /* inodedep only */
#define NEWBLOCK 0x0800 /* pagedep only */
+#define INPROGRESS 0x1000 /* dirrem, freeblks, freefrag, freefile only */
#define ONWORKLIST 0x8000
#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE)
diff --git a/sys/ufs/ifs/ifs_lookup.c b/sys/ufs/ifs/ifs_lookup.c
index c6e5873..510b02b 100644
--- a/sys/ufs/ifs/ifs_lookup.c
+++ b/sys/ufs/ifs/ifs_lookup.c
@@ -242,7 +242,7 @@ ifs_lookup(ap)
return ENOENT;
}
/* Now, we can get the vnode */
- error = VFS_VGET(vdp->v_mount, (long)inodenum, &tdp);
+ error = VFS_VGET(vdp->v_mount, (long)inodenum, LK_EXCLUSIVE, &tdp);
if (error)
return (error);
if (!lockparent || !(flags & ISLASTCN))
diff --git a/sys/ufs/ifs/ifs_vfsops.c b/sys/ufs/ifs/ifs_vfsops.c
index 7eade14..b86048f 100644
--- a/sys/ufs/ifs/ifs_vfsops.c
+++ b/sys/ufs/ifs/ifs_vfsops.c
@@ -71,7 +71,7 @@ static MALLOC_DEFINE(M_IFSNODE, "IFS node", "IFS vnode private part");
static int ifs_init (struct vfsconf *);
static int ifs_mount (struct mount *, char *, caddr_t,
struct nameidata *, struct thread *);
-extern int ifs_vget (struct mount *, ino_t, struct vnode **);
+extern int ifs_vget (struct mount *, ino_t, int, struct vnode **);
@@ -151,9 +151,10 @@ ifs_init(vfsp)
}
int
-ifs_vget(mp, ino, vpp)
+ifs_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
struct fs *fs;
@@ -167,9 +168,10 @@ ifs_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);
- }
/*
* Lock out the creation of new entries in the FFS hash table in
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index c4e2795..dc59164 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -74,8 +74,7 @@ int ufs_direnter __P((struct vnode *, struct vnode *, struct direct *,
int ufs_dirremove __P((struct vnode *, struct inode *, int, int));
int ufs_dirrewrite __P((struct inode *, struct inode *, ino_t, int, int));
int ufs_getlbns __P((struct vnode *, ufs_daddr_t, struct indir *, int *));
-struct vnode *
- ufs_ihashget __P((dev_t, ino_t));
+int ufs_ihashget __P((dev_t, ino_t, int, struct vnode **));
void ufs_ihashinit __P((void));
void ufs_ihashins __P((struct inode *));
struct vnode *
diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c
index d1537af..d31add3 100644
--- a/sys/ufs/ufs/ufs_ihash.c
+++ b/sys/ufs/ufs/ufs_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/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index bbb07af..a668a18 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -508,14 +508,8 @@ found:
*vpp = vdp;
return (0);
}
- if (flags & ISDOTDOT)
- VOP_UNLOCK(vdp, 0, td); /* race to get the inode */
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
- if (flags & ISDOTDOT) {
- if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, td) != 0)
- cnp->cn_flags |= PDIRUNLOCK;
- }
- if (error)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp)) != 0)
return (error);
/*
* If directory is "sticky", then user must own
@@ -544,7 +538,7 @@ found:
* regular file, or empty directory.
*/
if (nameiop == RENAME && wantparent && (flags & ISLASTCN)) {
- if ((error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread)) != 0)
+ if ((error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread)))
return (error);
/*
* Careful about locking second inode.
@@ -552,14 +546,8 @@ found:
*/
if (dp->i_number == dp->i_ino)
return (EISDIR);
- if (flags & ISDOTDOT)
- VOP_UNLOCK(vdp, 0, td); /* race to get the inode */
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
- if (flags & ISDOTDOT) {
- if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, td) != 0)
- cnp->cn_flags |= PDIRUNLOCK;
- }
- if (error)
+ if ((error = VFS_VGET(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp)) != 0)
return (error);
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
@@ -591,26 +579,25 @@ found:
*/
pdp = vdp;
if (flags & ISDOTDOT) {
- VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
- cnp->cn_flags |= PDIRUNLOCK;
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
- if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td) == 0)
- cnp->cn_flags &= ~PDIRUNLOCK;
- return (error);
- }
- if (lockparent && (flags & ISLASTCN)) {
- if ((error = vn_lock(pdp, LK_EXCLUSIVE, td)) != 0) {
- vput(tdp);
+ if ((VFS_VGET(pdp->v_mount, dp->i_ino, LK_NOWAIT | LK_EXCLUSIVE,
+ &tdp)) != 0) {
+ VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
+ error = VFS_VGET(pdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp);
+ vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
+ if (error)
return (error);
- }
- cnp->cn_flags &= ~PDIRUNLOCK;
+ }
+ if (!lockparent || !(flags & ISLASTCN)) {
+ VOP_UNLOCK(pdp, 0, td);
+ cnp->cn_flags |= PDIRUNLOCK;
}
*vpp = tdp;
} else if (dp->i_number == dp->i_ino) {
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
+ error = VFS_VGET(pdp->v_mount, dp->i_ino, LK_EXCLUSIVE, &tdp);
if (error)
return (error);
if (!lockparent || !(flags & ISLASTCN)) {
@@ -1254,7 +1241,8 @@ ufs_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino)
break;
vput(vp);
- error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp);
+ error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino,
+ LK_EXCLUSIVE, &vp);
if (error) {
vp = NULL;
break;
diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c
index e6cbd6c..c9176d9 100644
--- a/sys/ufs/ufs/ufs_vfsops.c
+++ b/sys/ufs/ufs/ufs_vfsops.c
@@ -84,7 +84,7 @@ ufs_root(mp, vpp)
struct vnode *nvp;
int error;
- error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp);
+ error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp);
if (error)
return (error);
*vpp = nvp;
@@ -199,7 +199,7 @@ ufs_fhtovp(mp, ufhp, vpp)
struct vnode *nvp;
int error;
- error = VFS_VGET(mp, ufhp->ufid_ino, &nvp);
+ error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
if (error) {
*vpp = NULLVP;
return (error);
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index bf05ff3..9dd3eab 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -244,7 +244,7 @@ ufs_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