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...*/
|
/* true if old FS format...*/
|
||||||
#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0)
|
#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
|
static int
|
||||||
ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *cred,
|
ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *cred,
|
||||||
struct thread *td)
|
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);
|
vnode_create_vobject(vdp, DIP(dp, i_size), cnp->cn_thread);
|
||||||
|
|
||||||
bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
|
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:
|
restart:
|
||||||
bp = NULL;
|
bp = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user