Re: panic: LK_RETRY set with incompatible flags

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Wed, 06 Feb 2013 11:14:16 +0200
on 06/02/2013 03:30 Rick Macklem said the following:
> Since I don't understand ZFS, I have just posted a query on
> freebsd-fs_at_, which I hope will get noticed by people who
> may know why ZFS is doing this.

Actually I think I have an explanation, just been busy past couple of days.
The problem is precisely with .zfs/shares, which is a strange beast that
currently has no practical use on FreeBSD.

.zfs/shares has its own on-disk node.  The node has some special properties:
- it is a directory node
- it is not reachable from any other node
- its parent ID is set to itself (as for a root node)
- its ID is stored in a special filesystem property

At run time ZFS creates special vnodes for .zfs, .zfs/snapshot and .zfs/shares.
The vnodes are special is a sense that each of them has its own v_ops different
from v_ops of the regular ZFS vnodes.
For example, vop_lookup method of .zfs/shares should return the .zfs vnode for a
".." lookup.  The v_ops are sane and self-consistent and everything is supposed
to work fine with them and provide some ".zfs magic".

Except for one hole.  The .zfs/shares vnode has the same inode number as the
on-disk node.  Also, its vop_vptofh generates fid_t consistent with the on-disk
node.
Then, ZFS vfs_fhtovp has a special case to do the right thing for fid_t-s of
.zfs and .zfs/snapshot.  But for some reason there is no special code for
.zfs/shares.  And so a regular ZFS vnode is created/returned in that case.

And this is the problem.

Regular zfs_lookup for ".." in this vnode returns the vnode itself because of
the magic properties described in the beginning.  And so on.

We seem to have inherited this problem from the upstream:
http://thread.gmane.org/gmane.os.illumos.zfs/599

I believe that currently NFS is the only user of VOP_FID and VFS_FHTOVP.
There are also getfh(2), lgetfh(2) and fhopen(2), but I am not sure how widely
they are used.

In either case, I believe that zfs_fhtovp should grow a check for object ==
zfsvfs->z_shares_dir and return the "made up" .zfs/shares vnode in that case
(instead of a regular zfs vnode).

Additionally, I am not sure, but perhaps zfs_vget() should do the same kind of
tricks as zfs_fhtovp.

-- 
Andriy Gapon
Received on Wed Feb 06 2013 - 08:14:31 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:34 UTC