1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-28 08:02:54 +00:00

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.
This commit is contained in:
Kirk McKusick 2002-03-17 01:25:47 +00:00
parent ac59490b5e
commit a0595d0249
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=92462
48 changed files with 308 additions and 191 deletions

View File

@ -1854,7 +1854,7 @@ coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp)
} }
/* XXX - ensure that nonzero-return means failure */ /* XXX - ensure that nonzero-return means failure */
error = VFS_VGET(mp,ino,vpp); error = VFS_VGET(mp,ino,LK_EXCLUSIVE,vpp);
if (error) { if (error) {
myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n", myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n",
(u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error)); (u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error));

View File

@ -352,7 +352,8 @@ cd9660_lookup(ap)
*/ */
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */ 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); dp->i_ino != ino, ep);
brelse(bp); brelse(bp);
if (error) { if (error) {
@ -373,7 +374,8 @@ cd9660_lookup(ap)
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } 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); dp->i_ino != ino, ep);
brelse(bp); brelse(bp);
if (error) if (error)

View File

@ -92,15 +92,19 @@ cd9660_uninit(vfsp)
* Use the device/inum pair to find the incore inode, and return a pointer * 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. * to it. If it is in core, but locked, wait for it.
*/ */
struct vnode * int
cd9660_ihashget(dev, inum) cd9660_ihashget(dev, inum, flags, vpp)
dev_t dev; dev_t dev;
ino_t inum; ino_t inum;
int flags;
struct vnode **vpp;
{ {
struct thread *td = curthread; /* XXX */ struct thread *td = curthread; /* XXX */
struct iso_node *ip; struct iso_node *ip;
struct vnode *vp; struct vnode *vp;
int error;
*vpp = NULL;
loop: loop:
mtx_lock(&cd9660_ihash_mtx); mtx_lock(&cd9660_ihash_mtx);
for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) { for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
@ -108,13 +112,17 @@ cd9660_ihashget(dev, inum)
vp = ITOV(ip); vp = ITOV(ip);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
mtx_unlock(&cd9660_ihash_mtx); 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; goto loop;
return (vp); if (error)
return (error);
*vpp = vp;
return (0);
} }
} }
mtx_unlock(&cd9660_ihash_mtx); mtx_unlock(&cd9660_ihash_mtx);
return (NULL); return (0);
} }
/* /*

View File

@ -117,7 +117,7 @@ void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE)); struct iso_node *, struct buf *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *, void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE)); 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 *)); void cd9660_ihashins __P((struct iso_node *));
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE)); int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *)); int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));

View File

@ -69,7 +69,7 @@ static int cd9660_mount __P((struct mount *,
static int cd9660_unmount __P((struct mount *, int, struct thread *)); static int cd9660_unmount __P((struct mount *, int, struct thread *));
static int cd9660_root __P((struct mount *, struct vnode **)); static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct thread *)); 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_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_vptofh __P((struct vnode *, struct fid *)); 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. * With RRIP we must use the `.' entry of the root directory.
* Simply tell vget, that it's a relocated 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)); imp->iso_ftype == ISO_FTYPE_RRIP, dp));
} }
@ -644,7 +644,7 @@ cd9660_fhtovp(mp, fhp, vpp)
ifhp->ifid_ino, ifhp->ifid_start); ifhp->ifid_ino, ifhp->ifid_start);
#endif #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; *vpp = NULLVP;
return (error); return (error);
} }
@ -659,9 +659,10 @@ cd9660_fhtovp(mp, fhp, vpp)
} }
int int
cd9660_vget(mp, ino, vpp) cd9660_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; 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 * and force the extra read, but I don't want to think about fixing
* that right now. * that right now.
*/ */
return (cd9660_vget_internal(mp, ino, vpp, return (cd9660_vget_internal(mp, ino, flags, vpp,
#if 0 #if 0
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP, VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
#else #else
@ -681,9 +682,10 @@ cd9660_vget(mp, ino, vpp)
} }
int int
cd9660_vget_internal(mp, ino, vpp, relocated, isodir) cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
int relocated; int relocated;
struct iso_directory_record *isodir; struct iso_directory_record *isodir;
@ -697,7 +699,9 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
imp = VFSTOISOFS(mp); imp = VFSTOISOFS(mp);
dev = imp->im_dev; 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); return (0);
/* Allocate a new vnode/iso_node. */ /* Allocate a new vnode/iso_node. */
@ -717,6 +721,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
ip->i_dev = dev; ip->i_dev = dev;
ip->i_number = ino; 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 * 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 * this inode will block if they arrive while we are sleeping waiting

View File

@ -254,7 +254,7 @@ struct iso_mnt {
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift) #define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define blksize(imp, ip, lbn) ((imp)->logical_block_size) #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 *)); struct iso_directory_record *));
int cd9660_init __P((struct vfsconf *)); int cd9660_init __P((struct vfsconf *));
int cd9660_uninit __P((struct vfsconf *)); int cd9660_uninit __P((struct vfsconf *));

View File

@ -1854,7 +1854,7 @@ coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp)
} }
/* XXX - ensure that nonzero-return means failure */ /* XXX - ensure that nonzero-return means failure */
error = VFS_VGET(mp,ino,vpp); error = VFS_VGET(mp,ino,LK_EXCLUSIVE,vpp);
if (error) { if (error) {
myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n", myprintf(("coda_grab_vnode: iget/vget(%lx, %lu) returns %p, err %d\n",
(u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error)); (u_long)dev2udev(dev), (u_long)ino, (void *)*vpp, error));

View File

@ -393,7 +393,7 @@ void hpfs_hphashinit __P((void));
void hpfs_hphashdestroy __P((void)); void hpfs_hphashdestroy __P((void));
struct hpfsnode *hpfs_hphashlookup __P((dev_t, lsn_t)); struct hpfsnode *hpfs_hphashlookup __P((dev_t, lsn_t));
struct hpfsnode *hpfs_hphashget __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_hphashins __P((register struct hpfsnode *));
void hpfs_hphashrem __P((register struct hpfsnode *)); void hpfs_hphashrem __P((register struct hpfsnode *));
extern struct lock hpfs_hphash_lock; extern struct lock hpfs_hphash_lock;

View File

