svn commit: r276192 - head/sys/kern
Rick Macklem
rmacklem at FreeBSD.org
Wed Dec 24 22:58:09 UTC 2014
Author: rmacklem
Date: Wed Dec 24 22:58:08 2014
New Revision: 276192
URL: https://svnweb.freebsd.org/changeset/base/276192
Log:
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.
Reviewed by: kib
MFC after: 1 week
Modified:
head/sys/kern/vfs_default.c
Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c Wed Dec 24 19:47:50 2014 (r276191)
+++ head/sys/kern/vfs_default.c Wed Dec 24 22:58:08 2014 (r276192)
@@ -401,17 +401,23 @@ 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 will LOR/deadlock if a vn_lock() call
+ * is done on vp. Fortunately, vattr.va_size is only
+ * needed for SEEK_END and the NFSv4 server only uses SEEK_SET.
+ */
+ 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));
}
@@ -420,17 +426,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-head
mailing list