From 7b65a8599465354462ec420f9124a3e4b0aa03dc Mon Sep 17 00:00:00 2001
From: Raghavendra G <rgowdapp@redhat.com>
Date: Wed, 11 May 2016 17:49:10 +0530
Subject: [PATCH 157/158] 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: I1bda157baabe58431b7f6f6fffee0abfe5225342
BUG: 1325760
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/74412
---
xlators/cluster/dht/src/dht-common.c | 2 +-
xlators/cluster/dht/src/dht-selfheal.c | 67 +++++++++++++++++++++++++++-----
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 e9fcf47..10d47de 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -1605,7 +1605,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 a70b3f7..83bbd0a 100644
--- a/xlators/cluster/dht/src/dht-selfheal.c
+++ b/xlators/cluster/dht/src/dht-selfheal.c
@@ -1957,23 +1957,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;
@@ -2011,17 +2038,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,
--
1.7.1