@ -122,15 +122,19 @@ hpfs_hphashget(dev, ino)
} }
#endif #endif
struct vnode * int
hpfs_hphashvget(dev, ino, td) hpfs_hphashvget(dev, ino, flags, vpp, td)
dev_t dev; dev_t dev;
lsn_t ino; lsn_t ino;
int flags;
struct vnode **vpp;
struct thread *td; struct thread *td;
{ {
struct hpfsnode *hp; struct hpfsnode *hp;
struct vnode *vp; struct vnode *vp;
int error;
*vpp = NULLVP;
loop: loop:
mtx_lock(&hpfs_hphash_mtx); mtx_lock(&hpfs_hphash_mtx);
LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) { LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) {
@ -138,13 +142,17 @@ hpfs_hphashvget(dev, ino, td)
vp = HPTOV(hp); vp = HPTOV(hp);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
mtx_unlock(&hpfs_hphash_mtx); 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; goto loop;
return (vp); if (error)
return (error);
*vpp = vp;
return (0);
} }
} }
mtx_unlock(&hpfs_hphash_mtx); mtx_unlock(&hpfs_hphash_mtx);
return (NULLVP); return (0);
} }
/* /*

View File

@ -536,7 +536,8 @@ hpfs_validateparent (
if (hp->h_no == hp->h_fn.fn_parent) { if (hp->h_no == hp->h_fn.fn_parent) {
dhp = hp; dhp = hp;
} else { } 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) if (error)
return (error); return (error);
dhp = VTOHP(dvp); dhp = VTOHP(dvp);
@ -689,7 +690,7 @@ hpfs_updateparent (
dhp = hp; dhp = hp;
} else { } else {
error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent, error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
&dvp); LK_EXCLUSIVE, &dvp);
if (error) if (error)
return (error); return (error);
dhp = VTOHP(dvp); dhp = VTOHP(dvp);

View File

@ -59,7 +59,7 @@ static int hpfs_root __P((struct mount *, struct vnode **));
static int hpfs_statfs __P((struct mount *, struct statfs *, static int hpfs_statfs __P((struct mount *, struct statfs *,
struct thread *)); struct thread *));
static int hpfs_unmount __P((struct mount *, int, 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)); struct vnode **vpp));
static int hpfs_mountfs __P((register struct vnode *, struct mount *, static int hpfs_mountfs __P((register struct vnode *, struct mount *,
struct hpfs_args *, struct thread *)); struct hpfs_args *, struct thread *));
@ -380,7 +380,7 @@ hpfs_root(
struct hpfsmount *hpmp = VFSTOHPFS(mp); struct hpfsmount *hpmp = VFSTOHPFS(mp);
dprintf(("hpfs_root():\n")); 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) { if(error) {
printf("hpfs_root: VFS_VGET failed: %d\n",error); printf("hpfs_root: VFS_VGET failed: %d\n",error);
return (error); return (error);
@ -429,7 +429,7 @@ hpfs_fhtovp(
struct hpfid *hpfhp = (struct hpfid *)fhp; struct hpfid *hpfhp = (struct hpfid *)fhp;
int error; 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; *vpp = NULLVP;
return (error); return (error);
} }
@ -460,6 +460,7 @@ static int
hpfs_vget( hpfs_vget(
struct mount *mp, struct mount *mp,
ino_t ino, ino_t ino,
int flags,
struct vnode **vpp) struct vnode **vpp)
{ {
struct hpfsmount *hpmp = VFSTOHPFS(mp); struct hpfsmount *hpmp = VFSTOHPFS(mp);
@ -475,7 +476,9 @@ hpfs_vget(
hp = NULL; hp = NULL;
vp = 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")); dprintf(("hashed\n"));
return (0); return (0);
} }
@ -531,7 +534,12 @@ hpfs_vget(
} }
do { 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")); dprintf(("hashed2\n"));
vput(vp); vput(vp);
return (0); return (0);

View File

@ -1096,21 +1096,18 @@ hpfs_lookup(ap)
dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n", dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n",
dhp->h_no, dhp->h_fn.fn_parent)); dhp->h_no, dhp->h_fn.fn_parent));
VOP_UNLOCK(dvp,0,cnp->cn_thread); if (VFS_VGET(hpmp->hpm_mp, dhp->h_fn.fn_parent,
LK_NOWAIT | LK_EXCLUSIVE, ap->a_vpp)) {
error = VFS_VGET(hpmp->hpm_mp, VOP_UNLOCK(dvp,0,cnp->cn_thread);
dhp->h_fn.fn_parent, ap->a_vpp); error = VFS_VGET(hpmp->hpm_mp,
if(error) { dhp->h_fn.fn_parent, LK_EXCLUSIVE, ap->a_vpp);
VOP_LOCK(dvp, 0, cnp->cn_thread); VOP_LOCK(dvp, 0, cnp->cn_thread);
return(error); if(error)
return(error);
} }
if (!lockparent || !(flags & ISLASTCN))
if( lockparent && (flags & ISLASTCN) && VOP_UNLOCK(dvp,0,cnp->cn_thread);
(error = VOP_LOCK(dvp, 0, cnp->cn_thread)) ) { return (0);
vput( *(ap->a_vpp) );
return (error);
}
return (error);
} else { } else {
struct buf *bp; struct buf *bp;
struct hpfsdirent *dep; struct hpfsdirent *dep;
@ -1148,7 +1145,8 @@ hpfs_lookup(ap)
return (0); 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) { if (error) {
printf("hpfs_lookup: VFS_VGET FAILED %d\n", error); printf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
brelse(bp); brelse(bp);

View File

@ -1946,7 +1946,7 @@ ntfs_toupper_use(mp, ntmp)
MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar), MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar),
M_NTFSRDATA, M_WAITOK); M_NTFSRDATA, M_WAITOK);
if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp))) if ((error = VFS_VGET(mp, NTFS_UPCASEINO, LK_EXCLUSIVE, &vp)))
goto out; goto out;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL); 0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);

View File

@ -68,7 +68,7 @@ static int ntfs_root __P((struct mount *, struct vnode **));
static int ntfs_statfs __P((struct mount *, struct statfs *, static int ntfs_statfs __P((struct mount *, struct statfs *,
struct thread *)); struct thread *));
static int ntfs_unmount __P((struct mount *, int, 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)); struct vnode **vpp));
static int ntfs_mountfs __P((register struct vnode *, struct mount *, static int ntfs_mountfs __P((register struct vnode *, struct mount *,
struct ntfs_args *, struct thread *)); struct ntfs_args *, struct thread *));
@ -367,7 +367,8 @@ ntfs_mountfs(devvp, mp, argsp, td)
{ {
int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO }; int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
for (i=0; i<3; i++) { 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) if(error)
goto out1; goto out1;
ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM; ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
@ -397,7 +398,7 @@ ntfs_mountfs(devvp, mp, argsp, td)
struct attrdef ad; struct attrdef ad;
/* Open $AttrDef */ /* Open $AttrDef */
error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp ); error = VFS_VGET(mp, NTFS_ATTRDEFINO, LK_EXCLUSIVE, &vp );
if(error) if(error)
goto out1; goto out1;
@ -537,7 +538,7 @@ ntfs_root(
dprintf(("ntfs_root(): sysvn: %p\n", dprintf(("ntfs_root(): sysvn: %p\n",
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO])); 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) { if(error) {
printf("ntfs_root: VFS_VGET failed: %d\n",error); printf("ntfs_root: VFS_VGET failed: %d\n",error);
return (error); return (error);
@ -625,7 +626,7 @@ ntfs_fhtovp(
ddprintf(("ntfs_fhtovp(): %d\n", ntfhp->ntfid_ino)); 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; *vpp = NULLVP;
return (error); return (error);
} }
@ -768,10 +769,11 @@ static int
ntfs_vget( ntfs_vget(
struct mount *mp, struct mount *mp,
ino_t ino, ino_t ino,
int lkflags,
struct vnode **vpp) struct vnode **vpp)
{ {
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, lkflags, 0,
LK_EXCLUSIVE | LK_RETRY, 0, curthread, vpp); curthread, vpp);
} }
static struct vfsops ntfs_vfsops = { static struct vfsops ntfs_vfsops = {

View File

@ -629,8 +629,8 @@ ntfs_lookup(ap)
dprintf(("ntfs_lookup: parentdir: %d\n", dprintf(("ntfs_lookup: parentdir: %d\n",
vap->va_a_name->n_pnumber)); vap->va_a_name->n_pnumber));
error = VFS_VGET(ntmp->ntm_mountp, error = VFS_VGET(ntmp->ntm_mountp, vap->va_a_name->n_pnumber,
vap->va_a_name->n_pnumber,ap->a_vpp); LK_EXCLUSIVE, ap->a_vpp);
ntfs_ntvattrrele(vap); ntfs_ntvattrrele(vap);
if (error) { if (error) {
if (vn_lock(dvp,LK_EXCLUSIVE|LK_RETRY,cnp->cn_thread)==0) if (vn_lock(dvp,LK_EXCLUSIVE|LK_RETRY,cnp->cn_thread)==0)

View File

@ -73,7 +73,8 @@ static int nullfs_statfs(struct mount *mp, struct statfs *sbp,
static int nullfs_sync(struct mount *mp, int waitfor, static int nullfs_sync(struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td); struct ucred *cred, struct thread *td);
static int nullfs_unmount(struct mount *mp, int mntflags, 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_vptofh(struct vnode *vp, struct fid *fhp);
static int nullfs_extattrctl(struct mount *mp, int cmd, static int nullfs_extattrctl(struct mount *mp, int cmd,
struct vnode *filename_vp, struct vnode *filename_vp,
@ -344,13 +345,14 @@ nullfs_sync(mp, waitfor, cred, td)
} }
static int static int
nullfs_vget(mp, ino, vpp) nullfs_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
int error; int error;
error = VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, vpp); error = VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, flags, vpp);
if (error) if (error)
return (error); return (error);

View File

@ -90,7 +90,8 @@ static int smbfs_init(struct vfsconf *vfsp);
static int smbfs_uninit(struct vfsconf *vfsp); static int smbfs_uninit(struct vfsconf *vfsp);
#if __FreeBSD_version < 400009 #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 *, static int smbfs_fhtovp(struct mount *, struct fid *,
struct sockaddr *, struct vnode **, int *, struct sockaddr *, struct vnode **, int *,
struct ucred **); struct ucred **);
@ -467,9 +468,10 @@ smbfs_sync(mp, waitfor, cred, td)
* smbfs flat namespace lookup. Unsupported. * smbfs flat namespace lookup. Unsupported.
*/ */
/* ARGSUSED */ /* ARGSUSED */
static int smbfs_vget(mp, ino, vpp) static int smbfs_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
return (EOPNOTSUPP); return (EOPNOTSUPP);

View File

@ -73,7 +73,7 @@ static int umapfs_sync __P((struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td)); struct ucred *cred, struct thread *td));
static int umapfs_unmount __P((struct mount *mp, int mntflags, static int umapfs_unmount __P((struct mount *mp, int mntflags,
struct thread *td)); 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)); struct vnode **vpp));
static int umapfs_vptofh __P((struct vnode *vp, struct fid *fhp)); static int umapfs_vptofh __P((struct vnode *vp, struct fid *fhp));
static int umapfs_extattrctl __P((struct mount *mp, int cmd, static int umapfs_extattrctl __P((struct mount *mp, int cmd,
@ -387,13 +387,14 @@ umapfs_sync(mp, waitfor, cred, td)
} }
static int static int
umapfs_vget(mp, ino, vpp) umapfs_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp)); return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, flags, vpp));
} }
static int static int

