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:
parent
ac59490b5e
commit
a0595d0249
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=92462
@ -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));
|
||||
|
@ -352,7 +352,8 @@ cd9660_lookup(ap)
|
||||
*/
|
||||
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 @@ cd9660_lookup(ap)
|
||||
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)
|
||||
|
@ -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 @@ cd9660_ihashget(dev, inum)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 *));
|
||||
|
@ -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. */
|
||||
@ -717,6 +721,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
ip->i_dev = dev;
|
||||
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
|
||||
|
@ -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 *));
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -122,15 +122,19 @@ hpfs_hphashget(dev, ino)
|
||||
}
|
||||
#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 @@ hpfs_hphashvget(dev, ino, td)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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(error)
|
||||
return(error);
|
||||
}
|
||||
|
||||
if( lockparent && (flags & ISLASTCN) &&
|
||||
(error = VOP_LOCK(dvp, 0, cnp->cn_thread)) ) {
|
||||
vput( *(ap->a_vpp) );
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 @@ smbfs_sync(mp, waitfor, cred, td)
|
||||
* 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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 @@ ufs_ihashget(dev, inum)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -601,7 +601,8 @@ ext2_lookup(ap)
|
||||
*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 @@ ext2_lookup(ap)
|
||||
*/
|
||||
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 @@ ext2_lookup(ap)
|
||||
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 @@ ext2_lookup(ap)
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ ext2_sync(mp, waitfor, cred, td)
|
||||
* 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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -601,7 +601,8 @@ ext2_lookup(ap)
|
||||
*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 @@ ext2_lookup(ap)
|
||||
*/
|
||||
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 @@ ext2_lookup(ap)
|
||||
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 @@ ext2_lookup(ap)
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ ext2_sync(mp, waitfor, cred, td)
|
||||
* 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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -352,7 +352,8 @@ cd9660_lookup(ap)
|
||||
*/
|
||||
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 @@ cd9660_lookup(ap)
|
||||
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)
|
||||
|
@ -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 @@ cd9660_ihashget(dev, inum)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 *));
|
||||
|
@ -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. */
|
||||
@ -717,6 +721,18 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
ip->i_dev = dev;
|
||||
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
|
||||
|
@ -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 *));
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
* 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 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
* 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 =
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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 @@ ufs_ihashget(dev, inum)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -508,14 +508,8 @@ ufs_lookup(ap)
|
||||
*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 @@ ufs_lookup(ap)
|
||||
* 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 @@ ufs_lookup(ap)
|
||||
*/
|
||||
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 @@ ufs_lookup(ap)
|
||||
*/
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user