Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173098274
D12083.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D12083.id.diff
View Options
Index: head/sys/fs/nfsclient/nfs_clbio.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clbio.c
+++ head/sys/fs/nfsclient/nfs_clbio.c
@@ -365,20 +365,13 @@
int error = 0;
struct vattr vattr;
struct nfsnode *np = VTONFS(vp);
- int old_lock;
+ bool old_lock;
/*
- * Grab the exclusive lock before checking whether the cache is
- * consistent.
- * XXX - We can make this cheaper later (by acquiring cheaper locks).
- * But for now, this suffices.
+ * Ensure the exclusove access to the node before checking
+ * whether the cache is consistent.
*/
- old_lock = ncl_upgrade_vnlock(vp);
- if (vp->v_iflag & VI_DOOMED) {
- error = EBADF;
- goto out;
- }
-
+ old_lock = ncl_excl_start(vp);
mtx_lock(&np->n_mtx);
if (np->n_flag & NMODIFIED) {
mtx_unlock(&np->n_mtx);
@@ -386,9 +379,7 @@
if (vp->v_type != VDIR)
panic("nfs: bioread, not dir");
ncl_invaldir(vp);
- error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
+ error = ncl_vinvalbuf(vp, V_SAVE | V_ALLOWCLEAN, td, 1);
if (error != 0)
goto out;
}
@@ -404,16 +395,14 @@
mtx_unlock(&np->n_mtx);
error = VOP_GETATTR(vp, &vattr, cred);
if (error)
- return (error);
+ goto out;
mtx_lock(&np->n_mtx);
if ((np->n_flag & NSIZECHANGED)
|| (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime))) {
mtx_unlock(&np->n_mtx);
if (vp->v_type == VDIR)
ncl_invaldir(vp);
- error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
+ error = ncl_vinvalbuf(vp, V_SAVE | V_ALLOWCLEAN, td, 1);
if (error != 0)
goto out;
mtx_lock(&np->n_mtx);
@@ -423,7 +412,7 @@
mtx_unlock(&np->n_mtx);
}
out:
- ncl_downgrade_vnlock(vp, old_lock);
+ ncl_excl_finish(vp, old_lock);
return (error);
}
@@ -608,8 +597,6 @@
while (error == NFSERR_BAD_COOKIE) {
ncl_invaldir(vp);
error = ncl_vinvalbuf(vp, 0, td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
/*
* Yuck! The directory has been modified on the
@@ -933,8 +920,6 @@
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
error = ncl_vinvalbuf(vp, V_SAVE | ((ioflag &
IO_VMIO) != 0 ? V_VMIO : 0), td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
if (error != 0)
return (error);
} else
@@ -1016,9 +1001,6 @@
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
error = ncl_vinvalbuf(vp, V_SAVE | ((ioflag &
IO_VMIO) != 0 ? V_VMIO : 0), td, 1);
- if (error == 0 &&
- (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
if (error != 0)
return (error);
wouldcommit = biosize;
@@ -1336,7 +1318,7 @@
struct nfsnode *np = VTONFS(vp);
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
int error = 0, slpflag, slptimeo;
- int old_lock = 0;
+ bool old_lock;
ASSERT_VOP_LOCKED(vp, "ncl_vinvalbuf");
@@ -1352,16 +1334,9 @@
slptimeo = 0;
}
- old_lock = ncl_upgrade_vnlock(vp);
- if (vp->v_iflag & VI_DOOMED) {
- /*
- * Since vgonel() uses the generic vinvalbuf() to flush
- * dirty buffers and it does not call this function, it
- * is safe to just return OK when VI_DOOMED is set.
- */
- ncl_downgrade_vnlock(vp, old_lock);
- return (0);
- }
+ old_lock = ncl_excl_start(vp);
+ if (old_lock)
+ flags |= V_ALLOWCLEAN;
/*
* Now, flush as required.
@@ -1400,7 +1375,7 @@
np->n_flag &= ~NMODIFIED;
mtx_unlock(&np->n_mtx);
out:
- ncl_downgrade_vnlock(vp, old_lock);
+ ncl_excl_finish(vp, old_lock);
return error;
}
Index: head/sys/fs/nfsclient/nfs_clnode.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clnode.c
+++ head/sys/fs/nfsclient/nfs_clnode.c
@@ -141,6 +141,9 @@
* happened to return an error no special casing is needed).
*/
mtx_init(&np->n_mtx, "NEWNFSnode lock", NULL, MTX_DEF | MTX_DUPOK);
+ lockinit(&np->n_excl, PVFS, "nfsupg", VLKTIMEOUT, LK_NOSHARE |
+ LK_CANRECURSE);
+
/*
* NFS supports recursive and shared locking.
*/
@@ -167,6 +170,7 @@
*npp = NULL;
FREE((caddr_t)np->n_fhp, M_NFSFH);
mtx_destroy(&np->n_mtx);
+ lockdestroy(&np->n_excl);
uma_zfree(newnfsnode_zone, np);
return (error);
}
@@ -332,6 +336,7 @@
if (np->n_v4 != NULL)
FREE((caddr_t)np->n_v4, M_NFSV4NODE);
mtx_destroy(&np->n_mtx);
+ lockdestroy(&np->n_excl);
uma_zfree(newnfsnode_zone, vp->v_data);
vp->v_data = NULL;
return (0);
Index: head/sys/fs/nfsclient/nfs_clport.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clport.c
+++ head/sys/fs/nfsclient/nfs_clport.c
@@ -230,6 +230,8 @@
* happened to return an error no special casing is needed).
*/
mtx_init(&np->n_mtx, "NEWNFSnode lock", NULL, MTX_DEF | MTX_DUPOK);
+ lockinit(&np->n_excl, PVFS, "nfsupg", VLKTIMEOUT, LK_NOSHARE |
+ LK_CANRECURSE);
/*
* Are we getting the root? If so, make sure the vnode flags
@@ -271,6 +273,7 @@
if (error != 0) {
*npp = NULL;
mtx_destroy(&np->n_mtx);
+ lockdestroy(&np->n_excl);
FREE((caddr_t)nfhp, M_NFSFH);
if (np->n_v4 != NULL)
FREE((caddr_t)np->n_v4, M_NFSV4NODE);
Index: head/sys/fs/nfsclient/nfs_clsubs.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clsubs.c
+++ head/sys/fs/nfsclient/nfs_clsubs.c
@@ -135,30 +135,33 @@
mtx_unlock(&np->n_mtx);
}
-int
-ncl_upgrade_vnlock(struct vnode *vp)
+bool
+ncl_excl_start(struct vnode *vp)
{
- int old_lock;
+ struct nfsnode *np;
+ int vn_lk;
- ASSERT_VOP_LOCKED(vp, "ncl_upgrade_vnlock");
- old_lock = NFSVOPISLOCKED(vp);
- if (old_lock != LK_EXCLUSIVE) {
- KASSERT(old_lock == LK_SHARED,
- ("ncl_upgrade_vnlock: wrong old_lock %d", old_lock));
- /* Upgrade to exclusive lock, this might block */
- NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY);
- }
- return (old_lock);
+ ASSERT_VOP_LOCKED(vp, "ncl_excl_start");
+ vn_lk = NFSVOPISLOCKED(vp);
+ if (vn_lk == LK_EXCLUSIVE)
+ return (false);
+ KASSERT(vn_lk == LK_SHARED,
+ ("ncl_excl_start: wrong vnode lock %d", vn_lk));
+ /* Ensure exclusive access, this might block */
+ np = VTONFS(vp);
+ lockmgr(&np->n_excl, LK_EXCLUSIVE, NULL);
+ return (true);
}
void
-ncl_downgrade_vnlock(struct vnode *vp, int old_lock)
+ncl_excl_finish(struct vnode *vp, bool old_lock)
{
- if (old_lock != LK_EXCLUSIVE) {
- KASSERT(old_lock == LK_SHARED, ("wrong old_lock %d", old_lock));
- /* Downgrade from exclusive lock. */
- NFSVOPLOCK(vp, LK_DOWNGRADE | LK_RETRY);
- }
+ struct nfsnode *np;
+
+ if (!old_lock)
+ return;
+ np = VTONFS(vp);
+ lockmgr(&np->n_excl, LK_RELEASE, NULL);
}
#ifdef NFS_ACDEBUG
Index: head/sys/fs/nfsclient/nfs_clvnops.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c
+++ head/sys/fs/nfsclient/nfs_clvnops.c
@@ -520,8 +520,6 @@
if (np->n_flag & NMODIFIED) {
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
if (error == EINTR || error == EIO) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -558,8 +556,6 @@
np->n_direofoffset = 0;
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
if (error == EINTR || error == EIO) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -580,8 +576,6 @@
if (np->n_directio_opens == 0) {
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
if (error) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -722,8 +716,6 @@
}
} else {
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
}
mtx_lock(&np->n_mtx);
}
@@ -942,9 +934,7 @@
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, vap->va_size == 0 ?
0 : V_SAVE, td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
- if (error != 0) {
+ if (error != 0) {
vnode_pager_setsize(vp, tsize);
return (error);
}
@@ -971,8 +961,6 @@
(np->n_flag & NMODIFIED) && vp->v_type == VREG) {
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- return (EBADF);
if (error == EINTR || error == EIO)
return (error);
} else
@@ -1676,9 +1664,7 @@
* unnecessary delayed writes later.
*/
error = ncl_vinvalbuf(vp, 0, cnp->cn_thread, 1);
- if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
- error = EBADF;
- else if (error != EINTR && error != EIO)
+ if (error != EINTR && error != EIO)
/* Do the rpc */
error = nfs_removerpc(dvp, vp, cnp->cn_nameptr,
cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread);
@@ -3089,10 +3075,6 @@
if ((np->n_flag & NMODIFIED) || ret ||
np->n_change != va.va_filerev) {
(void) ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if ((vp->v_iflag & VI_DOOMED) != 0) {
- NFSVOPUNLOCK(vp, 0);
- return (EBADF);
- }
np->n_attrstamp = 0;
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
ret = VOP_GETATTR(vp, &va, cred);
Index: head/sys/fs/nfsclient/nfsnode.h
===================================================================
--- head/sys/fs/nfsclient/nfsnode.h
+++ head/sys/fs/nfsclient/nfsnode.h
@@ -92,6 +92,8 @@
*/
struct nfsnode {
struct mtx n_mtx; /* Protects all of these members */
+ struct lock n_excl; /* Exclusive helper for shared
+ vnode lock */
u_quad_t n_size; /* Current size of file */
u_quad_t n_brev; /* Modify rev when cached */
u_quad_t n_lrev; /* Modify rev for lease */
@@ -184,8 +186,8 @@
int ncl_nget(struct mount *, u_int8_t *, int, struct nfsnode **, int);
nfsuint64 *ncl_getcookie(struct nfsnode *, off_t, int);
void ncl_invaldir(struct vnode *);
-int ncl_upgrade_vnlock(struct vnode *);
-void ncl_downgrade_vnlock(struct vnode *, int);
+bool ncl_excl_start(struct vnode *);
+void ncl_excl_finish(struct vnode *, bool old_lock);
void ncl_dircookie_lock(struct nfsnode *);
void ncl_dircookie_unlock(struct nfsnode *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 24, 2:13 PM (35 m, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39531342
Default Alt Text
D12083.id.diff (10 KB)
Attached To
Mode
D12083: Do not drop NFS vnode lock when performing consistency checks.
Attached
Detach File
Event Timeline
Log In to Comment