summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/coda/coda_vnops.c2
-rw-r--r--sys/fs/cd9660/cd9660_lookup.c6
-rw-r--r--sys/fs/cd9660/cd9660_node.c18
-rw-r--r--sys/fs/cd9660/cd9660_node.h2
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c30
-rw-r--r--sys/fs/cd9660/iso.h2
-rw-r--r--sys/fs/coda/coda_vnops.c2
-rw-r--r--sys/fs/hpfs/hpfs.h2
-rw-r--r--sys/fs/hpfs/hpfs_hash.c18
-rw-r--r--sys/fs/hpfs/hpfs_subr.c5
-rw-r--r--sys/fs/hpfs/hpfs_vfsops.c18
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c26
-rw-r--r--sys/fs/ntfs/ntfs_subr.c2
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c16
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c4
-rw-r--r--sys/fs/nullfs/null_vfsops.c8
-rw-r--r--sys/fs/smbfs/smbfs_vfsops.c6
-rw-r--r--sys/fs/umapfs/umap_vfsops.c7
-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
-rw-r--r--sys/isofs/cd9660/cd9660_lookup.c6
-rw-r--r--sys/isofs/cd9660/cd9660_node.c18
-rw-r--r--sys/isofs/cd9660/cd9660_node.h2
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c30
-rw-r--r--sys/isofs/cd9660/iso.h2
-rw-r--r--sys/kern/vfs_default.c3
-rw-r--r--sys/nfsserver/nfs_serv.c6
-rw-r--r--sys/sys/mount.h7
-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
48 files changed, 308 insertions, 191 deletions
diff --git a/sys/coda/coda_vnops.c b/sys/coda/coda_vnops.c
index 646ee34..c47d309 100644
--- a/sys/coda/coda_vnops.c
+++ b/sys/coda/coda_vnops.c
@@ -1854,7 +1854,7 @@ coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp)
}
/* XXX - ensure that nonzero-return means failure */
- error = VFS_VGET(mp,ino,vpp);
+ error = VFS_VGET(mp,ino,LK_EXCLUSIVE,vpp);
if (error) {
myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n",
(u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error));
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c
index 706a7ae..da927e1 100644
--- a/sys/fs/cd9660/cd9660_lookup.c
+++ b/sys/fs/cd9660/cd9660_lookup.c
@@ -352,7 +352,8 @@ found:
*/
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
- error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error) {
@@ -373,7 +374,8 @@ found:
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error)
diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c
index 53ffeca..0060364 100644
--- a/sys/fs/cd9660/cd9660_node.c
+++ b/sys/fs/cd9660/cd9660_node.c
@@ -92,15 +92,19 @@ cd9660_uninit(vfsp)
* 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 *
-cd9660_ihashget(dev, inum)
+int
+cd9660_ihashget(dev, inum, flags, vpp)
dev_t dev;
ino_t inum;
+ int flags;
+ struct vnode **vpp;
{
struct thread *td = curthread; /* XXX */
struct iso_node *ip;
struct vnode *vp;
+ int error;
+ *vpp = NULL;
loop:
mtx_lock(&cd9660_ihash_mtx);
for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
@@ -108,13 +112,17 @@ loop:
vp = ITOV(ip);
mtx_lock(&vp->v_interlock);
mtx_unlock(&cd9660_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(&cd9660_ihash_mtx);
- return (NULL);
+ return (0);
}
/*
diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h
index 100c08e..2a0d7ef 100644
--- a/sys/fs/cd9660/cd9660_node.h
+++ b/sys/fs/cd9660/cd9660_node.h
@@ -117,7 +117,7 @@ void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
-struct vnode *cd9660_ihashget __P((dev_t, ino_t));
+int cd9660_ihashget __P((dev_t, ino_t, int, struct vnode **));
void cd9660_ihashins __P((struct iso_node *));
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index 1e3719d..60a7b38 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -69,7 +69,7 @@ static int cd9660_mount __P((struct mount *,
static int cd9660_unmount __P((struct mount *, int, struct thread *));
static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct thread *));
-static int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
+static int cd9660_vget __P((struct mount *, ino_t, int, struct vnode **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_vptofh __P((struct vnode *, struct fid *));
@@ -578,7 +578,7 @@ cd9660_root(mp, vpp)
* With RRIP we must use the `.' entry of the root directory.
* Simply tell vget, that it's a relocated directory.
*/
- return (cd9660_vget_internal(mp, ino, vpp,
+ return (cd9660_vget_internal(mp, ino, LK_EXCLUSIVE, vpp,
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
}
@@ -644,7 +644,7 @@ cd9660_fhtovp(mp, fhp, vpp)
ifhp->ifid_ino, ifhp->ifid_start);
#endif
- if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, ifhp->ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
@@ -659,9 +659,10 @@ cd9660_fhtovp(mp, fhp, vpp)
}
int
-cd9660_vget(mp, ino, vpp)
+cd9660_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
@@ -671,7 +672,7 @@ cd9660_vget(mp, ino, vpp)
* and force the extra read, but I don't want to think about fixing
* that right now.
*/
- return (cd9660_vget_internal(mp, ino, vpp,
+ return (cd9660_vget_internal(mp, ino, flags, vpp,
#if 0
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
#else
@@ -681,9 +682,10 @@ cd9660_vget(mp, ino, vpp)
}
int
-cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
+cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
int relocated;
struct iso_directory_record *isodir;
@@ -697,7 +699,9 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
imp = VFSTOISOFS(mp);
dev = imp->im_dev;
- if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
+ if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0)
+ return (error);
+ if (*vpp != NULL)
return (0);
/* Allocate a new vnode/iso_node. */
@@ -718,6 +722,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
ip->i_number = ino;
/*
+ * Check to be sure that it did not show up. We have to put it
+ * on the hash chain as the cleanup from vput expects to find
+ * it there.
+ */
+ if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0 ||
+ *vpp != NULL) {
+ cd9660_ihashins(ip);
+ vput(vp);
+ return (error);
+ }
+
+ /*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h
index b62c723..453423a 100644
--- a/sys/fs/cd9660/iso.h
+++ b/sys/fs/cd9660/iso.h
@@ -254,7 +254,7 @@ struct iso_mnt {
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
-int cd9660_vget_internal __P((struct mount *, ino_t, struct vnode **, int,
+int cd9660_vget_internal __P((struct mount *, ino_t, int, struct vnode **, int,
struct iso_directory_record *));
int cd9660_init __P((struct vfsconf *));
int cd9660_uninit __P((struct vfsconf *));
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index 646ee34..c47d309 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -1854,7 +1854,7 @@ coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp)
}
/* XXX - ensure that nonzero-return means failure */
- error = VFS_VGET(mp,ino,vpp);
+ error = VFS_VGET(mp,ino,LK_EXCLUSIVE,vpp);
if (error) {
myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n",
(u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error));
diff --git a/sys/fs/hpfs/hpfs.h b/sys/fs/hpfs/hpfs.h
index bd90ce4..ec2cfad 100644
--- a/sys/fs/hpfs/hpfs.h
+++ b/sys/fs/hpfs/hpfs.h
@@ -393,7 +393,7 @@ void hpfs_hphashinit __P((void));
void hpfs_hphashdestroy __P((void));
struct hpfsnode *hpfs_hphashlookup __P((dev_t, lsn_t));
struct hpfsnode *hpfs_hphashget __P((dev_t, lsn_t));
-struct vnode *hpfs_hphashvget __P((dev_t, lsn_t, struct thread *));
+int hpfs_hphashvget __P((dev_t, lsn_t, int, struct vnode **, struct thread *));
void hpfs_hphashins __P((register struct hpfsnode *));
void hpfs_hphashrem __P((register struct hpfsnode *));
extern struct lock hpfs_hphash_lock;
diff --git a/sys/fs/hpfs/hpfs_hash.c b/sys/fs/hpfs/hpfs_hash.c
index 1c6601a..0a04a9a 100644
--- a/sys/fs/hpfs/hpfs_hash.c
+++ b/sys/fs/hpfs/hpfs_hash.c
@@ -122,15 +122,19 @@ loop:
}
#endif
-struct vnode *
-hpfs_hphashvget(dev, ino, td)
+int
+hpfs_hphashvget(dev, ino, flags, vpp, td)
dev_t dev;
lsn_t ino;
+ int flags;
+ struct vnode **vpp;
struct thread *td;
{
struct hpfsnode *hp;
struct vnode *vp;
+ int error;
+ *vpp = NULLVP;
loop:
mtx_lock(&hpfs_hphash_mtx);
LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) {
@@ -138,13 +142,17 @@ loop:
vp = HPTOV(hp);
mtx_lock(&vp->v_interlock);
mtx_unlock(&hpfs_hphash_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(&hpfs_hphash_mtx);
- return (NULLVP);
+ return (0);
}
/*
diff --git a/sys/fs/hpfs/hpfs_subr.c b/sys/fs/hpfs/hpfs_subr.c
index 5fa32a5..b45ebbd 100644
--- a/sys/fs/hpfs/hpfs_subr.c
+++ b/sys/fs/hpfs/hpfs_subr.c
@@ -536,7 +536,8 @@ hpfs_validateparent (
if (hp->h_no == hp->h_fn.fn_parent) {
dhp = hp;
} else {
- error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent, &dvp);
+ error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent,
+ LK_EXCLUSIVE, &dvp);
if (error)
return (error);
dhp = VTOHP(dvp);
@@ -689,7 +690,7 @@ hpfs_updateparent (
dhp = hp;
} else {
error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
- &dvp);
+ LK_EXCLUSIVE, &dvp);
if (error)
return (error);
dhp = VTOHP(dvp);
diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c
index dcb5995..cf3c114 100644
--- a/sys/fs/hpfs/hpfs_vfsops.c
+++ b/sys/fs/hpfs/hpfs_vfsops.c
@@ -59,7 +59,7 @@ static int hpfs_root __P((struct mount *, struct vnode **));
static int hpfs_statfs __P((struct mount *, struct statfs *,
struct thread *));
static int hpfs_unmount __P((struct mount *, int, struct thread *));
-static int hpfs_vget __P((struct mount *mp, ino_t ino,
+static int hpfs_vget __P((struct mount *mp, ino_t ino, int flags,
struct vnode **vpp));
static int hpfs_mountfs __P((register struct vnode *, struct mount *,
struct hpfs_args *, struct thread *));
@@ -380,7 +380,7 @@ hpfs_root(
struct hpfsmount *hpmp = VFSTOHPFS(mp);
dprintf(("hpfs_root():\n"));
- error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, vpp);
+ error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, LK_EXCLUSIVE, vpp);
if(error) {
printf("hpfs_root: VFS_VGET failed: %d\n",error);
return (error);
@@ -429,7 +429,7 @@ hpfs_fhtovp(
struct hpfid *hpfhp = (struct hpfid *)fhp;
int error;
- if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
@@ -460,6 +460,7 @@ static int
hpfs_vget(
struct mount *mp,
ino_t ino,
+ int flags,
struct vnode **vpp)
{
struct hpfsmount *hpmp = VFSTOHPFS(mp);
@@ -475,7 +476,9 @@ hpfs_vget(
hp = NULL;
vp = NULL;
- if ((*vpp = hpfs_hphashvget(hpmp->hpm_dev, ino, td)) != NULL) {
+ if ((error = hpfs_hphashvget(hpmp->hpm_dev, ino, flags, vpp, td)) != 0)
+ return (error);
+ if (*vpp != NULL) {
dprintf(("hashed\n"));
return (0);
}
@@ -531,7 +534,12 @@ hpfs_vget(
}
do {
- if ((*vpp = hpfs_hphashvget(hpmp->hpm_dev, ino, td)) != NULL) {
+ if ((error =
+ hpfs_hphashvget(hpmp->hpm_dev, ino, flags, vpp, td))) {
+ vput(vp);
+ return (error);
+ }
+ if (*vpp != NULL) {
dprintf(("hashed2\n"));
vput(vp);
return (0);
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
index e3ed555..7b4d731 100644
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ b/sys/fs/hpfs/hpfs_vnops.c
@@ -1096,21 +1096,18 @@ hpfs_lookup(ap)
dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n",
dhp->h_no, dhp->h_fn.fn_parent));
- VOP_UNLOCK(dvp,0,cnp->cn_thread);
-
- error = VFS_VGET(hpmp->hpm_mp,
- dhp->h_fn.fn_parent, ap->a_vpp);
- if(error) {
+ if (VFS_VGET(hpmp->hpm_mp, dhp->h_fn.fn_parent,
+ LK_NOWAIT | LK_EXCLUSIVE, ap->a_vpp)) {
+ VOP_UNLOCK(dvp,0,cnp->cn_thread);
+ error = VFS_VGET(hpmp->hpm_mp,
+ dhp->h_fn.fn_parent, LK_EXCLUSIVE, ap->a_vpp);
VOP_LOCK(dvp, 0, cnp->cn_thread);
- return(error);
- }
-
- if( lockparent && (flags & ISLASTCN) &&
- (error = VOP_LOCK(dvp, 0, cnp->cn_thread)) ) {
- vput( *(ap->a_vpp) );
- return (error);
+ if(error)
+ return(error);
}
- return (error);
+ if (!lockparent || !(flags & ISLASTCN))
+ VOP_UNLOCK(dvp,0,cnp->cn_thread);
+ return (0);
} else {
struct buf *bp;
struct hpfsdirent *dep;
@@ -1148,7 +1145,8 @@ hpfs_lookup(ap)
return (0);
}
- error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, ap->a_vpp);
+ error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, LK_EXCLUSIVE,
+ ap->a_vpp);
if (error) {
printf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
brelse(bp);
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
index f14d741..de239f0 100644
--- a/sys/fs/ntfs/ntfs_subr.c
+++ b/sys/fs/ntfs/ntfs_subr.c
@@ -1946,7 +1946,7 @@ ntfs_toupper_use(mp, ntmp)
MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar),
M_NTFSRDATA, M_WAITOK);
- if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp)))
+ if ((error = VFS_VGET(mp, NTFS_UPCASEINO, LK_EXCLUSIVE, &vp)))
goto out;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
index 712d4d3..48bacbe 100644
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ b/sys/fs/ntfs/ntfs_vfsops.c
@@ -68,7 +68,7 @@ static int ntfs_root __P((struct mount *, struct vnode **));
static int ntfs_statfs __P((struct mount *, struct statfs *,
struct thread *));
static int ntfs_unmount __P((struct mount *, int, struct thread *));
-static int ntfs_vget __P((struct mount *mp, ino_t ino,
+static int ntfs_vget __P((struct mount *mp, ino_t ino, int lkflags,
struct vnode **vpp));
static int ntfs_mountfs __P((register struct vnode *, struct mount *,
struct ntfs_args *, struct thread *));
@@ -367,7 +367,8 @@ ntfs_mountfs(devvp, mp, argsp, td)
{
int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
for (i=0; i<3; i++) {
- error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
+ error = VFS_VGET(mp, pi[i], LK_EXCLUSIVE,
+ &(ntmp->ntm_sysvn[pi[i]]));
if(error)
goto out1;
ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
@@ -397,7 +398,7 @@ ntfs_mountfs(devvp, mp, argsp, td)
struct attrdef ad;
/* Open $AttrDef */
- error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp );
+ error = VFS_VGET(mp, NTFS_ATTRDEFINO, LK_EXCLUSIVE, &vp );
if(error)
goto out1;
@@ -537,7 +538,7 @@ ntfs_root(
dprintf(("ntfs_root(): sysvn: %p\n",
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
- error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
+ error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, LK_EXCLUSIVE, &nvp);
if(error) {
printf("ntfs_root: VFS_VGET failed: %d\n",error);
return (error);
@@ -625,7 +626,7 @@ ntfs_fhtovp(
ddprintf(("ntfs_fhtovp(): %d\n", ntfhp->ntfid_ino));
- if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
@@ -768,10 +769,11 @@ static int
ntfs_vget(
struct mount *mp,
ino_t ino,
+ int lkflags,
struct vnode **vpp)
{
- return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
- LK_EXCLUSIVE | LK_RETRY, 0, curthread, vpp);
+ return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, lkflags, 0,
+ curthread, vpp);
}
static struct vfsops ntfs_vfsops = {
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
index e07914b..31b910b 100644
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ b/sys/fs/ntfs/ntfs_vnops.c
@@ -629,8 +629,8 @@ ntfs_lookup(ap)
dprintf(("ntfs_lookup: parentdir: %d\n",
vap->va_a_name->n_pnumber));
- error = VFS_VGET(ntmp->ntm_mountp,
- vap->va_a_name->n_pnumber,ap->a_vpp);
+ error = VFS_VGET(ntmp->ntm_mountp, vap->va_a_name->n_pnumber,
+ LK_EXCLUSIVE, ap->a_vpp);
ntfs_ntvattrrele(vap);
if (error) {
if (vn_lock(dvp,LK_EXCLUSIVE|LK_RETRY,cnp->cn_thread)==0)
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index 1ab0aaa..d0a1ed1 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -73,7 +73,8 @@ static int nullfs_statfs(struct mount *mp, struct statfs *sbp,
static int nullfs_sync(struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td);
static int nullfs_unmount(struct mount *mp, int mntflags, struct thread *td);
-static int nullfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
+static int nullfs_vget(struct mount *mp, ino_t ino, int flags,
+ struct vnode **vpp);
static int nullfs_vptofh(struct vnode *vp, struct fid *fhp);
static int nullfs_extattrctl(struct mount *mp, int cmd,
struct vnode *filename_vp,
@@ -344,13 +345,14 @@ nullfs_sync(mp, waitfor, cred, td)
}
static int
-nullfs_vget(mp, ino, vpp)
+nullfs_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
int error;
- error = VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, vpp);
+ error = VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, flags, vpp);
if (error)
return (error);
diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c
index b3b5cd3..575585c 100644
--- a/sys/fs/smbfs/smbfs_vfsops.c
+++ b/sys/fs/smbfs/smbfs_vfsops.c
@@ -90,7 +90,8 @@ static int smbfs_init(struct vfsconf *vfsp);
static int smbfs_uninit(struct vfsconf *vfsp);
#if __FreeBSD_version < 400009
-static int smbfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
+static int smbfs_vget(struct mount *mp, ino_t ino, int flags,
+ struct vnode **vpp);
static int smbfs_fhtovp(struct mount *, struct fid *,
struct sockaddr *, struct vnode **, int *,
struct ucred **);
@@ -467,9 +468,10 @@ loop:
* smbfs flat namespace lookup. Unsupported.
*/
/* ARGSUSED */
-static int smbfs_vget(mp, ino, vpp)
+static int smbfs_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
return (EOPNOTSUPP);
diff --git a/sys/fs/umapfs/umap_vfsops.c b/sys/fs/umapfs/umap_vfsops.c
index a22b8df..17bfdc1 100644
--- a/sys/fs/umapfs/umap_vfsops.c
+++ b/sys/fs/umapfs/umap_vfsops.c
@@ -73,7 +73,7 @@ static int umapfs_sync __P((struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td));
static int umapfs_unmount __P((struct mount *mp, int mntflags,
struct thread *td));
-static int umapfs_vget __P((struct mount *mp, ino_t ino,
+static int umapfs_vget __P((struct mount *mp, ino_t ino, int flags,
struct vnode **vpp));
static int umapfs_vptofh __P((struct vnode *vp, struct fid *fhp));
static int umapfs_extattrctl __P((struct mount *mp, int cmd,
@@ -387,13 +387,14 @@ umapfs_sync(mp, waitfor, cred, td)
}
static int
-umapfs_vget(mp, ino, vpp)
+umapfs_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
- return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp));
+ return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, flags, vpp));
}
static int
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);
diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c
index 706a7ae..da927e1 100644
--- a/sys/isofs/cd9660/cd9660_lookup.c
+++ b/sys/isofs/cd9660/cd9660_lookup.c
@@ -352,7 +352,8 @@ found:
*/
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
- error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error) {
@@ -373,7 +374,8 @@ found:
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
+ LK_EXCLUSIVE, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error)
diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c
index 53ffeca..0060364 100644
--- a/sys/isofs/cd9660/cd9660_node.c
+++ b/sys/isofs/cd9660/cd9660_node.c
@@ -92,15 +92,19 @@ cd9660_uninit(vfsp)
* 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 *
-cd9660_ihashget(dev, inum)
+int
+cd9660_ihashget(dev, inum, flags, vpp)
dev_t dev;
ino_t inum;
+ int flags;
+ struct vnode **vpp;
{
struct thread *td = curthread; /* XXX */
struct iso_node *ip;
struct vnode *vp;
+ int error;
+ *vpp = NULL;
loop:
mtx_lock(&cd9660_ihash_mtx);
for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
@@ -108,13 +112,17 @@ loop:
vp = ITOV(ip);
mtx_lock(&vp->v_interlock);
mtx_unlock(&cd9660_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(&cd9660_ihash_mtx);
- return (NULL);
+ return (0);
}
/*
diff --git a/sys/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h
index 100c08e..2a0d7ef 100644
--- a/sys/isofs/cd9660/cd9660_node.h
+++ b/sys/isofs/cd9660/cd9660_node.h
@@ -117,7 +117,7 @@ void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
-struct vnode *cd9660_ihashget __P((dev_t, ino_t));
+int cd9660_ihashget __P((dev_t, ino_t, int, struct vnode **));
void cd9660_ihashins __P((struct iso_node *));
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c
index 1e3719d..60a7b38 100644
--- a/sys/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/isofs/cd9660/cd9660_vfsops.c
@@ -69,7 +69,7 @@ static int cd9660_mount __P((struct mount *,
static int cd9660_unmount __P((struct mount *, int, struct thread *));
static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct thread *));
-static int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
+static int cd9660_vget __P((struct mount *, ino_t, int, struct vnode **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_vptofh __P((struct vnode *, struct fid *));
@@ -578,7 +578,7 @@ cd9660_root(mp, vpp)
* With RRIP we must use the `.' entry of the root directory.
* Simply tell vget, that it's a relocated directory.
*/
- return (cd9660_vget_internal(mp, ino, vpp,
+ return (cd9660_vget_internal(mp, ino, LK_EXCLUSIVE, vpp,
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
}
@@ -644,7 +644,7 @@ cd9660_fhtovp(mp, fhp, vpp)
ifhp->ifid_ino, ifhp->ifid_start);
#endif
- if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, ifhp->ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
@@ -659,9 +659,10 @@ cd9660_fhtovp(mp, fhp, vpp)
}
int
-cd9660_vget(mp, ino, vpp)
+cd9660_vget(mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
@@ -671,7 +672,7 @@ cd9660_vget(mp, ino, vpp)
* and force the extra read, but I don't want to think about fixing
* that right now.
*/
- return (cd9660_vget_internal(mp, ino, vpp,
+ return (cd9660_vget_internal(mp, ino, flags, vpp,
#if 0
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
#else
@@ -681,9 +682,10 @@ cd9660_vget(mp, ino, vpp)
}
int
-cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
+cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
int relocated;
struct iso_directory_record *isodir;
@@ -697,7 +699,9 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
imp = VFSTOISOFS(mp);
dev = imp->im_dev;
- if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
+ if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0)
+ return (error);
+ if (*vpp != NULL)
return (0);
/* Allocate a new vnode/iso_node. */
@@ -718,6 +722,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
ip->i_number = ino;
/*
+ * Check to be sure that it did not show up. We have to put it
+ * on the hash chain as the cleanup from vput expects to find
+ * it there.
+ */
+ if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0 ||
+ *vpp != NULL) {
+ cd9660_ihashins(ip);
+ vput(vp);
+ return (error);
+ }
+
+ /*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
diff --git a/sys/isofs/cd9660/iso.h b/sys/isofs/cd9660/iso.h
index b62c723..453423a 100644
--- a/sys/isofs/cd9660/iso.h
+++ b/sys/isofs/cd9660/iso.h
@@ -254,7 +254,7 @@ struct iso_mnt {
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
-int cd9660_vget_internal __P((struct mount *, ino_t, struct vnode **, int,
+int cd9660_vget_internal __P((struct mount *, ino_t, int, struct vnode **, int,
struct iso_directory_record *));
int cd9660_init __P((struct vfsconf *));
int cd9660_uninit __P((struct vfsconf *));
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index dab13c2..9a3a3c1 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -802,9 +802,10 @@ vfs_stdsync (mp, waitfor, cred, td)
}
int
-vfs_stdvget (mp, ino, vpp)
+vfs_stdvget (mp, ino, flags, vpp)
struct mount *mp;
ino_t ino;
+ int flags;
struct vnode **vpp;
{
return (EOPNOTSUPP);
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 17aea87..2d79643 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -3428,7 +3428,8 @@ again:
* Probe one of the directory entries to see if the filesystem
* supports VGET.
*/
- if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp) == EOPNOTSUPP) {
+ if (VFS_VGET(vp->v_mount, dp->d_fileno, LK_EXCLUSIVE, &nvp) ==
+ EOPNOTSUPP) {
error = NFSERR_NOTSUPP;
vrele(vp);
vp = NULL;
@@ -3462,7 +3463,8 @@ again:
* For readdir_and_lookup get the vnode using
* the file number.
*/
- if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp))
+ if (VFS_VGET(vp->v_mount, dp->d_fileno, LK_EXCLUSIVE,
+ &nvp))
goto invalid;
bzero((caddr_t)nfhp, NFSX_V3FH);
nfhp->fh_fsid =
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 5cd748d..505e034 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -358,7 +358,7 @@ struct vfsops {
struct thread *td));
int (*vfs_sync) __P((struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td));
- int (*vfs_vget) __P((struct mount *mp, ino_t ino,
+ int (*vfs_vget) __P((struct mount *mp, ino_t ino, int flags,
struct vnode **vpp));
int (*vfs_fhtovp) __P((struct mount *mp, struct fid *fhp,
struct vnode **vpp));
@@ -381,7 +381,8 @@ struct vfsops {
#define VFS_QUOTACTL(MP,C,U,A,P) (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A, P)
#define VFS_STATFS(MP, SBP, P) (*(MP)->mnt_op->vfs_statfs)(MP, SBP, P)
#define VFS_SYNC(MP, WAIT, C, P) (*(MP)->mnt_op->vfs_sync)(MP, WAIT, C, P)
-#define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
+#define VFS_VGET(MP, INO, FLAGS, VPP) \
+ (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP)
#define VFS_FHTOVP(MP, FIDP, VPP) \
(*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP)
#define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP)
@@ -456,7 +457,7 @@ int vfs_stdquotactl __P((struct mount *mp, int cmds, uid_t uid,
int vfs_stdstatfs __P((struct mount *mp, struct statfs *sbp, struct thread *td));
int vfs_stdsync __P((struct mount *mp, int waitfor, struct ucred *cred,
struct thread *td));
-int vfs_stdvget __P((struct mount *mp, ino_t ino, struct vnode **vpp));
+int vfs_stdvget __P((struct mount *mp, ino_t ino, int, struct vnode **vpp));
int vfs_stdfhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
int vfs_stdcheckexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
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