Ensure that VOP_ACCESSX is called with exclusively locked vnode for
the kernel compiled with QUOTA option. ufs_accessx() upgrades the vdp vnode lock from shared to exclusive to assign the dquot structure to the vnode, and ufs_delete_denied() is called when tvp is locked. Since upgrade drops shared lock when non-blocked upgrade failed, LOR is there. Reported and tested by: Dmitry Pryanishnikov <lynx.ripe gmail com> Tested by: pho PR: kern/147890 MFC after: 1 week
This commit is contained in:
parent
fafb8f11c0
commit
427ef27ec7
@ -77,6 +77,32 @@ 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)
|
||||
@ -232,6 +258,13 @@ 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
restart:
|
||||
bp = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user