Date: Fri, 18 Jun 2010 10:18:06 +0300 From: Dmitry Pryanishnikov <lynx.ripe@gmail.com> To: Kostik Belousov <kostikbel@gmail.com> Cc: freebsd-fs@freebsd.org, trasz@freebsd.org Subject: Re: kern/147890: [ufs] [regression] ufs-related lock problem in RELENG_8 (18.04.2010 -> 20.04.2010) Message-ID: <AANLkTiljxpcIEmrxbp5Q8cqYg9ELqlqJmzHrxawF48wJ@mail.gmail.com> In-Reply-To: <20100617083239.GZ13238@deviant.kiev.zoral.com.ua> References: <201006162220.o5GMK3uM002900@freefall.freebsd.org> <20100617072841.GY13238@deviant.kiev.zoral.com.ua> <20100617083239.GZ13238@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Hello! 2010/6/17 Kostik Belousov <kostikbel@gmail.com>: > > What _could_ happen in your case is the relock in ufs_accessx for QUOTA. > ufs_delete_denied() calls VOP_ACCESSX for both parent directory > and target vnode while parent directory is locked. If source directory > is not exclusively locked, LOR can happen, since ufs_accessx has to > unlock and lock directory vnode. I am not sure how many similar cases > of VOP_ACCESS[X] is places in the problematic locations. > > Try the (untested) patch below. Thank you! The kernel with this patch applied (RELENG_8 date =3D 14.06.2010) has been running for 9 hours, the problem does not manifest itself (with unpatched kernel the problem typically appear within 1st hour of uptime). > > diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c > index 0030c52..c779491 100644 > --- a/sys/ufs/ufs/ufs_lookup.c > +++ b/sys/ufs/ufs/ufs_lookup.c > @@ -77,6 +77,32 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, CTLFLAG_RW, &di= rchk, 0, ""); > =A0/* true if old FS format...*/ > =A0#define OFSFMT(vp) =A0 =A0 ((vp)->v_mount->mnt_maxsymlinklen <=3D 0) > > +#ifdef QUOTA > +static int > +ufs_lookup_upgrade_lock(struct vnode *vp) > +{ > + =A0 =A0 =A0 int error; > + > + =A0 =A0 =A0 ASSERT_VOP_LOCKED(vp, __FUNCTION__); > + =A0 =A0 =A0 if (VOP_ISLOCKED(vp) =3D=3D LK_EXCLUSIVE) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (0); > + > + =A0 =A0 =A0 error =3D 0; > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* Upgrade vnode lock, since getinoquota() > + =A0 =A0 =A0 =A0* requires exclusive lock to modify inode. > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 vhold(vp); > + =A0 =A0 =A0 vn_lock(vp, LK_UPGRADE | LK_RETRY); > + =A0 =A0 =A0 VI_LOCK(vp); > + =A0 =A0 =A0 if (vp->v_iflag & VI_DOOMED) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D ENOENT; > + =A0 =A0 =A0 vdropl(vp); > + =A0 =A0 =A0 return (error); > +} > +#endif > + > =A0static int > =A0ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *= cred, > =A0 =A0 struct thread *td) > @@ -232,6 +258,13 @@ ufs_lookup_ino(struct vnode *vdp, struct vnode **vpp= , struct componentname *cnp, > =A0 =A0 =A0 =A0vnode_create_vobject(vdp, DIP(dp, i_size), cnp->cn_thread)= ; > > =A0 =A0 =A0 =A0bmask =3D VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_io= size - 1; > +#ifdef QUOTA > + =A0 =A0 =A0 if ((nameiop =3D=3D DELETE || nameiop =3D=3D RENAME) && (fl= ags & ISLASTCN)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D ufs_lookup_upgrade_lock(vdp); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (error !=3D 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (error); > + =A0 =A0 =A0 } > +#endif > > =A0restart: > =A0 =A0 =A0 =A0bp =3D NULL; > --=20 Sincerely, Dmitry nic-hdl: LYNX-RIPE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTiljxpcIEmrxbp5Q8cqYg9ELqlqJmzHrxawF48wJ>