From fff596880afe0e06b433fd3afbe1a2335bf88709 Mon Sep 17 00:00:00 2001 From: Prashanth Pai Date: Wed, 27 Apr 2016 13:37:07 +0530 Subject: posix: Set correct d_type for readdirp() calls dirent.d_type can contain the type of the directory entry. The 'd_type' struct member in dirent is present in Linux and many BSD flavours. However, filling d_type with correct value requires support from the underlying filesystem. If not, d_type is set to DT_UNKNOWN. XFS added support for d_type as part of their newer version 5 on-disk format. However, this requires Linux >= 3.15, xfsprogs >= 3.2.0 and the bricks to be formatted using the new format. This patch enables posix xlator to set d_type to the right value even when the underlying filesystem does not support it. d_type can be set using information previously fetched by stat() on the dir entry. This will aid FUSE applications to leverage d_type to avoid the expense of calling lstat() if further actions depend on the type of the file. Refer `man 3 readdir` and `man 2 getdents` > Change-Id: Ic5a262fe4c64122726b4fae2d1bea375c559ca04 > Signed-off-by: Prashanth Pai > Reviewed-on: http://review.gluster.org/14095 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Jeff Darcy (cherry picked from commit 77def44d497d090ef3f393b6d9403c1a29dcf993) Change-Id: Iaaf2a7c85ce8deb9043772e04a76b904d8bf076e BUG: 1332396 Signed-off-by: Prashanth Pai Reviewed-on: http://review.gluster.org/14175 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Niels de Vos CentOS-regression: Gluster Build System --- xlators/storage/posix/src/posix.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'xlators') diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index b823257d540..6cd7df54909 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -6059,6 +6059,24 @@ posix_entry_xattr_fill (xlator_t *this, inode_t *inode, } +#ifdef _DIRENT_HAVE_D_TYPE +static int +posix_d_type_from_ia_type (ia_type_t type) +{ + switch (type) { + case IA_IFDIR: return DT_DIR; + case IA_IFCHR: return DT_CHR; + case IA_IFBLK: return DT_BLK; + case IA_IFIFO: return DT_FIFO; + case IA_IFLNK: return DT_LNK; + case IA_IFREG: return DT_REG; + case IA_IFSOCK: return DT_SOCK; + default: return DT_UNKNOWN; + } +} +#endif + + int posix_readdirp_fill (xlator_t *this, fd_t *fd, gf_dirent_t *entries, dict_t *dict) { @@ -6116,6 +6134,17 @@ posix_readdirp_fill (xlator_t *this, fd_t *fd, gf_dirent_t *entries, dict_t *dic entry->d_stat = stbuf; if (stbuf.ia_ino) entry->d_ino = stbuf.ia_ino; + +#ifdef _DIRENT_HAVE_D_TYPE + if (entry->d_type == DT_UNKNOWN && !IA_ISINVAL(stbuf.ia_type)) { + /* The platform supports d_type but the underlying + filesystem doesn't. We set d_type to the correct + value from ia_type */ + entry->d_type = + posix_d_type_from_ia_type (stbuf.ia_type); + } +#endif + inode = NULL; } -- cgit