summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-09-05 13:25:27 +0000
committerkib <kib@FreeBSD.org>2014-09-05 13:25:27 +0000
commitdb4159a95c99ba2e1d62e884a99c2e2688d0119e (patch)
tree0774d9b50ac48dbb2b82dfec04a76c37b132d800 /sys/ufs
parent78a27e5e59a68d71ac8cc78ba7d6143c4a75bb98 (diff)
downloadFreeBSD-src-db4159a95c99ba2e1d62e884a99c2e2688d0119e.zip
FreeBSD-src-db4159a95c99ba2e1d62e884a99c2e2688d0119e.tar.gz
MFC r270797:
Direct access to the quota files, in particular, lookup, causes lock conflict with the quota metadata access. Mark quota vnode lock as recursive and always exclusive to avoid the problem. Approved by: re (gjb)
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/ufs_quota.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index f8bc981..a6e139a 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -557,8 +557,21 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
if (*vpp != vp)
quotaoff1(td, mp, type);
+ /*
+ * When the directory vnode containing the quota file is
+ * inactivated, due to the shared lookup of the quota file
+ * vput()ing the dvp, the qsyncvp() call for the containing
+ * directory would try to acquire the quota lock exclusive.
+ * At the same time, lookup already locked the quota vnode
+ * shared. Mark the quota vnode lock as allowing recursion
+ * and automatically converting shared locks to exclusive.
+ *
+ * Also mark quota vnode as system.
+ */
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
vp->v_vflag |= VV_SYSTEM;
+ VN_LOCK_AREC(vp);
+ VN_LOCK_DSHARE(vp);
VOP_UNLOCK(vp, 0);
*vpp = vp;
/*
OpenPOWER on IntegriCloud