Skip site navigation (1)Skip section navigation (2)
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 -&gt; 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>