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.

This effectively reverts r209367.

Tested by:	pho
Reviewed by:	mckusick
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2016-09-08 12:04:45 +00:00
parent df4265774e
commit ccb19123e5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305593

View File

@ -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: