summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/posix/bug-1360679.t36
-rw-r--r--xlators/storage/posix/src/posix.c70
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 -
*/