View File

@ -399,7 +399,7 @@ ext2_valloc(pvp, mode, cred, vpp)
if (ino == 0) if (ino == 0)
goto noinodes; goto noinodes;
error = VFS_VGET(pvp->v_mount, ino, vpp); error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) { if (error) {
UFS_VFREE(pvp, ino, mode); UFS_VFREE(pvp, ino, mode);
return (error); return (error);

View File

@ -93,15 +93,19 @@ ufs_ihashlookup(dev, inum)
* Use the device/inum pair to find the incore inode, and return a pointer * 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. * to it. If it is in core, but locked, wait for it.
*/ */
struct vnode * int
ufs_ihashget(dev, inum) ufs_ihashget(dev, inum, flags, vpp)
dev_t dev; dev_t dev;
ino_t inum; ino_t inum;
int flags;
struct vnode **vpp;
{ {
struct thread *td = curthread; /* XXX */ struct thread *td = curthread; /* XXX */
struct inode *ip; struct inode *ip;
struct vnode *vp; struct vnode *vp;
int error;
*vpp = NULL;
loop: loop:
mtx_lock(&ufs_ihash_mtx); mtx_lock(&ufs_ihash_mtx);
LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) { LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
@ -109,13 +113,17 @@ ufs_ihashget(dev, inum)
vp = ITOV(ip); vp = ITOV(ip);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
mtx_unlock(&ufs_ihash_mtx); 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; goto loop;
return (vp); if (error)
return (error);
*vpp = vp;
return (0);
} }
} }
mtx_unlock(&ufs_ihash_mtx); mtx_unlock(&ufs_ihash_mtx);
return (NULL); return (0);
} }
/* /*

View File

@ -601,7 +601,8 @@ ext2_lookup(ap)
*vpp = vdp; *vpp = vdp;
return (0); 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); return (error);
/* /*
* If directory is "sticky", then user must own * If directory is "sticky", then user must own
@ -638,7 +639,8 @@ ext2_lookup(ap)
*/ */
if (dp->i_number == dp->i_ino) if (dp->i_number == dp->i_ino)
return (EISDIR); 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); return (error);
*vpp = tdp; *vpp = tdp;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
@ -669,7 +671,8 @@ ext2_lookup(ap)
pdp = vdp; pdp = vdp;
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */ 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); vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
return (error); return (error);
} }
@ -683,7 +686,8 @@ ext2_lookup(ap)
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } 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); return (error);
if (!lockparent || !(flags & ISLASTCN)) if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp, 0, td); VOP_UNLOCK(pdp, 0, td);
@ -1064,7 +1068,8 @@ ext2_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino) if (dirbuf.dotdot_ino == rootino)
break; break;
vput(vp); 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; vp = NULL;
break; break;
} }

