diff options
author | kib <kib@FreeBSD.org> | 2016-09-22 08:59:58 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-09-22 08:59:58 +0000 |
commit | 50712f510ff041f56e7221aec9eff9a3f9fc3d28 (patch) | |
tree | 030ddfbf1392dff4b3f44128d2e39b423ddfd00a | |
parent | 924101bf21d10b51836d7a3b03634c22c4959183 (diff) | |
download | FreeBSD-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.c | 51 |
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: |