From 7042ac8cd7a89d0a9f85501aba83010ea1bb1b65 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 15 May 2003 21:12:08 +0000 Subject: [PATCH] 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 --- sys/nfsclient/nfs_bio.c | 4 +++- sys/nfsclient/nfs_vnops.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 379419ecdb6..088be6507d1 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 a3f7d8f143a..9e23230bac7 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));