diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-05-15 21:12:08 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-05-15 21:12:08 +0000 |
commit | 94ff93f449f6846c6c61435659387b97cfd4aa8c (patch) | |
tree | 4a74e55c92f8d4993ed69006e456d2e6870c355c | |
parent | 7e2cfac5e09cab2e6a3c4e05c476c2326bb4ba09 (diff) | |
download | FreeBSD-src-94ff93f449f6846c6c61435659387b97cfd4aa8c.zip FreeBSD-src-94ff93f449f6846c6c61435659387b97cfd4aa8c.tar.gz |
This change grabs the vnode lock for NFS client vnodes when calling
VOP_SETATTR() or VOP_GETATTR(); without these locks (a) VFS_DEBUG_LOCKS
will panic, and (b) it may be possible to corrupt entries in the cached
vnode attributes in the nfsnode, since nfsnode attribute cache data is
also protected by the vnode lock.
Approved by: re (jhb)
Pointed out by: VFS_DEBUG_LOCKS
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 4 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 4 |
2 files changed, 7 insertions, 1 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 379419e..088be65 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -1063,6 +1063,8 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, slpflag, slptimeo; + ASSERT_VOP_LOCKED(vp, "nfs_vinvalbuf"); + VI_LOCK(vp); if (vp->v_iflag & VI_XLOCK) { /* XXX Should we wait here? */ @@ -1344,7 +1346,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) uiop->uio_resid = 0; } } - ASSERT_VOP_LOCKED(vp, "nfs_doio"); + /* ASSERT_VOP_LOCKED(vp, "nfs_doio"); */ if (p && (vp->v_vflag & VV_TEXT) && (np->n_mtime != np->n_vattr.va_mtime.tv_sec)) { uprintf("Process killed due to text file modification\n"); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index a3f7d8f..9e23230 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -526,7 +526,9 @@ nfs_close(struct vop_close_args *ap) error = nfs_flush(vp, ap->a_cred, MNT_WAIT, ap->a_td, cm); /* np->n_flag &= ~NMODIFIED; */ } else { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, ap->a_td); error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_td, 1); + VOP_UNLOCK(vp, 0, ap->a_td); } np->n_attrstamp = 0; } @@ -3131,7 +3133,9 @@ nfsfifo_close(struct vop_close_args *ap) vattr.va_atime = np->n_atim; if (np->n_flag & NUPD) vattr.va_mtime = np->n_mtim; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, ap->a_td); (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_td); + VOP_UNLOCK(vp, 0, ap->a_td); } } return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); |