Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Sep 2009 16:05:20 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r197167 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <200909131605.n8DG5K5Y025402@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@ena.com>
  Analysis by:	Jaakko Heinonen <jh@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) {



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