From a0ae826a7413e1ad0a5796201d156d8d915c93ad 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: I8de1e643dbe88c57eb7a946357283f46c30ae701 BUG: 1332397 Signed-off-by: Prashanth Pai Reviewed-on: http://review.gluster.org/14176 Smoke: Gluster Build System Tested-by: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Niels de Vos --- tests/bugs/posix/bug-1175711.c | 37 +++++++++++++++++++++++++++++++++++++ tests/bugs/posix/bug-1175711.t | 30 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/bugs/posix/bug-1175711.c create mode 100755 tests/bugs/posix/bug-1175711.t (limited to 'tests/bugs') 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 +#include +#include +#include + +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; -- cgit