Use vfs_hash_ref(9) to eliminate LK_EXCLOTHER kludge. As a
consequence, the nfs client override of VOP_LOCK1() is no longer needed. Reviewed and tested by: rmacklem Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
54a33d2f97
commit
b6a60ae74a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299413
@ -293,7 +293,7 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp,
|
||||
}
|
||||
|
||||
/*
|
||||
* Anothe variant of nfs_nget(). This one is only used by reopen. It
|
||||
* Another variant of nfs_nget(). This one is only used by reopen. It
|
||||
* takes almost the same args as nfs_nget(), but only succeeds if an entry
|
||||
* exists in the cache. (Since files should already be "open" with a
|
||||
* vnode ref cnt on the node when reopen calls this, it should always
|
||||
@ -332,21 +332,24 @@ nfscl_ngetreopen(struct mount *mntp, u_int8_t *fhp, int fhsize,
|
||||
NFSVOPUNLOCK(nvp, 0);
|
||||
} else if (error == EBUSY) {
|
||||
/*
|
||||
* The LK_EXCLOTHER lock type tells nfs_lock1() to not try
|
||||
* and lock the vnode, but just get a v_usecount on it.
|
||||
* LK_NOWAIT is set so that when vget() returns ENOENT,
|
||||
* vfs_hash_get() fails instead of looping.
|
||||
* If this succeeds, it is safe so long as a vflush() with
|
||||
* It is safe so long as a vflush() with
|
||||
* FORCECLOSE has not been done. Since the Renew thread is
|
||||
* stopped and the MNTK_UNMOUNTF flag is set before doing
|
||||
* a vflush() with FORCECLOSE, we should be ok here.
|
||||
*/
|
||||
if ((mntp->mnt_kern_flag & MNTK_UNMOUNTF))
|
||||
error = EINTR;
|
||||
else
|
||||
error = vfs_hash_get(mntp, hash,
|
||||
(LK_EXCLOTHER | LK_NOWAIT), td, &nvp,
|
||||
newnfs_vncmpf, nfhp);
|
||||
else {
|
||||
vfs_hash_ref(mntp, hash, td, &nvp, newnfs_vncmpf, nfhp);
|
||||
if (nvp == NULL) {
|
||||
error = ENOENT;
|
||||
} else if ((nvp->v_iflag & VI_DOOMED) != 0) {
|
||||
error = ENOENT;
|
||||
vrele(nvp);
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
FREE(nfhp, M_NFSFH);
|
||||
if (error)
|
||||
|
@ -138,7 +138,6 @@ static vop_rmdir_t nfs_rmdir;
|
||||
static vop_symlink_t nfs_symlink;
|
||||
static vop_readdir_t nfs_readdir;
|
||||
static vop_strategy_t nfs_strategy;
|
||||
static vop_lock1_t nfs_lock1;
|
||||
static int nfs_lookitup(struct vnode *, char *, int,
|
||||
struct ucred *, struct thread *, struct nfsnode **);
|
||||
static int nfs_sillyrename(struct vnode *, struct vnode *,
|
||||
@ -167,7 +166,6 @@ struct vop_vector newnfs_vnodeops = {
|
||||
.vop_putpages = ncl_putpages,
|
||||
.vop_inactive = ncl_inactive,
|
||||
.vop_link = nfs_link,
|
||||
.vop_lock1 = nfs_lock1,
|
||||
.vop_lookup = nfs_lookup,
|
||||
.vop_mkdir = nfs_mkdir,
|
||||
.vop_mknod = nfs_mknod,
|
||||
@ -3349,37 +3347,6 @@ struct buf_ops buf_ops_newnfs = {
|
||||
.bop_bdflush = bufbdflush,
|
||||
};
|
||||
|
||||
/*
|
||||
* Cloned from vop_stdlock(), and then the ugly hack added.
|
||||
*/
|
||||
static int
|
||||
nfs_lock1(struct vop_lock1_args *ap)
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* Since vfs_hash_get() calls vget() and it will no longer work
|
||||
* for FreeBSD8 with flags == 0, I can only think of this horrible
|
||||
* hack to work around it. I call vfs_hash_get() with LK_EXCLOTHER
|
||||
* and then handle it here. All I want for this case is a v_usecount
|
||||
* on the vnode to use for recovery, while another thread might
|
||||
* hold a lock on the vnode. I have the other threads blocked, so
|
||||
* there isn't any race problem.
|
||||
*/
|
||||
if ((ap->a_flags & LK_TYPE_MASK) == LK_EXCLOTHER) {
|
||||
if ((ap->a_flags & LK_INTERLOCK) == 0)
|
||||
panic("ncllock1");
|
||||
if ((vp->v_iflag & VI_DOOMED))
|
||||
error = ENOENT;
|
||||
VI_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp),
|
||||
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file,
|
||||
ap->a_line));
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_getacl(struct vop_getacl_args *ap)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user