svn commit: r197167 -
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sun Sep 13 16:05:21 UTC 2009
Author: pjd
Date: Sun Sep 13 16:05:20 2009
New Revision: 197167
URL: http://svn.freebsd.org/changeset/base/197167
Log:
Work-around READDIRPLUS problem with .zfs/ and .zfs/snapshot/ directories
by just returning EOPNOTSUPP. This will allow NFS server to fall back to
regular READDIR.
Note that converting inode number to snapshot's vnode is expensive operation.
Snapshots are stored in AVL tree, but based on their names, not inode numbers,
so to convert inode to snapshot vnode we have to interate over all snalshots.
This is not a problem in OpenSolaris, because in their READDIRPLUS
implementation they use VOP_LOOKUP() on d_name, instead of VFS_VGET() on
d_fileno as we do.
PR: kern/125149
Reported by: Weldon Godfrey <wgodfrey at ena.com>
Analysis by: Jaakko Heinonen <jh at saunalahti.fi>
MFC after: 3 days
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Sun Sep 13 15:42:19 2009 (r197166)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Sun Sep 13 16:05:20 2009 (r197167)
@@ -1114,6 +1114,20 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int fla
znode_t *zp;
int err;
+ /*
+ * XXXPJD: zfs_zget() can't operate on virtual entires like .zfs/ or
+ * .zfs/snapshot/ directories, so for now just return EOPNOTSUPP.
+ * This will make NFS to fall back to using READDIR instead of
+ * READDIRPLUS.
+ * Also snapshots are stored in AVL tree, but based on their names,
+ * not inode numbers, so it will be very inefficient to iterate
+ * over all snapshots to find the right one.
+ * Note that OpenSolaris READDIRPLUS implementation does LOOKUP on
+ * d_name, and not VGET on d_fileno as we do.
+ */
+ if (ino == ZFSCTL_INO_ROOT || ino == ZFSCTL_INO_SNAPDIR)
+ return (EOPNOTSUPP);
+
ZFS_ENTER(zfsvfs);
err = zfs_zget(zfsvfs, ino, &zp);
if (err == 0 && zp->z_unlinked) {
More information about the svn-src-all
mailing list