diff options
-rw-r--r-- | tests/bugs/posix/bug-1175711.c | 37 | ||||
-rwxr-xr-x | tests/bugs/posix/bug-1175711.t | 30 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 29 |
3 files changed, 96 insertions, 0 deletions
diff --git a/tests/bugs/posix/bug-1175711.c b/tests/bugs/posix/bug-1175711.c new file mode 100644 index 00000000000..fbbea3f636b --- /dev/null +++ b/tests/bugs/posix/bug-1175711.c @@ -0,0 +1,37 @@ +#include <stdio.h> +#include <dirent.h> +#include <string.h> +#include <assert.h> + +int +main(int argc, char **argv) +{ + DIR *dir = NULL; + struct dirent *entry = NULL; + int ret = 0; + char *path = NULL; + + assert (argc == 2); + path = argv[1]; + + dir = opendir(path); + if (!dir) { + printf("opendir(%s) failed.\n", path); + return -1; + } + +#ifdef _DIRENT_HAVE_D_TYPE + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_UNKNOWN) { + printf("d_type found to be DT_UNKNOWN\n"); + ret = -1; + break; + } + } +#endif + + if (dir) + closedir(dir); + + return ret; +} diff --git a/tests/bugs/posix/bug-1175711.t b/tests/bugs/posix/bug-1175711.t new file mode 100755 index 00000000000..f4162544d92 --- /dev/null +++ b/tests/bugs/posix/bug-1175711.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +# Create, start and mount the volume. +TEST glusterd; +TEST $CLI volume create $V0 $H0:$B0/$V0; +TEST $CLI volume start $V0; +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 + +# Compile the test program +TEST $CC -Wall $(dirname $0)/bug-1175711.c -o $(dirname $0)/bug-1175711 + +# Create directory and some entries inside them. +mkdir -p $M0/dir-bug-1175711 +mkdir -p $M0/dir-bug-1175711/DT_DIR +touch $M0/dir-bug-1175711/DT_REG + +# Invoke the test program and pass path of directory to it. +TEST $(dirname $0)/bug-1175711 $M0/dir-bug-1175711 + +# Unmount, stop and delete the volume +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +TEST $CLI volume stop $V0; +TEST $CLI volume delete $V0; + +cleanup; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 474c47c911f..7475839972a 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -5966,6 +5966,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) { @@ -6023,6 +6041,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; } |