summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-09-22 08:59:58 +0000
committerkib <kib@FreeBSD.org>2016-09-22 08:59:58 +0000
commit50712f510ff041f56e7221aec9eff9a3f9fc3d28 (patch)
tree030ddfbf1392dff4b3f44128d2e39b423ddfd00a
parent924101bf21d10b51836d7a3b03634c22c4959183 (diff)
downloadFreeBSD-src-50712f510ff041f56e7221aec9eff9a3f9fc3d28.zip
FreeBSD-src-50712f510ff041f56e7221aec9eff9a3f9fc3d28.tar.gz
MFC r305593:
There is no need to upgrade the last dvp lock on lookups for modifying operations. Instead of upgrading, assert that the lock is exclusive. Explain the cause in comments.
-rw-r--r--sys/ufs/ufs/ufs_lookup.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index dcff4fb..a86f70d 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -76,32 +76,6 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, "");
/* true if old FS format...*/
#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0)
-#ifdef QUOTA
-static int
-ufs_lookup_upgrade_lock(struct vnode *vp)
-{
- int error;
-
- ASSERT_VOP_LOCKED(vp, __FUNCTION__);
- if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
- return (0);
-
- error = 0;
-
- /*
- * Upgrade vnode lock, since getinoquota()
- * requires exclusive lock to modify inode.
- */
- vhold(vp);
- vn_lock(vp, LK_UPGRADE | LK_RETRY);
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED)
- error = ENOENT;
- vdropl(vp);
- return (error);
-}
-#endif
-
static int
ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *cred,
struct thread *td)
@@ -259,12 +233,25 @@ ufs_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp,
vnode_create_vobject(vdp, DIP(dp, i_size), cnp->cn_thread);
bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
-#ifdef QUOTA
- if ((nameiop == DELETE || nameiop == RENAME) && (flags & ISLASTCN)) {
- error = ufs_lookup_upgrade_lock(vdp);
- if (error != 0)
- return (error);
- }
+
+#ifdef DEBUG_VFS_LOCKS
+ /*
+ * Assert that the directory vnode is locked, and locked
+ * exclusively for the last component lookup for modifying
+ * operations.
+ *
+ * The directory-modifying operations need to save
+ * intermediate state in the inode between namei() call and
+ * actual directory manipulations. See fields in the struct
+ * inode marked as 'used during directory lookup'. We must
+ * ensure that upgrade in namei() does not happen, since
+ * upgrade might need to unlock vdp. If quotas are enabled,
+ * getinoquota() also requires exclusive lock to modify inode.
+ */
+ ASSERT_VOP_LOCKED(vdp, "ufs_lookup1");
+ if ((nameiop == CREATE || nameiop == DELETE || nameiop == RENAME) &&
+ (flags & (LOCKPARENT | ISLASTCN)) == (LOCKPARENT | ISLASTCN))
+ ASSERT_VOP_ELOCKED(vdp, "ufs_lookup2");
#endif
restart:
OpenPOWER on IntegriCloud