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
This commit is contained in:
parent
4c68dee0fb
commit
7746b6461d
@ -1114,6 +1114,20 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user