diff options
-rw-r--r-- | tests/bugs/posix/bug-1360679.t | 36 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 70 |
2 files changed, 95 insertions, 11 deletions
diff --git a/tests/bugs/posix/bug-1360679.t b/tests/bugs/posix/bug-1360679.t new file mode 100644 index 00000000000..fbb9d027ddb --- /dev/null +++ b/tests/bugs/posix/bug-1360679.t @@ -0,0 +1,36 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../fileio.rc + +cleanup +function num_entries { + ls -l $1 | wc -l +} + +function create_unlink_entry { + for i in {0..1} + do + mkdir -p $B0/${V0}$i/.glusterfs/unlink/{1..3}/{1..10}/1 + dd if=/dev/urandom of=$B0/${V0}$i/.glusterfs/unlink/file-1 bs=1M count=1 + dd if=/dev/urandom of=$B0/${V0}$i/.glusterfs/unlink/file-2 bs=1M count=1 + dd if=/dev/urandom of=$B0/${V0}$i/.glusterfs/unlink/1/file-1 bs=1M count=1 + dd if=/dev/urandom of=$B0/${V0}$i/.glusterfs/unlink/2/file-1 bs=1M count=1 + dd if=/dev/urandom of=$B0/${V0}$i/.glusterfs/unlink/3/file-1 bs=1M count=1 + ln $B0/${V0}$i/.glusterfs/unlink/file-1 $B0/${V0}$i/.glusterfs/unlink/file-link + ln -s $B0/${V0}$i/.glusterfs/unlink/1 $B0/${V0}$i/.glusterfs/unlink/link + ln -s $B0/${V0}$i/.glusterfs/unlink/2 $B0/${V0}$i/.glusterfs/unlink/link-2 + done +} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 disperse 6 redundancy 2 $H0:$B0/${V0}{0..5} +TEST $CLI volume start $V0 +TEST $CLI volume stop $V0 +create_unlink_entry +TEST $CLI volume start $V0 +EXPECT_WITHIN $UNLINK_TIMEOUT "^1$" num_entries $B0/${V0}0/.glusterfs/unlink/ +EXPECT_WITHIN $UNLINK_TIMEOUT "^1$" num_entries $B0/${V0}1/.glusterfs/unlink/ +cleanup; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index ab2dcc2905b..ad42d2e1c8f 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -25,6 +25,8 @@ #include <sys/stat.h> #include <signal.h> #include <sys/uio.h> +#include <unistd.h> +#include <ftw.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> @@ -6610,6 +6612,61 @@ out: } int32_t +posix_delete_unlink_entry (const char *fpath, const struct stat *sb, + int typeflag, struct FTW *ftwbuf) { + + int ret = 0; + + if (!fpath) + goto out; + + switch (typeflag) { + case FTW_SL: + case FTW_NS: + case FTW_F: + case FTW_SLN: + ret = sys_unlink(fpath); + break; + case FTW_D: + case FTW_DP: + case FTW_DNR: + if (ftwbuf->level != 0) { + ret = sys_rmdir(fpath); + } + break; + default: + break; + } + if (ret) { + gf_msg ("posix_delete_unlink_entry", GF_LOG_WARNING, errno, + P_MSG_HANDLE_CREATE, + "Deletion of entries %s failed" + "Please delete it manually", + fpath); + } +out: + return 0; +} + +int32_t +posix_delete_unlink (const char *unlink_path) { + + int ret = -1; + int flags = 0; + + flags |= (FTW_DEPTH | FTW_PHYS); + + ret = nftw(unlink_path, posix_delete_unlink_entry, 2, flags); + if (ret) { + gf_msg ("posix_delete_unlink", GF_LOG_ERROR, 0, + P_MSG_HANDLE_CREATE, + "Deleting files from %s failed", + unlink_path); + } + return ret; +} + +int32_t posix_create_unlink_dir (xlator_t *this) { char *unlink_path = NULL; @@ -6655,15 +6712,8 @@ posix_create_unlink_dir (xlator_t *this) { unlink_path); return -1; } - ret = sys_rename (unlink_path, landfill_path); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, errno, - P_MSG_HANDLE_CREATE, - "Can not delete directory %s ", - unlink_path); - return -1; - } - break; + ret = posix_delete_unlink (unlink_path); + return 0; default: break; } @@ -6679,8 +6729,6 @@ posix_create_unlink_dir (xlator_t *this) { return 0; } - - /** * init - */ |