View File

@ -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_statfs __P((struct mount *, struct statfs *, struct thread *));
static int ext2_sync __P((struct mount *, int, struct ucred *, 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_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 int ext2_vptofh __P((struct vnode *, struct fid *));
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part"); static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@ -982,9 +982,10 @@ ext2_sync(mp, waitfor, cred, td)
* done by the calling routine. * done by the calling routine.
*/ */
static int static int
ext2_vget(mp, ino, vpp) ext2_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
register struct ext2_sb_info *fs; register struct ext2_sb_info *fs;
@ -999,7 +1000,9 @@ ext2_vget(mp, ino, vpp)
ump = VFSTOUFS(mp); ump = VFSTOUFS(mp);
dev = ump->um_dev; dev = ump->um_dev;
restart: restart:
if ((*vpp = ufs_ihashget(dev, ino)) != NULL) if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
return (error);
if (*vpp != NULL)
return (0); return (0);
/* /*

View File

@ -285,7 +285,7 @@ ext2_mknod(ap)
(*vpp)->v_type = VNON; (*vpp)->v_type = VNON;
ino = ip->i_number; /* Save this before vgone() invalidates ip. */ ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp); 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) { if (error) {
*vpp = NULL; *vpp = NULL;
return (error); return (error);

View File

@ -399,7 +399,7 @@ ext2_valloc(pvp, mode, cred, vpp)
if (ino == 0) if (ino == 0)
goto noinodes; goto noinodes;
error = VFS_VGET(pvp->v_mount, ino, vpp); error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) { if (error) {
UFS_VFREE(pvp, ino, mode); UFS_VFREE(pvp, ino, mode);
return (error); return (error);

View File

@ -601,7 +601,8 @@ ext2_lookup(ap)
*vpp = vdp; *vpp = vdp;
return (0); 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); return (error);
/* /*
* If directory is "sticky", then user must own * If directory is "sticky", then user must own
@ -638,7 +639,8 @@ ext2_lookup(ap)
*/ */
if (dp->i_number == dp->i_ino) if (dp->i_number == dp->i_ino)
return (EISDIR); 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); return (error);
*vpp = tdp; *vpp = tdp;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
@ -669,7 +671,8 @@ ext2_lookup(ap)
pdp = vdp; pdp = vdp;
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */ 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); vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
return (error); return (error);
} }
@ -683,7 +686,8 @@ ext2_lookup(ap)
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } 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); return (error);
if (!lockparent || !(flags & ISLASTCN)) if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp, 0, td); VOP_UNLOCK(pdp, 0, td);
@ -1064,7 +1068,8 @@ ext2_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino) if (dirbuf.dotdot_ino == rootino)
break; break;
vput(vp); 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; vp = NULL;
break; break;
} }

View File

@ -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_statfs __P((struct mount *, struct statfs *, struct thread *));
static int ext2_sync __P((struct mount *, int, struct ucred *, 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_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 int ext2_vptofh __P((struct vnode *, struct fid *));
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part"); static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@ -982,9 +982,10 @@ ext2_sync(mp, waitfor, cred, td)
* done by the calling routine. * done by the calling routine.
*/ */
static int static int
ext2_vget(mp, ino, vpp) ext2_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
register struct ext2_sb_info *fs; register struct ext2_sb_info *fs;
@ -999,7 +1000,9 @@ ext2_vget(mp, ino, vpp)
ump = VFSTOUFS(mp); ump = VFSTOUFS(mp);
dev = ump->um_dev; dev = ump->um_dev;
restart: restart:
if ((*vpp = ufs_ihashget(dev, ino)) != NULL) if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
return (error);
if (*vpp != NULL)
return (0); return (0);
/* /*

View File

@ -285,7 +285,7 @@ ext2_mknod(ap)
(*vpp)->v_type = VNON; (*vpp)->v_type = VNON;
ino = ip->i_number; /* Save this before vgone() invalidates ip. */ ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp); 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) { if (error) {
*vpp = NULL; *vpp = NULL;
return (error); return (error);

View File

@ -352,7 +352,8 @@ cd9660_lookup(ap)
*/ */
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */ 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); dp->i_ino != ino, ep);
brelse(bp); brelse(bp);
if (error) { if (error) {
@ -373,7 +374,8 @@ cd9660_lookup(ap)
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } 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); dp->i_ino != ino, ep);
brelse(bp); brelse(bp);
if (error) if (error)

