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