svn commit: r276440 - stable/9/sys/kern
Rick Macklem
rmacklem at FreeBSD.org
Wed Dec 31 01:29:45 UTC 2014
Author: rmacklem
Date: Wed Dec 31 01:29:44 2014
New Revision: 276440
URL: https://svnweb.freebsd.org/changeset/base/276440
Log:
MFC: r276192, r276200
Modify vop_stdadvlock{async}() so that it only
locks/unlocks the vnode and does a VOP_GETATTR()
for the SEEK_END case. This is safe to do, since
lf_advlock{async}() only uses the size argument
for the SEEK_END case.
The NFSv4 server needs this when
vfs.nfsd.enable_locallocks!=0 since locking the
vnode results in a LOR that can cause a deadlock
for the nfsd threads.
Modified:
stable/9/sys/kern/vfs_default.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/kern/vfs_default.c
==============================================================================
--- stable/9/sys/kern/vfs_default.c Wed Dec 31 00:54:38 2014 (r276439)
+++ stable/9/sys/kern/vfs_default.c Wed Dec 31 01:29:44 2014 (r276440)
@@ -399,17 +399,24 @@ int
vop_stdadvlock(struct vop_advlock_args *ap)
{
struct vnode *vp;
- struct ucred *cred;
struct vattr vattr;
int error;
vp = ap->a_vp;
- cred = curthread->td_ucred;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
- if (error)
- return (error);
+ if (ap->a_fl->l_whence == SEEK_END) {
+ /*
+ * The NFSv4 server must avoid doing a vn_lock() here, since it
+ * can deadlock the nfsd threads, due to a LOR. Fortunately
+ * the NFSv4 server always uses SEEK_SET and this code is
+ * only required for the SEEK_END case.
+ */
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ if (error)
+ return (error);
+ } else
+ vattr.va_size = 0;
return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size));
}
@@ -418,17 +425,19 @@ int
vop_stdadvlockasync(struct vop_advlockasync_args *ap)
{
struct vnode *vp;
- struct ucred *cred;
struct vattr vattr;
int error;
vp = ap->a_vp;
- cred = curthread->td_ucred;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
- if (error)
- return (error);
+ if (ap->a_fl->l_whence == SEEK_END) {
+ /* The size argument is only needed for SEEK_END. */
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ if (error)
+ return (error);
+ } else
+ vattr.va_size = 0;
return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size));
}
More information about the svn-src-stable-9
mailing list