]> granicus.if.org Git - zfs/commitdiff
Return correct type and offset from zfs_readdir
authorRichard Yao <ryao@gentoo.org>
Sun, 4 Aug 2013 18:58:45 +0000 (14:58 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 7 Aug 2013 23:16:43 +0000 (16:16 -0700)
zfs_readdir() is used by getdents(), which provides a list of all files
in directory, their types and an offset that be used by llseek() to seek
to the next directory entry.

On Solaris, the first two directory entries "." and ".." respectively
have offsets 1 and 2 on ZFS while the other files have rather large
numbers. Currently, ZFSOnLinux is  giving "." offset 0 and all other
entries large numbers. The first entry's next entry offset points to
itself, which causes software that uses llseek() in conjunction with
getdents() for filesystem navigation to enter an infinite loop.  The
offsets used for each directory entry are filesystem specific on all
platforms, so we can fix this by adopting the Solaris behavior.

Also, we currently report each directory entry as having type 0 (???).
This is not wrong, but we can do better. getdents() on Solaris does not
appear to provide this information, but it does on Linux and Mac OS X
do. ZFS provides easy access to type information in zfs_readdir(), so
this patch provides this as well.

Reported-by: Andrey <andrey@kudinov.su>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #1624

module/zfs/zfs_vnops.c

index 3c3e8db4b05829ad702b8a4a7c881a62ba50581c..db5d3856a6aced6c51b0b5f2886c56d6fb7dfd6b 100644 (file)
@@ -2099,7 +2099,7 @@ zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
                        objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
                }
                done = filldir(dirent, zap.za_name, strlen(zap.za_name),
-                              zap_cursor_serialize(&zc), objnum, 0);
+                              *pos, objnum, ZFS_DIRENT_TYPE(zap.za_first_integer));
                if (done) {
                        break;
                }