Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Feb 2013 13:07:59 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Rick Macklem <rmacklem@uoguelph.ca>
Cc:        FreeBSD Current <freebsd-current@FreeBSD.org>, Sergey Kandaurov <pluknet@gmail.com>, Andriy Gapon <avg@FreeBSD.org>
Subject:   Re: panic: LK_RETRY set with incompatible flags
Message-ID:  <20130203110759.GM2522@kib.kiev.ua>
In-Reply-To: <1423598176.2627168.1359858639862.JavaMail.root@erie.cs.uoguelph.ca>
References:  <510A73A0.9000607@FreeBSD.org> <1423598176.2627168.1359858639862.JavaMail.root@erie.cs.uoguelph.ca>

next in thread | previous in thread | raw e-mail | index | archive | help

--yHpupmvcyB3InP4W
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sat, Feb 02, 2013 at 09:30:39PM -0500, Rick Macklem wrote:
> Andriy Gapon wrote:
> > on 31/01/2013 15:29 Sergey Kandaurov said the following:
> > > Hi.
> > >
> > > Got this assertion on idle NFS server while `ls -la /.zfs/shares/'
> > > issued on NFS client.
> > > kern/vfs_vnops.c:_vn_lock()
> > >                 KASSERT((flags & LK_RETRY) =3D=3D 0 || error =3D=3D 0,
> > >                     ("LK_RETRY set with incompatible flags (0x%x) or
> > > an error occured (%d)",
> > >
> > > panic: LK_RETRY set with incompatible flags (0x200400) or an error
> > > occured (11)
> > >
> > > What does that mean and how is it possible? As you can see, both
> > > parts
> > > of assertion failed.
> > > 11 is EDEADLK
> > > 0x200400: LK_RETRY & LK_UPGRADE
> >=20
> > LK_SHARED, not LK_UPGRADE.
> > Apparently the thread already holds an exlusive lock on the vnode,
> > which you
> > confirm below.
> >=20
> >=20
> > > Tracing pid 2943 tid 101532 td 0xfffffe004f5b7000
> > > kdb_enter() at kdb_enter+0x3e/frame 0xffffff848e45ef50
> > > vpanic() at vpanic+0x147/frame 0xffffff848e45ef90
> > > kassert_panic() at kassert_panic+0x136/frame 0xffffff848e45f000
> > > _vn_lock() at _vn_lock+0x70/frame 0xffffff848e45f070
> > > zfs_lookup() at zfs_lookup+0x392/frame 0xffffff848e45f100
> > > zfs_freebsd_lookup() at zfs_freebsd_lookup+0x6d/frame
> > > 0xffffff848e45f240
> > > VOP_CACHEDLOOKUP_APV() at VOP_CACHEDLOOKUP_APV+0xc2/frame
> > > 0xffffff848e45f260
> > > vfs_cache_lookup() at vfs_cache_lookup+0xcf/frame 0xffffff848e45f2b0
> > > VOP_LOOKUP_APV() at VOP_LOOKUP_APV+0xc2/frame 0xffffff848e45f2d0
> > > lookup() at lookup+0x548/frame 0xffffff848e45f350
> > > nfsvno_namei() at nfsvno_namei+0x1a5/frame 0xffffff848e45f400
> > > nfsrvd_lookup() at nfsrvd_lookup+0x13a/frame 0xffffff848e45f6b0
> > > nfsrvd_dorpc() at nfsrvd_dorpc+0xca5/frame 0xffffff848e45f8a0
> > > nfssvc_program() at nfssvc_program+0x482/frame 0xffffff848e45fa00
> > > svc_run_internal() at svc_run_internal+0x1e9/frame
> > > 0xffffff848e45fba0
> > > svc_thread_start() at svc_thread_start+0xb/frame 0xffffff848e45fbb0
> > > fork_exit() at fork_exit+0x84/frame 0xffffff848e45fbf0
> > > fork_trampoline() at fork_trampoline+0xe/frame 0xffffff848e45fbf0
> > > --- trap 0xc, rip =3D 0x800883e9a, rsp =3D 0x7fffffffd488, rbp =3D
> > > 0x7fffffffd730 ---
> > >
> > > db> show lockedvnods
> > > Locked vnodes
> > >
> > > 0xfffffe02e21b11d8: tag zfs, type VDIR
> > >     usecount 4, writecount 0, refcount 4 mountedhere 0
> > >     flags (VI_ACTIVE)
> > >     v_object 0xfffffe02d9f2eb40 ref 0 pages 0
> > >     lock type zfs: EXCL by thread 0xfffffe004f5b7000 (pid 2943,
> > >     nfsd,
> > > tid 101532)
> > >
> > >
> > >
> I just took a look at zfs_vnops.c and I am probably missing something,
> but I can't see how this ever worked for a lookup of ".." when at the
> root (unless ZFS doesn't do the ".." is the current directory when at
> the root).
>=20
> Here's the code snippet:
> 1442 	if (error =3D=3D 0 && (nm[0] !=3D '.' || nm[1] !=3D '\0')) {
> 1443 	int ltype =3D 0;
> 1444 =09
> 1445 	if (cnp->cn_flags & ISDOTDOT) {
> 1446 	        ltype =3D VOP_ISLOCKED(dvp);
> 1447            VOP_UNLOCK(dvp, 0);
> 1448 	}
> 1449 	ZFS_EXIT(zfsvfs);
> 1450 	error =3D zfs_vnode_lock(*vpp, cnp->cn_lkflags);
> 1451 	if (cnp->cn_flags & ISDOTDOT)
> 1452 	        vn_lock(dvp, ltype | LK_RETRY);
> 1453 	if (error !=3D 0) {
> 1454 	        VN_RELE(*vpp);
> 1455 	        *vpp =3D NULL;
> 1456 	        return (error);
> 1457 	}=20
>=20
> Maybe line# 1451 should be changed to:
>         if ((cnp->cn_flags & ISDOTDOT) && *vpp !=3D dvp)
>=20
> I'm not at all familiar with ZFS, so I've probably way
> off the mark on this, rick
> ps: I hope kib and jhb don't mind being added as cc's, since
>     they are familiar with this stuff, although maybe not ZFS
>     specifics.

VFS (should) never call VOP_LOOKUP for the dotdot and root vnode.
The logic in the lookup() prevents it.

Might it be a missing check in the nfs server code ? (I did not looked yet).

--yHpupmvcyB3InP4W
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iQIcBAEBAgAGBQJRDkUPAAoJEJDCuSvBvK1BaRsP/jK3Y+hIYByw8IwzsWlm1wzo
OXzYznH6HOjp5D4zijl4efx1UiPUYw8FnxLEwUol2hHH8Nkplj7lv1DkaAIHekoC
bRJ/G8+lyJXKZlY9cKMPrZrzGFAwUtxMwZbXTIbfOIjemji1GgtxDmQVSQu0xotW
wU+ae2fNmCdS6+/9rRyKQId1w/M02oZOO3cleoaoFmGI8kVYgYpZ6jHtg0twK3K8
fFLq486TLx/MFX8iUzVrbe5T1h4q+tOENtcDz4xxO4b7P7S34Tb1Z3ZDKl7CEpxy
vjIuu9/4tXuivuyBiJgXQx8Tv5nfOxF7+jPzpbizj56Ggg4xSSdmr68oh3mWoESG
JzeupNk6B/WfBfTA26jKi82lFVGuhm+kIj/KNxHGbOHSIApKHKTvWAt9Vy4vj+fo
E3f0EP3qXpsF856ux9hAeVyQuUMprFcN/XkCNANyiqdeq0H0/rSgFaqoO3JE7Pfw
aC+4l7uwhNplK4rW4MHFL/26AbAEVzNKZcp9zuwAWSv45hakH0EdAyJaPpXCc41a
bYvnmL57oln95d/TjdbI6WW9nbJRKZNEr1r4A4+eKZiOS85AZL277e5dxo34dj+D
SHJHt/GTDpH3YM00uZuQj6yI6EHu/DVD8spgUDIpvaLwRrxY/1HZgMJcD/dmrwRs
nOuhTGDNKp0/WNOPtQX/
=9ruN
-----END PGP SIGNATURE-----

--yHpupmvcyB3InP4W--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130203110759.GM2522>