View File

@ -92,15 +92,19 @@ cd9660_uninit(vfsp)
* Use the device/inum pair to find the incore inode, and return a pointer * 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. * to it. If it is in core, but locked, wait for it.
*/ */
struct vnode * int
cd9660_ihashget(dev, inum) cd9660_ihashget(dev, inum, flags, vpp)
dev_t dev; dev_t dev;
ino_t inum; ino_t inum;
int flags;
struct vnode **vpp;
{ {
struct thread *td = curthread; /* XXX */ struct thread *td = curthread; /* XXX */
struct iso_node *ip; struct iso_node *ip;
struct vnode *vp; struct vnode *vp;
int error;
*vpp = NULL;
loop: loop:
mtx_lock(&cd9660_ihash_mtx); mtx_lock(&cd9660_ihash_mtx);
for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) { for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
@ -108,13 +112,17 @@ cd9660_ihashget(dev, inum)
vp = ITOV(ip); vp = ITOV(ip);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
mtx_unlock(&cd9660_ihash_mtx); 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; goto loop;
return (vp); if (error)
return (error);
*vpp = vp;
return (0);
} }
} }
mtx_unlock(&cd9660_ihash_mtx); mtx_unlock(&cd9660_ihash_mtx);
return (NULL); return (0);
} }
/* /*

View File

@ -117,7 +117,7 @@ void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE)); struct iso_node *, struct buf *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *, void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE)); 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 *)); void cd9660_ihashins __P((struct iso_node *));
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE)); int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *)); int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));

View File

@ -69,7 +69,7 @@ static int cd9660_mount __P((struct mount *,
static int cd9660_unmount __P((struct mount *, int, struct thread *)); static int cd9660_unmount __P((struct mount *, int, struct thread *));
static int cd9660_root __P((struct mount *, struct vnode **)); static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct thread *)); 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_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_vptofh __P((struct vnode *, struct fid *)); 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. * With RRIP we must use the `.' entry of the root directory.
* Simply tell vget, that it's a relocated 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)); imp->iso_ftype == ISO_FTYPE_RRIP, dp));
} }
@ -644,7 +644,7 @@ cd9660_fhtovp(mp, fhp, vpp)
ifhp->ifid_ino, ifhp->ifid_start); ifhp->ifid_ino, ifhp->ifid_start);
#endif #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; *vpp = NULLVP;
return (error); return (error);
} }
@ -659,9 +659,10 @@ cd9660_fhtovp(mp, fhp, vpp)
} }
int int
cd9660_vget(mp, ino, vpp) cd9660_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; 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 * and force the extra read, but I don't want to think about fixing
* that right now. * that right now.
*/ */
return (cd9660_vget_internal(mp, ino, vpp, return (cd9660_vget_internal(mp, ino, flags, vpp,
#if 0 #if 0
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP, VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
#else #else
@ -681,9 +682,10 @@ cd9660_vget(mp, ino, vpp)
} }
int int
cd9660_vget_internal(mp, ino, vpp, relocated, isodir) cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
int relocated; int relocated;
struct iso_directory_record *isodir; struct iso_directory_record *isodir;
@ -697,7 +699,9 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
imp = VFSTOISOFS(mp); imp = VFSTOISOFS(mp);
dev = imp->im_dev; 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); return (0);
/* Allocate a new vnode/iso_node. */ /* Allocate a new vnode/iso_node. */
@ -717,6 +721,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
ip->i_dev = dev; ip->i_dev = dev;
ip->i_number = ino; 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 * 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 * this inode will block if they arrive while we are sleeping waiting

View File

@ -254,7 +254,7 @@ struct iso_mnt {
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift) #define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define blksize(imp, ip, lbn) ((imp)->logical_block_size) #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 *)); struct iso_directory_record *));
int cd9660_init __P((struct vfsconf *)); int cd9660_init __P((struct vfsconf *));
int cd9660_uninit __P((struct vfsconf *)); int cd9660_uninit __P((struct vfsconf *));

View File

@ -802,9 +802,10 @@ vfs_stdsync (mp, waitfor, cred, td)
} }
int int
vfs_stdvget (mp, ino, vpp) vfs_stdvget (mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
return (EOPNOTSUPP); return (EOPNOTSUPP);

View File

@ -3428,7 +3428,8 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
* Probe one of the directory entries to see if the filesystem * Probe one of the directory entries to see if the filesystem
* supports VGET. * 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; error = NFSERR_NOTSUPP;
vrele(vp); vrele(vp);
vp = NULL; vp = NULL;
@ -3462,7 +3463,8 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
* For readdir_and_lookup get the vnode using * For readdir_and_lookup get the vnode using
* the file number. * 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; goto invalid;
bzero((caddr_t)nfhp, NFSX_V3FH); bzero((caddr_t)nfhp, NFSX_V3FH);
nfhp->fh_fsid = nfhp->fh_fsid =

View File

@ -358,7 +358,7 @@ struct vfsops {
struct thread *td)); struct thread *td));
int (*vfs_sync) __P((struct mount *mp, int waitfor, int (*vfs_sync) __P((struct mount *mp, int waitfor,
struct ucred *cred, struct thread *td)); 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)); struct vnode **vpp));
int (*vfs_fhtovp) __P((struct mount *mp, struct fid *fhp, int (*vfs_fhtovp) __P((struct mount *mp, struct fid *fhp,
struct vnode **vpp)); 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_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_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_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) \ #define VFS_FHTOVP(MP, FIDP, VPP) \
(*(MP)->mnt_op->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) #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_stdstatfs __P((struct mount *mp, struct statfs *sbp, struct thread *td));
int vfs_stdsync __P((struct mount *mp, int waitfor, struct ucred *cred, int vfs_stdsync __P((struct mount *mp, int waitfor, struct ucred *cred,
struct thread *td)); 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_stdfhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
int vfs_stdcheckexp __P((struct mount *mp, struct sockaddr *nam, int vfs_stdcheckexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp)); int *extflagsp, struct ucred **credanonp));

View File

@ -629,7 +629,7 @@ ffs_valloc(pvp, mode, cred, vpp)
(allocfcn_t *)ffs_nodealloccg); (allocfcn_t *)ffs_nodealloccg);
if (ino == 0) if (ino == 0)
goto noinodes; goto noinodes;
error = VFS_VGET(pvp->v_mount, ino, vpp); error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
if (error) { if (error) {
UFS_VFREE(pvp, ino, mode); UFS_VFREE(pvp, ino, mode);
return (error); return (error);
@ -1977,7 +1977,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
cmd.size); cmd.size);
} }
#endif /* DEBUG */ #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; break;
ip = VTOI(vp); ip = VTOI(vp);
ip->i_nlink += cmd.size; ip->i_nlink += cmd.size;
@ -1996,7 +1996,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
cmd.size); cmd.size);
} }
#endif /* DEBUG */ #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; break;
ip = VTOI(vp); ip = VTOI(vp);
ip->i_blocks += cmd.size; ip->i_blocks += cmd.size;

