summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
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 /sys/ufs/ufs
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.
Diffstat (limited to 'sys/ufs/ufs')
-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