summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2016-05-11 17:49:10 +0530
committerRaghavendra G <rgowdapp@redhat.com>2016-05-16 09:10:20 -0700
commit06f92634d9ad8aa5c56d786e5248016c283e5c5b (patch)
tree89b7602b70cf6232427aceba1b53a280ac34d43c
parent1a3e4159c8ecda51e0f7bb018e017aa0f9d522b8 (diff)
cluster/distribute: use a linked inode in directory heal codepath
This is needed for following reasons: * healing is done in lookup and mkdir codepath where inode is not linked _yet_ as normally linking is done in interface layers (fuse-bridge, gfapi, nfsv3 etc). * healing consists of non-lookup fops like inodelk, setattr, setxattr etc. All non-lookup fops expect a linked inode. Change-Id: I1bd8157abbae58431b7f6f6fffee0abfe5225342 BUG: 1334164 Signed-off-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-on: http://review.gluster.org/14295 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Smoke: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Susant Palai <spalai@redhat.com> Reviewed-by: mohammed rafi kc <rkavunga@redhat.com>
-rw-r--r--xlators/cluster/dht/src/dht-common.c2
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c67
2 files changed, 58 insertions, 11 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index e8d7401c474..21962cd342c 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -1600,7 +1600,7 @@ unwind_hashed_and_cached:
DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
dht_set_fixed_dir_stat (&local->postparent);
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->loc.inode, &local->stbuf, local->xattr,
+ local->inode, &local->stbuf, local->xattr,
&local->postparent);
return 0;
}
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
index 3e10ef7e344..16cae5d087d 100644
--- a/xlators/cluster/dht/src/dht-selfheal.c
+++ b/xlators/cluster/dht/src/dht-selfheal.c
@@ -1952,23 +1952,50 @@ dht_selfheal_new_directory (call_frame_t *frame,
dht_selfheal_dir_cbk_t dir_cbk,
dht_layout_t *layout)
{
- dht_local_t *local = NULL;
- int ret = 0;
+ dht_local_t *local = NULL;
+ int ret = 0;
+ inode_t *linked_inode = NULL, *inode = NULL;
+ loc_t *loc = NULL;
+ char pgfid[GF_UUID_BUF_SIZE] = {0};
+ char gfid[GF_UUID_BUF_SIZE] = {0};
+ int32_t op_errno = EIO;
local = frame->local;
+ loc = &local->loc;
+
+ gf_uuid_unparse(local->stbuf.ia_gfid, gfid);
+ gf_uuid_unparse(loc->parent->gfid, pgfid);
+
+ linked_inode = inode_link (loc->inode, loc->parent, loc->name,
+ &local->stbuf);
+ if (!linked_inode) {
+ gf_msg (frame->this->name, GF_LOG_WARNING, 0,
+ DHT_MSG_DIR_SELFHEAL_FAILED,
+ "linking inode failed (%s/%s) => %s",
+ pgfid, loc->name, gfid);
+ ret = -1;
+ goto out;
+ }
+
+ inode = loc->inode;
+ loc->inode = linked_inode;
+ inode_unref (inode);
+
local->selfheal.dir_cbk = dir_cbk;
local->selfheal.layout = dht_layout_ref (frame->this, layout);
dht_layout_sort_volname (layout);
dht_selfheal_layout_new_directory (frame, &local->loc, layout);
+ op_errno = ENOMEM;
ret = dht_selfheal_layout_lock (frame, layout, _gf_true,
dht_selfheal_dir_xattr,
dht_should_heal_layout);
+out:
if (ret < 0) {
- dir_cbk (frame, NULL, frame->this, -1, ENOMEM, NULL);
+ dir_cbk (frame, NULL, frame->this, -1, op_errno, NULL);
}
return 0;
@@ -2006,17 +2033,37 @@ int
dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
loc_t *loc, dht_layout_t *layout)
{
- dht_local_t *local = NULL;
- uint32_t down = 0;
- uint32_t misc = 0;
- int ret = 0;
- xlator_t *this = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
+ dht_local_t *local = NULL;
+ uint32_t down = 0;
+ uint32_t misc = 0;
+ int ret = 0;
+ xlator_t *this = NULL;
+ char pgfid[GF_UUID_BUF_SIZE] = {0};
+ char gfid[GF_UUID_BUF_SIZE] = {0};
+ inode_t *linked_inode = NULL, *inode = NULL;
local = frame->local;
this = frame->this;
- gf_uuid_unparse(loc->gfid, gfid);
+ if (!__is_root_gfid (local->stbuf.ia_gfid)) {
+ gf_uuid_unparse(local->stbuf.ia_gfid, gfid);
+ gf_uuid_unparse(loc->parent->gfid, pgfid);
+
+ linked_inode = inode_link (loc->inode, loc->parent, loc->name,
+ &local->stbuf);
+ if (!linked_inode) {
+ gf_msg (this->name, GF_LOG_WARNING, 0,
+ DHT_MSG_DIR_SELFHEAL_FAILED,
+ "linking inode failed (%s/%s) => %s",
+ pgfid, loc->name, gfid);
+ ret = 0;
+ goto sorry_no_fix;
+ }
+
+ inode = loc->inode;
+ loc->inode = linked_inode;
+ inode_unref (inode);
+ }
dht_layout_anomalies (this, loc, layout,
&local->selfheal.hole_cnt,