|
|
12a457 |
From 98b9c42e563651d9ed5d125e275e3616a7009587 Mon Sep 17 00:00:00 2001
|
|
|
12a457 |
From: N Balachandran <nbalacha@redhat.com>
|
|
|
12a457 |
Date: Tue, 3 May 2016 11:00:07 +0530
|
|
|
12a457 |
Subject: [PATCH 109/139] cluster/dht: Handle rmdir failure correctly
|
|
|
12a457 |
|
|
|
12a457 |
DHT did not handle rmdir failures on non-hashed subvols
|
|
|
12a457 |
correctly in a 2x2 dist-rep volume, causing the
|
|
|
12a457 |
directory do be deleted from the hashed subvol.
|
|
|
12a457 |
Also fixed an issue where the dht_selfheal_restore
|
|
|
12a457 |
errcodes were overwriting the rmdir error codes
|
|
|
12a457 |
|
|
|
12a457 |
Upstream:
|
|
|
12a457 |
master : http://review.gluster.org/#/c/14060/
|
|
|
12a457 |
release-3.7 : http://review.gluster.org/14123
|
|
|
12a457 |
|
|
|
12a457 |
Change-Id: I51f1bfbb93f5c38fe6cfaf62975acd9d8dfa0ce9
|
|
|
12a457 |
BUG: 1329514
|
|
|
12a457 |
Signed-off-by: N Balachandran <nbalacha@redhat.com>
|
|
|
12a457 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/73469
|
|
|
12a457 |
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
|
|
|
12a457 |
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
|
|
|
12a457 |
---
|
|
|
12a457 |
xlators/cluster/dht/src/dht-common.c | 113 ++++++++++++++++++++++++++++----
|
|
|
12a457 |
xlators/cluster/dht/src/dht-selfheal.c | 11 +++-
|
|
|
12a457 |
2 files changed, 110 insertions(+), 14 deletions(-)
|
|
|
12a457 |
|
|
|
12a457 |
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
|
|
|
12a457 |
index b3f3774..c5bb9b7 100644
|
|
|
12a457 |
--- a/xlators/cluster/dht/src/dht-common.c
|
|
|
12a457 |
+++ b/xlators/cluster/dht/src/dht-common.c
|
|
|
12a457 |
@@ -7423,17 +7423,23 @@ err:
|
|
|
12a457 |
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-dht_rmdir_selfheal_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
12a457 |
+dht_rmdir_selfheal_cbk (call_frame_t *heal_frame, void *cookie, xlator_t *this,
|
|
|
12a457 |
int op_ret, int op_errno, dict_t *xdata)
|
|
|
12a457 |
{
|
|
|
12a457 |
- dht_local_t *local = NULL;
|
|
|
12a457 |
+ dht_local_t *local = NULL;
|
|
|
12a457 |
+ dht_local_t *heal_local = NULL;
|
|
|
12a457 |
+ call_frame_t *main_frame = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
- local = frame->local;
|
|
|
12a457 |
+ heal_local = heal_frame->local;
|
|
|
12a457 |
+ main_frame = heal_local->main_frame;
|
|
|
12a457 |
+ local = main_frame->local;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ DHT_STACK_DESTROY (heal_frame);
|
|
|
12a457 |
|
|
|
12a457 |
dht_set_fixed_dir_stat (&local->preparent);
|
|
|
12a457 |
dht_set_fixed_dir_stat (&local->postparent);
|
|
|
12a457 |
|
|
|
12a457 |
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
|
|
|
12a457 |
+ DHT_STACK_UNWIND (rmdir, main_frame, local->op_ret, local->op_errno,
|
|
|
12a457 |
&local->preparent, &local->postparent, NULL);
|
|
|
12a457 |
|
|
|
12a457 |
return 0;
|
|
|
12a457 |
@@ -7446,6 +7452,8 @@ dht_rmdir_hashed_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
12a457 |
struct iatt *postparent, dict_t *xdata)
|
|
|
12a457 |
{
|
|
|
12a457 |
dht_local_t *local = NULL;
|
|
|
12a457 |
+ dht_local_t *heal_local = NULL;
|
|
|
12a457 |
+ call_frame_t *heal_frame = NULL;
|
|
|
12a457 |
dht_conf_t *conf = NULL;
|
|
|
12a457 |
int this_call_cnt = 0;
|
|
|
12a457 |
call_frame_t *prev = NULL;
|
|
|
12a457 |
@@ -7496,8 +7504,33 @@ unlock:
|
|
|
12a457 |
local->stbuf.ia_type = local->loc.inode->ia_type;
|
|
|
12a457 |
|
|
|
12a457 |
gf_uuid_copy (local->gfid, local->loc.inode->gfid);
|
|
|
12a457 |
- dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
|
|
|
12a457 |
- &local->loc, local->layout);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* Use a different frame or else the rmdir op_ret is
|
|
|
12a457 |
+ * overwritten by that of the selfheal */
|
|
|
12a457 |
+
|
|
|
12a457 |
+ heal_frame = copy_frame (frame);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (heal_frame == NULL) {
|
|
|
12a457 |
+ goto err;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ heal_local = dht_local_init (heal_frame,
|
|
|
12a457 |
+ &local->loc,
|
|
|
12a457 |
+ NULL, 0);
|
|
|
12a457 |
+ if (!heal_local) {
|
|
|
12a457 |
+ DHT_STACK_DESTROY (heal_frame);
|
|
|
12a457 |
+ goto err;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ heal_local->inode = inode_ref (local->loc.inode);
|
|
|
12a457 |
+ heal_local->main_frame = frame;
|
|
|
12a457 |
+ gf_uuid_copy (heal_local->gfid, local->loc.inode->gfid);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ dht_selfheal_restore (heal_frame,
|
|
|
12a457 |
+ dht_rmdir_selfheal_cbk,
|
|
|
12a457 |
+ &heal_local->loc,
|
|
|
12a457 |
+ heal_local->layout);
|
|
|
12a457 |
+ return 0;
|
|
|
12a457 |
} else {
|
|
|
12a457 |
|
|
|
12a457 |
if (local->loc.parent) {
|
|
|
12a457 |
@@ -7523,6 +7556,12 @@ unlock:
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
return 0;
|
|
|
12a457 |
+
|
|
|
12a457 |
+err:
|
|
|
12a457 |
+ DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
|
|
|
12a457 |
+ local->op_errno, NULL, NULL, NULL);
|
|
|
12a457 |
+ return 0;
|
|
|
12a457 |
+
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
|
|
|
12a457 |
@@ -7536,6 +7575,9 @@ dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
12a457 |
call_frame_t *prev = NULL;
|
|
|
12a457 |
int done = 0;
|
|
|
12a457 |
char gfid[GF_UUID_BUF_SIZE] ={0};
|
|
|
12a457 |
+ dht_local_t *heal_local = NULL;
|
|
|
12a457 |
+ call_frame_t *heal_frame = NULL;
|
|
|
12a457 |
+ int ret = -1;
|
|
|
12a457 |
|
|
|
12a457 |
local = frame->local;
|
|
|
12a457 |
prev = cookie;
|
|
|
12a457 |
@@ -7592,16 +7634,56 @@ unlock:
|
|
|
12a457 |
local->stbuf.ia_type = local->loc.inode->ia_type;
|
|
|
12a457 |
|
|
|
12a457 |
gf_uuid_copy (local->gfid, local->loc.inode->gfid);
|
|
|
12a457 |
- dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
|
|
|
12a457 |
- &local->loc, local->layout);
|
|
|
12a457 |
+ heal_frame = copy_frame (frame);
|
|
|
12a457 |
+ if (heal_frame == NULL) {
|
|
|
12a457 |
+ goto err;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ heal_local = dht_local_init (heal_frame, &local->loc,
|
|
|
12a457 |
+ NULL, 0);
|
|
|
12a457 |
+ if (!heal_local) {
|
|
|
12a457 |
+ DHT_STACK_DESTROY (heal_frame);
|
|
|
12a457 |
+ goto err;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ heal_local->inode = inode_ref (local->loc.inode);
|
|
|
12a457 |
+ heal_local->main_frame = frame;
|
|
|
12a457 |
+ gf_uuid_copy (heal_local->gfid, local->loc.inode->gfid);
|
|
|
12a457 |
+ ret = dht_selfheal_restore (heal_frame,
|
|
|
12a457 |
+ dht_rmdir_selfheal_cbk,
|
|
|
12a457 |
+ &heal_local->loc,
|
|
|
12a457 |
+ heal_local->layout);
|
|
|
12a457 |
+ if (ret) {
|
|
|
12a457 |
+ DHT_STACK_DESTROY (heal_frame);
|
|
|
12a457 |
+ goto err;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
} else if (this_call_cnt) {
|
|
|
12a457 |
/* If non-hashed subvol's have responded, proceed */
|
|
|
12a457 |
+ if (local->op_ret == 0) {
|
|
|
12a457 |
+ /* Delete the dir from the hashed subvol if:
|
|
|
12a457 |
+ * The fop succeeded on at least one subvol
|
|
|
12a457 |
+ * and did not fail on any
|
|
|
12a457 |
+ * or
|
|
|
12a457 |
+ * The fop failed with ENOENT/ESTALE on
|
|
|
12a457 |
+ * all subvols */
|
|
|
12a457 |
+
|
|
|
12a457 |
+ STACK_WIND (frame, dht_rmdir_hashed_subvol_cbk,
|
|
|
12a457 |
+ local->hashed_subvol,
|
|
|
12a457 |
+ local->hashed_subvol->fops->rmdir,
|
|
|
12a457 |
+ &local->loc, local->flags, NULL);
|
|
|
12a457 |
+ } else {
|
|
|
12a457 |
+ /* hashed-subvol was non-NULL and rmdir failed on
|
|
|
12a457 |
+ * all non hashed-subvols. Unwind rmdir with
|
|
|
12a457 |
+ * local->op_ret and local->op_errno. */
|
|
|
12a457 |
+ dht_rmdir_unlock (frame, this);
|
|
|
12a457 |
+ DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
|
|
|
12a457 |
+ local->op_errno, &local->preparent,
|
|
|
12a457 |
+ &local->postparent, NULL);
|
|
|
12a457 |
|
|
|
12a457 |
- local->need_selfheal = 0;
|
|
|
12a457 |
- STACK_WIND (frame, dht_rmdir_hashed_subvol_cbk,
|
|
|
12a457 |
- local->hashed_subvol,
|
|
|
12a457 |
- local->hashed_subvol->fops->rmdir,
|
|
|
12a457 |
- &local->loc, local->flags, NULL);
|
|
|
12a457 |
+ return 0;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ }
|
|
|
12a457 |
} else if (!this_call_cnt) {
|
|
|
12a457 |
/* All subvol's have responded, proceed */
|
|
|
12a457 |
|
|
|
12a457 |
@@ -7630,6 +7712,11 @@ unlock:
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
return 0;
|
|
|
12a457 |
+
|
|
|
12a457 |
+err:
|
|
|
12a457 |
+ DHT_STACK_UNWIND (rmdir, frame, -1, local->op_errno, NULL, NULL, NULL);
|
|
|
12a457 |
+ return 0;
|
|
|
12a457 |
+
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
|
|
|
12a457 |
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
12a457 |
index 307116a..a70b3f7 100644
|
|
|
12a457 |
--- a/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
12a457 |
+++ b/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
12a457 |
@@ -1314,20 +1314,29 @@ dht_selfheal_dir_mkdir_lookup_cbk (call_frame_t *frame, void *cookie,
|
|
|
12a457 |
int missing_dirs = 0;
|
|
|
12a457 |
dht_layout_t *layout = NULL;
|
|
|
12a457 |
loc_t *loc = NULL;
|
|
|
12a457 |
+ call_frame_t *prev = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
VALIDATE_OR_GOTO (this->private, err);
|
|
|
12a457 |
|
|
|
12a457 |
local = frame->local;
|
|
|
12a457 |
layout = local->layout;
|
|
|
12a457 |
loc = &local->loc;
|
|
|
12a457 |
+ prev = cookie;
|
|
|
12a457 |
|
|
|
12a457 |
this_call_cnt = dht_frame_return (frame);
|
|
|
12a457 |
|
|
|
12a457 |
LOCK (&frame->lock);
|
|
|
12a457 |
{
|
|
|
12a457 |
- if ((op_ret < 0) && (op_errno == ENOENT || op_errno == ESTALE))
|
|
|
12a457 |
+ if ((op_ret < 0) &&
|
|
|
12a457 |
+ (op_errno == ENOENT || op_errno == ESTALE)) {
|
|
|
12a457 |
local->selfheal.hole_cnt = !local->selfheal.hole_cnt ? 1
|
|
|
12a457 |
: local->selfheal.hole_cnt + 1;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (!op_ret) {
|
|
|
12a457 |
+ dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
}
|
|
|
12a457 |
UNLOCK (&frame->lock);
|
|
|
12a457 |
|
|
|
12a457 |
--
|
|
|
12a457 |
1.7.1
|
|
|
12a457 |
|