View File

@ -93,7 +93,7 @@ int ffs_update __P((struct vnode *, int));
int ffs_valloc __P((struct vnode *, int, struct ucred *, struct vnode **)); int ffs_valloc __P((struct vnode *, int, struct ucred *, struct vnode **));
int ffs_vfree __P((struct vnode *, ino_t, int)); 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 *)); int ffs_vptofh __P((struct vnode *, struct fid *));
extern vop_t **ffs_vnodeop_p; extern vop_t **ffs_vnodeop_p;

View File

@ -1177,7 +1177,8 @@ ffs_snapshot_mount(mp)
for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) { for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) {
if (fs->fs_snapinum[snaploc] == 0) if (fs->fs_snapinum[snaploc] == 0)
return; 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); printf("ffs_snapshot_mount: vget failed %d\n", error);
continue; continue;
} }

View File

@ -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 handle_written_mkdir __P((struct mkdir *, int));
static void initiate_write_inodeblock __P((struct inodedep *, struct buf *)); static void initiate_write_inodeblock __P((struct inodedep *, struct buf *));
static void handle_workitem_freefile __P((struct freefile *)); 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 *, static struct dirrem *newdirrem __P((struct buf *, struct inode *,
struct inode *, int, struct dirrem **)); struct inode *, int, struct dirrem **));
static void free_diradd __P((struct diradd *)); static void free_diradd __P((struct diradd *));
@ -580,7 +580,7 @@ softdep_process_worklist(matchmnt)
struct mount *matchmnt; struct mount *matchmnt;
{ {
struct thread *td = curthread; struct thread *td = curthread;
int matchcnt, loopcount; int cnt, matchcnt, loopcount;
long starttime; long starttime;
/* /*
@ -618,7 +618,10 @@ softdep_process_worklist(matchmnt)
loopcount = 1; loopcount = 1;
starttime = time_second; starttime = time_second;
while (num_on_worklist > 0) { 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 * If a umount operation wants to run the worklist
@ -675,7 +678,6 @@ process_worklist_item(matchmnt, flags)
int flags; int flags;
{ {
struct worklist *wk; struct worklist *wk;
struct dirrem *dirrem;
struct mount *mp; struct mount *mp;
struct vnode *vp; struct vnode *vp;
int matchcnt = 0; int matchcnt = 0;
@ -687,13 +689,19 @@ process_worklist_item(matchmnt, flags)
* inodes, we have to skip over any dirrem requests whose * inodes, we have to skip over any dirrem requests whose
* vnodes are resident and locked. * vnodes are resident and locked.
*/ */
vp = NULL;
LIST_FOREACH(wk, &softdep_workitem_pending, wk_list) { LIST_FOREACH(wk, &softdep_workitem_pending, wk_list) {
if (wk->wk_state & INPROGRESS)
continue;
if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM) if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
break; break;
dirrem = WK_DIRREM(wk); wk->wk_state |= INPROGRESS;
vp = ufs_ihashlookup(VFSTOUFS(dirrem->dm_mnt)->um_dev, FREE_LOCK(&lk);
dirrem->dm_oldinum); VFS_VGET(WK_DIRREM(wk)->dm_mnt, WK_DIRREM(wk)->dm_oldinum,
if (vp == NULL || !VOP_ISLOCKED(vp, curthread)) LK_NOWAIT | LK_EXCLUSIVE, &vp);
ACQUIRE_LOCK(&lk);
wk->wk_state &= ~INPROGRESS;
if (vp != NULL)
break; break;
} }
if (wk == 0) { if (wk == 0) {
@ -713,7 +721,7 @@ process_worklist_item(matchmnt, flags)
"process_worklist_item"); "process_worklist_item");
if (mp == matchmnt) if (mp == matchmnt)
matchcnt += 1; matchcnt += 1;
handle_workitem_remove(WK_DIRREM(wk)); handle_workitem_remove(WK_DIRREM(wk), vp);
break; break;
case D_FREEBLKS: case D_FREEBLKS:
@ -2280,8 +2288,9 @@ handle_workitem_freeblocks(freeblks, flags)
* to see if the block count needs to be adjusted. * to see if the block count needs to be adjusted.
*/ */
if (freeblks->fb_chkcnt != blocksreleased && if (freeblks->fb_chkcnt != blocksreleased &&
(fs->fs_flags & FS_UNCLEAN) != 0 && (flags & LK_NOWAIT) == 0 && (fs->fs_flags & FS_UNCLEAN) != 0 &&
VFS_VGET(freeblks->fb_mnt, freeblks->fb_previousinum, &vp) == 0) { VFS_VGET(freeblks->fb_mnt, freeblks->fb_previousinum,
(flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp) == 0) {
ip = VTOI(vp); ip = VTOI(vp);
ip->i_blocks += freeblks->fb_chkcnt - blocksreleased; ip->i_blocks += freeblks->fb_chkcnt - blocksreleased;
ip->i_flag |= IN_CHANGE; ip->i_flag |= IN_CHANGE;
@ -2742,7 +2751,7 @@ softdep_setup_remove(bp, dp, ip, isrmdir)
prevdirrem, dm_next); prevdirrem, dm_next);
dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino; dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino;
FREE_LOCK(&lk); 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. * If the link count reaches zero, the file is removed.
*/ */
static void static void
handle_workitem_remove(dirrem) handle_workitem_remove(dirrem, xp)
struct dirrem *dirrem; struct dirrem *dirrem;
struct vnode *xp;
{ {
struct thread *td = curthread; struct thread *td = curthread;
struct inodedep *inodedep; struct inodedep *inodedep;
@ -3043,7 +3053,9 @@ handle_workitem_remove(dirrem)
ino_t oldinum; ino_t oldinum;
int error; 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); softdep_error("handle_workitem_remove: vget", error);
return; return;
} }
@ -3112,7 +3124,7 @@ handle_workitem_remove(dirrem)
check_inode_unwritten(inodedep)) { check_inode_unwritten(inodedep)) {
FREE_LOCK(&lk); FREE_LOCK(&lk);
vput(vp); vput(vp);
handle_workitem_remove(dirrem); handle_workitem_remove(dirrem, NULL);
return; return;
} }
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list); WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
@ -4228,16 +4240,19 @@ softdep_fsync(vp)
/* /*
* We prevent deadlock by always fetching inodes from the * We prevent deadlock by always fetching inodes from the
* root, moving down the directory tree. Thus, when fetching * root, moving down the directory tree. Thus, when fetching
* our parent directory, we must unlock ourselves before * our parent directory, we first try to get the lock. If
* requesting the lock on our parent. See the comment in * that fails, we must unlock ourselves before requesting
* ufs_lookup for details on possible races. * the lock on our parent. See the comment in ufs_lookup
* for details on possible races.
*/ */
FREE_LOCK(&lk); FREE_LOCK(&lk);
VOP_UNLOCK(vp, 0, td); if (VFS_VGET(mnt, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp)) {
error = VFS_VGET(mnt, parentino, &pvp); VOP_UNLOCK(vp, 0, td);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); error = VFS_VGET(mnt, parentino, LK_EXCLUSIVE, &pvp);
if (error != 0) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
return (error); if (error != 0)
return (error);
}
/* /*
* All MKDIR_PARENT dependencies and all the NEWBLOCK pagedeps * All MKDIR_PARENT dependencies and all the NEWBLOCK pagedeps
* that are contained in direct blocks will be resolved by * that are contained in direct blocks will be resolved by
@ -4735,7 +4750,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
inum = dap->da_newinum; inum = dap->da_newinum;
if (dap->da_state & MKDIR_BODY) { if (dap->da_state & MKDIR_BODY) {
FREE_LOCK(&lk); FREE_LOCK(&lk);
if ((error = VFS_VGET(mp, inum, &vp)) != 0) if ((error = VFS_VGET(mp, inum, LK_EXCLUSIVE, &vp)))
break; break;
if ((error=VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td)) || if ((error=VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td)) ||
(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); FREE_LOCK(&lk);
if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
continue; continue;
if ((error = VFS_VGET(mp, ino, &vp)) != 0) { if ((error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &vp))) {
softdep_error("clear_remove: vget", error); softdep_error("clear_remove: vget", error);
vn_finished_write(mp); vn_finished_write(mp);
return; return;
@ -5072,7 +5087,7 @@ clear_inodedeps(td)
FREE_LOCK(&lk); FREE_LOCK(&lk);
if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
continue; 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); softdep_error("clear_inodedeps: vget", error);
vn_finished_write(mp); vn_finished_write(mp);
return; return;

View File

@ -158,7 +158,6 @@ ffs_mount(mp, path, data, ndp, td)
if ((error = ffs_mountfs(rootvp, mp, td, M_FFSNODE)) != 0) if ((error = ffs_mountfs(rootvp, mp, td, M_FFSNODE)) != 0)
return (error); return (error);
(void)VFS_STATFS(mp, &mp->mnt_stat, td); (void)VFS_STATFS(mp, &mp->mnt_stat, td);
return (0); return (0);
} }
@ -1143,9 +1142,10 @@ static int ffs_inode_hash_lock;
static struct mtx ffs_inode_hash_mtx; static struct mtx ffs_inode_hash_mtx;
int int
ffs_vget(mp, ino, vpp) ffs_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
struct fs *fs; struct fs *fs;
@ -1159,9 +1159,10 @@ ffs_vget(mp, ino, vpp)
ump = VFSTOUFS(mp); ump = VFSTOUFS(mp);
dev = ump->um_dev; dev = ump->um_dev;
restart: restart:
if ((*vpp = ufs_ihashget(dev, ino)) != NULL) { if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
return (error);
if (*vpp != NULL)
return (0); return (0);
}
/* /*
* Lock out the creation of new entries in the FFS hash table in * Lock out the creation of new entries in the FFS hash table in

View File

@ -101,6 +101,7 @@
#define IOSTARTED 0x0200 /* inodedep & pagedep only */ #define IOSTARTED 0x0200 /* inodedep & pagedep only */
#define SPACECOUNTED 0x0400 /* inodedep only */ #define SPACECOUNTED 0x0400 /* inodedep only */
#define NEWBLOCK 0x0800 /* pagedep only */ #define NEWBLOCK 0x0800 /* pagedep only */
#define INPROGRESS 0x1000 /* dirrem, freeblks, freefrag, freefile only */
#define ONWORKLIST 0x8000 #define ONWORKLIST 0x8000
#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE) #define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE)

View File

@ -242,7 +242,7 @@ ifs_lookup(ap)
return ENOENT; return ENOENT;
} }
/* Now, we can get the vnode */ /* 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) if (error)
return (error); return (error);
if (!lockparent || !(flags & ISLASTCN)) if (!lockparent || !(flags & ISLASTCN))

View File

@ -71,7 +71,7 @@ static MALLOC_DEFINE(M_IFSNODE, "IFS node", "IFS vnode private part");
static int ifs_init (struct vfsconf *); static int ifs_init (struct vfsconf *);
static int ifs_mount (struct mount *, char *, caddr_t, static int ifs_mount (struct mount *, char *, caddr_t,
struct nameidata *, struct thread *); 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 int
ifs_vget(mp, ino, vpp) ifs_vget(mp, ino, flags, vpp)
struct mount *mp; struct mount *mp;
ino_t ino; ino_t ino;
int flags;
struct vnode **vpp; struct vnode **vpp;
{ {
struct fs *fs; struct fs *fs;
@ -167,9 +168,10 @@ ifs_vget(mp, ino, vpp)
ump = VFSTOUFS(mp); ump = VFSTOUFS(mp);
dev = ump->um_dev; dev = ump->um_dev;
restart: restart:
if ((*vpp = ufs_ihashget(dev, ino)) != NULL) { if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
return (error);
if (*vpp != NULL)
return (0); return (0);
}
/* /*
* Lock out the creation of new entries in the FFS hash table in * Lock out the creation of new entries in the FFS hash table in

View File

@ -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_dirremove __P((struct vnode *, struct inode *, int, int));
int ufs_dirrewrite __P((struct inode *, struct inode *, ino_t, 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 *)); int ufs_getlbns __P((struct vnode *, ufs_daddr_t, struct indir *, int *));
struct vnode * int ufs_ihashget __P((dev_t, ino_t, int, struct vnode **));
ufs_ihashget __P((dev_t, ino_t));
void ufs_ihashinit __P((void)); void ufs_ihashinit __P((void));
void ufs_ihashins __P((struct inode *)); void ufs_ihashins __P((struct inode *));
struct vnode * struct vnode *

View File

@ -93,15 +93,19 @@ ufs_ihashlookup(dev, inum)
* Use the device/inum pair to find the incore inode, and return a pointer * 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. * to it. If it is in core, but locked, wait for it.
*/ */
struct vnode * int
ufs_ihashget(dev, inum) ufs_ihashget(dev, inum, flags, vpp)
dev_t dev; dev_t dev;
ino_t inum; ino_t inum;
int flags;
struct vnode **vpp;
{ {
struct thread *td = curthread; /* XXX */ struct thread *td = curthread; /* XXX */
struct inode *ip; struct inode *ip;
struct vnode *vp; struct vnode *vp;
int error;
*vpp = NULL;
loop: loop:
mtx_lock(&ufs_ihash_mtx); mtx_lock(&ufs_ihash_mtx);
LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) { LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
@ -109,13 +113,17 @@ ufs_ihashget(dev, inum)
vp = ITOV(ip); vp = ITOV(ip);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
mtx_unlock(&ufs_ihash_mtx); 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; goto loop;
return (vp); if (error)
return (error);
*vpp = vp;
return (0);
} }
} }
mtx_unlock(&ufs_ihash_mtx); mtx_unlock(&ufs_ihash_mtx);
return (NULL); return (0);
} }
/* /*

View File

@ -508,14 +508,8 @@ ufs_lookup(ap)
*vpp = vdp; *vpp = vdp;
return (0); return (0);
} }
if (flags & ISDOTDOT) if ((error = VFS_VGET(vdp->v_mount, dp->i_ino,
VOP_UNLOCK(vdp, 0, td); /* race to get the inode */ LK_EXCLUSIVE, &tdp)) != 0)
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)
return (error); return (error);
/* /*
* If directory is "sticky", then user must own * If directory is "sticky", then user must own
@ -544,7 +538,7 @@ ufs_lookup(ap)
* regular file, or empty directory. * regular file, or empty directory.
*/ */
if (nameiop == RENAME && wantparent && (flags & ISLASTCN)) { 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); return (error);
/* /*
* Careful about locking second inode. * Careful about locking second inode.
@ -552,14 +546,8 @@ ufs_lookup(ap)
*/ */
if (dp->i_number == dp->i_ino) if (dp->i_number == dp->i_ino)
return (EISDIR); return (EISDIR);
if (flags & ISDOTDOT) if ((error = VFS_VGET(vdp->v_mount, dp->i_ino,
VOP_UNLOCK(vdp, 0, td); /* race to get the inode */ LK_EXCLUSIVE, &tdp)) != 0)
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)
return (error); return (error);
*vpp = tdp; *vpp = tdp;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
@ -591,26 +579,25 @@ ufs_lookup(ap)
*/ */
pdp = vdp; pdp = vdp;
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */ if ((VFS_VGET(pdp->v_mount, dp->i_ino, LK_NOWAIT | LK_EXCLUSIVE,
cnp->cn_flags |= PDIRUNLOCK; &tdp)) != 0) {
if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) { VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td) == 0) error = VFS_VGET(pdp->v_mount, dp->i_ino,
cnp->cn_flags &= ~PDIRUNLOCK; LK_EXCLUSIVE, &tdp);
return (error); vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
} if (error)
if (lockparent && (flags & ISLASTCN)) {
if ((error = vn_lock(pdp, LK_EXCLUSIVE, td)) != 0) {
vput(tdp);
return (error); return (error);
} }
cnp->cn_flags &= ~PDIRUNLOCK; if (!lockparent || !(flags & ISLASTCN)) {
VOP_UNLOCK(pdp, 0, td);
cnp->cn_flags |= PDIRUNLOCK;
} }
*vpp = tdp; *vpp = tdp;
} else if (dp->i_number == dp->i_ino) { } else if (dp->i_number == dp->i_ino) {
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } 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) if (error)
return (error); return (error);
if (!lockparent || !(flags & ISLASTCN)) { if (!lockparent || !(flags & ISLASTCN)) {
@ -1254,7 +1241,8 @@ ufs_checkpath(source, target, cred)
if (dirbuf.dotdot_ino == rootino) if (dirbuf.dotdot_ino == rootino)
break; break;
vput(vp); 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) { if (error) {
vp = NULL; vp = NULL;
break; break;

View File

@ -84,7 +84,7 @@ ufs_root(mp, vpp)
struct vnode *nvp; struct vnode *nvp;
int error; int error;
error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp); error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp);
if (error) if (error)
return (error); return (error);
*vpp = nvp; *vpp = nvp;
@ -199,7 +199,7 @@ ufs_fhtovp(mp, ufhp, vpp)
struct vnode *nvp; struct vnode *nvp;
int error; int error;
error = VFS_VGET(mp, ufhp->ufid_ino, &nvp); error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
if (error) { if (error) {
*vpp = NULLVP; *vpp = NULLVP;
return (error); return (error);

View File

@ -244,7 +244,7 @@ ufs_mknod(ap)
(*vpp)->v_type = VNON; (*vpp)->v_type = VNON;
ino = ip->i_number; /* Save this before vgone() invalidates ip. */ ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp); 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) { if (error) {
*vpp = NULL; *vpp = NULL;
return (error); return (error);