summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2011-09-27 14:44:01 +0530
committerVijay Bellur <vijay@gluster.com>2011-09-29 04:14:43 -0700
commitfb648cf39c8715e5a25752defdfc95ec0ba04217 (patch)
tree20fe412c9a9b20b4ab2fca157a735cf453acea53 /xlators
parent09cfa5dffa79abd833354a26783db9edcfb69105 (diff)
cluster/afr: Handle files without gfid in self-heal
Change-Id: Ibcaaa9c928195939ff1e31b28b592e524e63a423 BUG: 3557 Reviewed-on: http://review.gluster.com/519 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/cluster/afr/src/afr-common.c5
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c464
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.h19
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c546
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c49
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c169
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.h4
-rw-r--r--xlators/cluster/afr/src/afr.h8
-rw-r--r--xlators/cluster/afr/src/pump.c32
9 files changed, 642 insertions, 654 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index c23e329dfcb..0131feaa075 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -723,6 +723,7 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
GF_FREE (sh->fresh_parent_dirs);
loc_wipe (&sh->parent_loc);
+ loc_wipe (&sh->lookup_loc);
if (sh->checksum)
GF_FREE (sh->checksum);
@@ -1235,12 +1236,12 @@ afr_launch_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode,
afr_self_heal (frame, this, inode);
}
-int
+unsigned int
afr_gfid_missing_count (const char *xlator_name, int32_t *success_children,
struct iatt *bufs, unsigned int child_count,
const char *path)
{
- int gfid_miss_count = 0;
+ unsigned int gfid_miss_count = 0;
int i = 0;
struct iatt *child1 = NULL;
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 8f50c625136..d1456d936bf 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -993,6 +993,37 @@ afr_sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
return 0;
}
+int
+afr_sh_common_create (afr_self_heal_t *sh, unsigned int child_count)
+{
+ int ret = -ENOMEM;
+ sh->buf = GF_CALLOC (child_count, sizeof (*sh->buf),
+ gf_afr_mt_iatt);
+ if (!sh->buf)
+ goto out;
+ sh->parentbufs = GF_CALLOC (child_count, sizeof (*sh->parentbufs),
+ gf_afr_mt_iatt);
+ if (!sh->parentbufs)
+ goto out;
+ sh->child_errno = GF_CALLOC (child_count, sizeof (*sh->child_errno),
+ gf_afr_mt_int);
+ if (!sh->child_errno)
+ goto out;
+ sh->success_children = afr_children_create (child_count);
+ if (!sh->success_children)
+ goto out;
+ sh->fresh_children = afr_children_create (child_count);
+ if (!sh->fresh_children)
+ goto out;
+ sh->xattr = GF_CALLOC (child_count, sizeof (*sh->xattr),
+ gf_afr_mt_dict_t);
+ if (!sh->xattr)
+ goto out;
+ ret = 0;
+out:
+ return ret;
+}
+
void
afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,
xlator_t *this,
@@ -1049,6 +1080,56 @@ afr_valid_ia_type (ia_type_t ia_type)
return _gf_false;
}
+int
+afr_impunge_frame_create (call_frame_t *frame, xlator_t *this,
+ int active_source, int ret_child, mode_t entry_mode,
+ call_frame_t **impunge_frame)
+{
+ afr_local_t *local = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ int ret = 0;
+ call_frame_t *new_frame = NULL;
+
+ op_errno = ENOMEM;
+ priv = this->private;
+ new_frame = copy_frame (frame);
+ if (!new_frame) {
+ goto out;
+ }
+
+ ALLOC_OR_GOTO (impunge_local, afr_local_t, out);
+
+ local = frame->local;
+ sh = &local->self_heal;
+ new_frame->local = impunge_local;
+ impunge_sh = &impunge_local->self_heal;
+ impunge_sh->sh_frame = frame;
+ impunge_sh->active_source = active_source;
+ impunge_sh->impunge_ret_child = ret_child;
+ impunge_sh->impunging_entry_mode = entry_mode;
+ impunge_local->child_up = memdup (local->child_up,
+ sizeof (*local->child_up) *
+ priv->child_count);
+ if (!impunge_local->child_up)
+ goto out;
+
+ ret = afr_sh_common_create (impunge_sh, priv->child_count);
+ if (ret) {
+ op_errno = -ret;
+ goto out;
+ }
+ op_errno = 0;
+ *impunge_frame = new_frame;
+out:
+ if (op_errno && new_frame)
+ AFR_STACK_DESTROY (new_frame);
+ return -op_errno;
+}
+
void
afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,
int child_index, struct iatt *buf,
@@ -1059,26 +1140,17 @@ afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,
afr_local_t *local = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *sh = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- int32_t op_errno = 0;
-
- impunge_frame = copy_frame (frame);
- if (!impunge_frame) {
- op_errno = ENOMEM;
- goto out;
- }
-
- ALLOC_OR_GOTO (impunge_local, afr_local_t, out);
+ int ret = 0;
+ mode_t mode = 0;
local = frame->local;
- sh = &local->self_heal;
- impunge_frame->local = impunge_local;
- impunge_sh = &impunge_local->self_heal;
- impunge_sh->sh_frame = frame;
- impunge_sh->active_source = sh->source;
- impunge_sh->impunging_entry_mode = st_mode_from_ia (buf->ia_prot,
- buf->ia_type);
- impunge_sh->impunge_ret_child = child_index;
+ sh = &local->self_heal;
+ mode = st_mode_from_ia (buf->ia_prot, buf->ia_type);
+ ret = afr_impunge_frame_create (frame, this, sh->source, child_index,
+ mode, &impunge_frame);
+ if (ret)
+ goto out;
+ impunge_local = impunge_frame->local;
loc_copy (&impunge_local->loc, &local->loc);
sh->impunge_done = impunge_done;
impunge_local->call_count = 1;
@@ -1087,8 +1159,8 @@ afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,
return;
out:
gf_log (this->name, GF_LOG_ERROR, "impunge of %s failed, reason: %s",
- local->loc.path, strerror (op_errno));
- impunge_done (frame, this, child_index, -1, op_errno);
+ local->loc.path, strerror (-ret));
+ impunge_done (frame, this, child_index, -1, -ret);
}
int
@@ -1165,12 +1237,12 @@ out:
}
void
-afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this)
+afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- int32_t op_errno = 0;
ia_type_t ia_type = IA_INVAL;
int32_t nsources = 0;
@@ -1178,23 +1250,10 @@ afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this)
sh = &local->self_heal;
priv = this->private;
- if (afr_get_children_count (sh->success_children,
- priv->child_count) == 0) {
- op_errno = afr_resultant_errno_get (NULL, sh->child_errno,
- priv->child_count);
- goto out;
- }
-
- if (afr_gfid_missing_count (this->name, sh->success_children,
- sh->buf, priv->child_count,
- local->loc.path) ||
- afr_conflicting_iattrs (sh->buf, sh->success_children,
- priv->child_count, local->loc.path,
- this->name)) {
- //this can happen if finding the fresh parent dir failed
- local->govinda_gOvinda = 1;
- sh->op_failed = 1;
- op_errno = EIO;
+ if (op_ret < 0) {
+ if (op_errno == EIO)
+ local->govinda_gOvinda = 1;
+ // EIO can happen if finding the fresh parent dir failed
goto out;
}
@@ -1227,31 +1286,68 @@ afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this)
sh_missing_entries_create (frame, this);
return;
out:
+ sh->op_failed = 1;
afr_sh_set_error (sh, op_errno);
afr_sh_missing_entries_finish (frame, this);
return;
}
static int
-afr_sh_missing_entries_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+afr_sh_common_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
int call_count = 0;
afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
op_errno, inode, buf, xattr,
- postparent, &local->loc);
+ postparent, &sh->lookup_loc);
call_count = afr_frame_return (frame);
- if (call_count == 0)
- afr_sh_missing_entries_lookup_done (frame, this);
+ if (call_count)
+ goto out;
+ op_ret = -1;
+ if (!sh->success_count) {
+ op_errno = afr_resultant_errno_get (NULL, sh->child_errno,
+ priv->child_count);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to lookup %s, "
+ "reason %s", sh->lookup_loc.path,
+ strerror (op_errno));
+ goto done;
+ }
+ if ((sh->lookup_flags & AFR_LOOKUP_FAIL_CONFLICTS) &&
+ (afr_conflicting_iattrs (sh->buf, sh->success_children,
+ priv->child_count,
+ sh->lookup_loc.path, this->name))) {
+ op_errno = EIO;
+ gf_log (this->name, GF_LOG_ERROR, "Conflicting entries "
+ "for %s", sh->lookup_loc.path);
+ goto done;
+ }
+
+ if ((sh->lookup_flags & AFR_LOOKUP_FAIL_MISSING_GFIDS) &&
+ (afr_gfid_missing_count (this->name, sh->success_children,
+ sh->buf, priv->child_count,
+ sh->lookup_loc.path))) {
+ op_errno = ENODATA;
+ gf_log (this->name, GF_LOG_ERROR, "Missing Gfids "
+ "for %s", sh->lookup_loc.path);
+ goto done;
+ }
+ op_ret = 0;
+
+done:
+ sh->lookup_done (frame, this, op_ret, op_errno);
+out:
return 0;
}
@@ -1354,8 +1450,10 @@ afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)
sh->buf, priv->child_count,
local->loc.path)) {
afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_missing_entries_lookup_cbk,
- _gf_true);
+ afr_sh_missing_entries_lookup_done,
+ sh->sh_gfid_req,
+ AFR_LOOKUP_FAIL_CONFLICTS|
+ AFR_LOOKUP_FAIL_MISSING_GFIDS);
} else {
//No need to set gfid so goto missing entries lookup done
//Behave as if you have done the lookup
@@ -1366,7 +1464,7 @@ afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)
afr_children_copy (sh->success_children,
sh->fresh_children,
priv->child_count);
- afr_sh_missing_entries_lookup_done (frame, this);
+ afr_sh_missing_entries_lookup_done (frame, this, 0, 0);
}
}
return 0;
@@ -1521,35 +1619,34 @@ afr_sh_save_child_iatts_from_policy (int32_t *children, struct iatt *bufs,
}
void
-afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this)
+afr_get_children_of_fresh_parent_dirs (afr_self_heal_t *sh,
+ unsigned int child_count)
+{
+ afr_children_intersection_get (sh->success_children,
+ sh->fresh_parent_dirs,
+ sh->sources, child_count);
+ afr_get_fresh_children (sh->success_children, sh->sources,
+ sh->fresh_children, child_count);
+ memset (sh->sources, 0, sizeof (*sh->sources) * child_count);
+}
+
+void
+afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
int32_t fresh_child_enoents = 0;
int32_t fresh_parent_count = 0;
- int32_t op_errno = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- if (afr_get_children_count (sh->success_children,
- priv->child_count) == 0) {
- op_errno = afr_resultant_errno_get (NULL, sh->child_errno,
- priv->child_count);
+ if (op_ret < 0)
goto fail;
- }
-
- //make intersection of (success_children & fresh_parent_dirs) fresh_children
- //the other success_children will be added to it if they are not stale
- afr_children_intersection_get (sh->success_children,
- sh->fresh_parent_dirs,
- sh->sources, priv->child_count);
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, priv->child_count);
- memset (sh->sources, 0, sizeof (*sh->sources) * priv->child_count);
-
+ afr_get_children_of_fresh_parent_dirs (sh, priv->child_count);
fresh_parent_count = afr_get_children_count (sh->fresh_parent_dirs,
priv->child_count);
//we need the enoent count of the subvols present in fresh_parent_dirs
@@ -1581,35 +1678,15 @@ afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this)
return;
fail:
+ sh->op_failed = 1;
afr_sh_set_error (sh, op_errno);
afr_sh_missing_entries_finish (frame, this);
return;
}
-static int
-afr_sh_children_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- int call_count = 0;
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent, &local->loc);
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_sh_children_lookup_done (frame, this);
-
- return 0;
-}
-
-static int
-afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
+static void
+afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
@@ -1632,28 +1709,14 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
* create so fail with EIO,
* If there are conflicting xattr fail with EIO.
*/
- if (afr_get_children_count (sh->success_children,
- priv->child_count) == 0) {
- gf_log (this->name, GF_LOG_ERROR, "Parent dir lookup failed "
- "for %s, in missing entry self-heal, continuing with "
- "the rest of the self-heals", local->loc.path);
+ if (op_ret < 0)
goto out;
- }
-
enoent_count = afr_errno_count (NULL, sh->child_errno,
priv->child_count, ENOENT);
if (enoent_count > 0) {
- gf_log (this->name, GF_LOG_INFO, "Parent dir missing for %s,"
- " in missing entry self-heal, continuing with the rest"
- " of the self-heals", local->loc.path);
- goto out;
- }
-
- if (afr_conflicting_iattrs (sh->buf, sh->success_children,
- priv->child_count, sh->parent_loc.path,
- this->name)) {
- gf_log (this->name, GF_LOG_INFO, "conflicting stat info for "
- "parent dirs of %s", local->loc.path);
+ gf_log (this->name, GF_LOG_ERROR, "Parent dir missing for %s,"
+ " in missing entry self-heal, aborting self-heal",
+ local->loc.path);
goto out;
}
@@ -1662,9 +1725,9 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
sh->success_children,
AFR_ENTRY_TRANSACTION);
if (nsources < 0) {
- gf_log (this->name, GF_LOG_INFO, "No sources for dir of %s,"
- " in missing entry self-heal, continuing with the rest"
- " of the self-heals", local->loc.path);
+ gf_log (this->name, GF_LOG_ERROR, "No sources for dir of %s,"
+ " in missing entry self-heal, aborting self-heal",
+ local->loc.path);
goto out;
}
@@ -1677,39 +1740,14 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
afr_get_fresh_children (sh->success_children, sh->sources,
sh->fresh_parent_dirs, priv->child_count);
afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_children_lookup_cbk, _gf_false);
- return 0;
+ afr_sh_children_lookup_done, NULL, 0);
+ return;
out:
afr_sh_set_error (sh, EIO);
sh->op_failed = 1;
afr_sh_missing_entries_finish (frame, this);
- return 0;
-}
-
-int
-afr_sh_conflicting_entry_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent)
-{
- int call_count = 0;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
-
- afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent, &sh->parent_loc);
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_sh_find_fresh_parents (frame, this);
-
- return 0;
+ return;
}
void
@@ -1727,6 +1765,7 @@ afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)
afr_reset_children (sh->success_children, child_count);
afr_reset_children (sh->fresh_children, child_count);
afr_reset_xattr (sh->xattr, child_count);
+ loc_wipe (&sh->lookup_loc);
}
/* afr self-heal state will be lost if this call is made
@@ -1734,7 +1773,8 @@ afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)
*/
int
afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- afr_lookup_cbk_t lookup_cbk, gf_boolean_t set_gfid)
+ afr_lookup_done_cbk_t lookup_done , uuid_t gfid,
+ int32_t flags)
{
afr_local_t *local = NULL;
int i = 0;
@@ -1755,16 +1795,19 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (xattr_req) {
afr_xattr_req_prepare (this, xattr_req, loc->path);
- if (set_gfid) {
+ if (gfid) {
gf_log (this->name, GF_LOG_DEBUG,
"looking up %s with gfid: %s",
- loc->path, uuid_utoa (sh->sh_gfid_req));
- GF_ASSERT (!uuid_is_null (sh->sh_gfid_req));
- afr_set_dict_gfid (xattr_req, sh->sh_gfid_req);
+ loc->path, uuid_utoa (gfid));
+ GF_ASSERT (!uuid_is_null (gfid));
+ afr_set_dict_gfid (xattr_req, gfid);
}
}
afr_sh_common_reset (sh, priv->child_count);
+ sh->lookup_done = lookup_done;
+ loc_copy (&sh->lookup_loc, loc);
+ sh->lookup_flags = flags;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -1772,7 +1815,7 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
loc->path, priv->children[i]->name);
STACK_WIND_COOKIE (frame,
- lookup_cbk,
+ afr_sh_common_lookup_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->lookup,
@@ -1811,8 +1854,8 @@ afr_sh_post_nb_entrylk_conflicting_sh_cbk (call_frame_t *frame, xlator_t *this)
gf_log (this->name, GF_LOG_DEBUG,
"Non blocking entrylks done. Proceeding to FOP");
afr_sh_common_lookup (frame, this, &sh->parent_loc,
- afr_sh_conflicting_entry_lookup_cbk,
- _gf_false);
+ afr_sh_find_fresh_parents,
+ NULL, AFR_LOOKUP_FAIL_CONFLICTS);
}
return 0;
@@ -1823,8 +1866,10 @@ afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
local = frame->local;
+ sh = &local->self_heal;
int_lock = &local->internal_lock;
if (int_lock->lock_op_ret < 0) {
@@ -1835,8 +1880,9 @@ afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)
gf_log (this->name, GF_LOG_DEBUG,
"Non blocking entrylks done. Proceeding to FOP");
afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_missing_entries_lookup_cbk,
- _gf_true);
+ afr_sh_missing_entries_lookup_done,
+ sh->sh_gfid_req, AFR_LOOKUP_FAIL_CONFLICTS|
+ AFR_LOOKUP_FAIL_MISSING_GFIDS);
}
return 0;
@@ -2038,30 +2084,19 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
int i = 0;
+ int32_t op_errno = 0;
+ int ret = 0;
+ afr_self_heal_t *orig_sh = NULL;
call_frame_t *sh_frame = NULL;
afr_local_t *sh_local = NULL;
local = frame->local;
+ orig_sh = &local->self_heal;
priv = this->private;
GF_ASSERT (local->loc.path);
- if (local->self_heal.background) {
- LOCK (&priv->lock);
- {
- if (priv->background_self_heals_started
- < priv->background_self_heal_count) {
- priv->background_self_heals_started++;
-
-
- } else {
- local->self_heal.background = _gf_false;
- }
- }
- UNLOCK (&priv->lock);
- }
-
gf_log (this->name, GF_LOG_TRACE,
"performing self heal on %s (metadata=%d data=%d entry=%d)",
local->loc.path,
@@ -2069,11 +2104,16 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
local->self_heal.do_data_self_heal,
local->self_heal.do_entry_self_heal);
+ op_errno = ENOMEM;
sh_frame = copy_frame (frame);
+ if (!sh_frame)
+ goto out;
afr_set_lk_owner (sh_frame, this);
afr_set_low_priority (sh_frame);
sh_local = afr_local_copy (local, this);
+ if (!sh_local)
+ goto out;
sh_frame->local = sh_local;
sh = &sh_local->self_heal;
@@ -2083,42 +2123,67 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
sh->completion_cbk = afr_self_heal_completion_cbk;
- sh->buf = GF_CALLOC (priv->child_count, sizeof (struct iatt),
- gf_afr_mt_iatt);
- sh->parentbufs = GF_CALLOC (priv->child_count, sizeof (struct iatt),
- gf_afr_mt_iatt);
- sh->child_errno = GF_CALLOC (priv->child_count, sizeof (int),
- gf_afr_mt_int);
sh->success = GF_CALLOC (priv->child_count, sizeof (*sh->success),
gf_afr_mt_char);
- sh->xattr = GF_CALLOC (priv->child_count, sizeof (dict_t *),
- gf_afr_mt_dict_t);
+ if (!sh->success)
+ goto out;
sh->sources = GF_CALLOC (sizeof (*sh->sources), priv->child_count,
gf_afr_mt_int);
+ if (!sh->sources)
+ goto out;
sh->locked_nodes = GF_CALLOC (sizeof (*sh->locked_nodes),
priv->child_count,
gf_afr_mt_int);
+ if (!sh->locked_nodes)
+ goto out;
sh->pending_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,
gf_afr_mt_int32_t);
+ if (!sh->pending_matrix)
+ goto out;
for (i = 0; i < priv->child_count; i++) {
sh->pending_matrix[i] = GF_CALLOC (sizeof (int32_t),
priv->child_count,
gf_afr_mt_int32_t);
+ if (!sh->pending_matrix[i])
+ goto out;
}
sh->delta_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,
gf_afr_mt_int32_t);
+ if (!sh->delta_matrix)
+ goto out;
for (i = 0; i < priv->child_count; i++) {
sh->delta_matrix[i] = GF_CALLOC (sizeof (int32_t),
priv->child_count,
gf_afr_mt_int32_t);
+ if (!sh->delta_matrix)
+ goto out;
}
- sh->success_children = afr_children_create (priv->child_count);
- sh->fresh_children = afr_children_create (priv->child_count);
sh->fresh_parent_dirs = afr_children_create (priv->child_count);
+ if (!sh->fresh_parent_dirs)
+ goto out;
+ ret = afr_sh_common_create (sh, priv->child_count);
+ if (ret) {
+ op_errno = -ret;
+ goto out;
+ }
+ if (local->self_heal.background) {
+ LOCK (&priv->lock);
+ {
+ if (priv->background_self_heals_started
+ < priv->background_self_heal_count) {
+ priv->background_self_heals_started++;
+
+
+ } else {
+ local->self_heal.background = _gf_false;
+ }
+ }
+ UNLOCK (&priv->lock);
+ }
FRAME_SU_DO (sh_frame, afr_local_t);
if (sh->do_missing_entry_self_heal) {
@@ -2133,7 +2198,12 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
afr_sh_missing_entries_done (sh_frame, this);
}
+ op_errno = 0;
+out:
+ if (op_errno) {
+ orig_sh->unwind (frame, this, -1, op_errno);
+ }
return 0;
}
@@ -2187,3 +2257,47 @@ afr_self_heal_type_for_transaction (afr_transaction_type type)
}
return sh_type;
}
+
+int
+afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
+{
+ int ret = -1;
+
+ if (!child) {
+ goto out;
+ }
+
+ if (strcmp (parent->path, "/") == 0)
+ ret = gf_asprintf ((char **)&child->path, "/%s", name);
+ else
+ ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path,
+ name);
+
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting child path");
+ }
+
+ if (!child->path) {
+ goto out;
+ }
+
+ child->name = strrchr (child->path, '/');
+ if (child->name)
+ child->name++;
+
+ child->parent = inode_ref (parent->inode);
+ child->inode = inode_new (parent->inode->table);
+
+ if (!child->inode) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret == -1)
+ loc_wipe (child);
+
+ return ret;
+}
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.h b/xlators/cluster/afr/src/afr-self-heal-common.h
index 3df5f0a0aa6..bc0dcd78cb8 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.h
+++ b/xlators/cluster/afr/src/afr-self-heal-common.h
@@ -29,11 +29,11 @@ typedef enum {
AFR_SELF_HEAL_INVALID = -1,
} afr_self_heal_type;
-typedef int
-(*afr_lookup_cbk_t) (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent);
+typedef enum {
+ AFR_LOOKUP_FAIL_CONFLICTS = 1,
+ AFR_LOOKUP_FAIL_MISSING_GFIDS = 2,
+} afr_lookup_flags_t;
+
int
afr_sh_select_source (int sources[], int child_count);
@@ -93,7 +93,8 @@ afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,
int
afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- afr_lookup_cbk_t lookup_cbk, gf_boolean_t set_gfid);
+ afr_lookup_done_cbk_t lookup_cbk, uuid_t uuid,
+ int32_t flags);
int
afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
int active_src, struct iatt *buf);
@@ -122,4 +123,10 @@ typedef int
(*afr_fxattrop_cbk_t) (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
dict_t *xattr);
+int
+afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name);
+int
+afr_impunge_frame_create (call_frame_t *frame, xlator_t *this,
+ int active_source, int ret_child, mode_t entry_mode,
+ call_frame_t **impunge_frame);
#endif /* __AFR_SELF_HEAL_COMMON_H__ */
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
index 356b15e635c..af41c480e87 100644
--- a/xlators/cluster/afr/src/afr-self-heal-entry.c
+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c
@@ -49,6 +49,15 @@
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
+#define AFR_INIT_SH_FRAME_VALS(_frame, _local, _sh, _sh_frame, _sh_local, _sh_sh)\
+ do {\
+ _local = _frame->local;\
+ _sh = &_local->self_heal;\
+ _sh_frame = _sh->sh_frame;\
+ _sh_local = _sh_frame->local;\
+ _sh_sh = &_sh_local->self_heal;\
+ } while (0);
+
int
afr_sh_entry_done (call_frame_t *frame, xlator_t *this)
{
@@ -298,51 +307,6 @@ next_active_sink (call_frame_t *frame, xlator_t *this,
return next_active_sink;
}
-
-int
-build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
-{
- int ret = -1;
-
- if (!child) {
- goto out;
- }
-
- if (strcmp (parent->path, "/") == 0)
- ret = gf_asprintf ((char **)&child->path, "/%s", name);
- else
- ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path,
- name);
-
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "asprintf failed while setting child path");
- }
-
- if (!child->path) {
- goto out;
- }
-
- child->name = strrchr (child->path, '/');
- if (child->name)
- child->name++;
-
- child->parent = inode_ref (parent->inode);
- child->inode = inode_new (parent->inode->table);
-
- if (!child->inode) {
- goto out;
- }
-
- ret = 0;
-out:
- if (ret == -1)
- loc_wipe (child);
-
- return ret;
-}
-
-
int
afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this);
@@ -757,7 +721,7 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
expunge_sh->active_source = active_src;
expunge_sh->entrybuf = entry->d_stat;
- ret = build_child_loc (this, &expunge_local->loc, &local->loc, name);
+ ret = afr_build_child_loc (this, &expunge_local->loc, &local->loc, name);
if (ret != 0) {
op_errno = EINVAL;
goto out;
@@ -923,6 +887,27 @@ afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this,
return 0;
}
+void
+afr_sh_entry_call_impunge_done (call_frame_t *impunge_frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ afr_local_t *impunge_local = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ call_frame_t *frame = NULL;
+ int32_t impunge_ret_child = 0;
+ afr_private_t *priv = NULL;
+
+ priv = this->private;
+ AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
+ frame, local, sh);
+
+ impunge_ret_child = impunge_sh->impunge_ret_child;
+ AFR_STACK_DESTROY (impunge_frame);
+ sh->impunge_done (frame, this, impunge_ret_child, op_ret,
+ op_errno);
+}
int
afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,
@@ -933,19 +918,12 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,
int call_count = 0;
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
afr_self_heal_t *impunge_sh = NULL;
- call_frame_t *frame = NULL;
int child_index = 0;
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
child_index = (long) cookie;
if (op_ret == 0) {
@@ -967,12 +945,9 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
- }
+ if (call_count == 0)
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ op_ret, op_errno);
return 0;
}
@@ -1053,7 +1028,6 @@ afr_sh_entry_impunge_parent_setattr_cbk (call_frame_t *setattr_frame,
return 0;
}
-
int
afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
@@ -1066,27 +1040,20 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
- call_frame_t *frame = NULL;
int active_src = 0;
int child_index = 0;
int32_t *pending_array = NULL;
dict_t *xattr = NULL;
int ret = 0;
int idx = 0;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
call_frame_t *setattr_frame = NULL;
int32_t valid = 0;
loc_t *parent_loc = NULL;
struct iatt parentbuf = {0,};
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1172,12 +1139,9 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, -1,
- op_errno);
- }
+ if (call_count == 0)
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ -1, op_errno);
}
return 0;
@@ -1205,6 +1169,7 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,
if (!dict)
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));
ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed",
@@ -1247,6 +1212,7 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this,
return 0;
}
+ GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));
ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed",
@@ -1281,32 +1247,22 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this,
dict_t *dict = NULL;
struct iatt *buf = NULL;
int ret = 0;
- call_frame_t *frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
afr_self_heal_t *impunge_sh = NULL;
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
buf = &impunge_local->cont.symlink.buf;
dict = dict_new ();
if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (impunge_frame, this, impunge_ret_child, -1,
- ENOMEM);
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ -1, ENOMEM);
goto out;
}
+ GF_ASSERT (!uuid_is_null (buf->ia_gfid));
ret = afr_set_dict_gfid (dict, buf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO,
@@ -1342,18 +1298,11 @@ afr_sh_entry_impunge_symlink_unlink_cbk (call_frame_t *impunge_frame,
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
- call_frame_t *frame = NULL;
int call_count = -1;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
child_index = (long) cookie;
@@ -1377,12 +1326,9 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
- }
+ if (call_count == 0)
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ op_ret, op_errno);
return 0;
}
@@ -1423,19 +1369,12 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
- call_frame_t *frame = NULL;
int call_count = -1;
int active_src = -1;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1480,12 +1419,9 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
- }
+ if (call_count == 0)
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ op_ret, op_errno);
return 0;
}
@@ -1525,19 +1461,12 @@ afr_sh_entry_impunge_readlink_cbk (call_frame_t *impunge_frame, void *cookie,
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
- call_frame_t *frame = NULL;
int call_count = -1;
int active_src = -1;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int32_t impunge_ret_child = 0;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1563,12 +1492,9 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
- }
+ if (call_count == 0)
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ op_ret, op_errno);
return 0;
}
@@ -1648,175 +1574,162 @@ afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,
return ret;
}
-int
-afr_sh_entry_impunge_recreate_lookup_cbk (call_frame_t *impunge_frame,
- void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xattr,struct iatt *postparent)
+gf_boolean_t
+afr_sh_need_recreate (afr_self_heal_t *impunge_sh, int *sources,
+ unsigned int child, unsigned int child_count)
{
- afr_private_t *priv = NULL;
- afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- afr_self_heal_t *sh = NULL;
- int active_src = 0;
- int child_index = 0;
- call_frame_t *frame = NULL;
- int call_count = 0;
- int ret = 0;
- int32_t impunge_ret_child = 0;
+ int32_t *success_children = NULL;
+ gf_boolean_t recreate = _gf_false;
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
-
- child_index = (long) cookie;
+ GF_ASSERT (impunge_sh->impunging_entry_mode);
+ GF_ASSERT (impunge_sh->child_errno);
+ GF_ASSERT (sources);
- active_src = impunge_sh->active_source;
-
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "looking up %s on %s (for %s) failed (%s)",
- impunge_local->loc.path,
- priv->children[active_src]->name,
- priv->children[child_index]->name,
- strerror (op_errno));
+ success_children = impunge_sh->success_children;
+ if (sources[child] || (child == impunge_sh->active_source)) {
+ GF_ASSERT (afr_is_child_present (success_children,
+ child_count, child));
goto out;
}
- ret = afr_sh_entry_impunge_create (impunge_frame, this, child_index, buf,
- postparent);
- if (ret)
+ if (IA_ISLNK (impunge_sh->impunging_entry_mode)) {
+ recreate = _gf_true;
goto out;
+ }
- return 0;
-
+ if (impunge_sh->child_errno[child] == ENOENT)
+ recreate = _gf_true;
out:
- LOCK (&impunge_frame->lock);
- {
- call_count = --impunge_local->call_count;
- }
- UNLOCK (&impunge_frame->lock);
+ return recreate;
+}
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
+unsigned int
+afr_sh_recreate_count (afr_self_heal_t *impunge_sh, int *sources,
+ unsigned int child_count)
+{
+ int count = 0;
+ int i = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (afr_sh_need_recreate (impunge_sh, sources, i, child_count))
+ count++;
}
- return 0;
+ return count;
}
-
int
-afr_sh_entry_impunge_recreate (call_frame_t *impunge_frame, xlator_t *this,
- int child_index)
+afr_sh_entry_call_impunge_recreate (call_frame_t *impunge_frame,
+ xlator_t *this)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
+ call_frame_t *frame = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ struct iatt *buf = NULL;
+ struct iatt *postparent = NULL;
+ unsigned int recreate_count = 0;
+ int i = 0;
int active_src = 0;
+ priv = this->private;
+ AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
+ frame, local, sh);
+ active_src = impunge_sh->active_source;
+ buf = &impunge_sh->buf[active_src];
+ postparent = &impunge_sh->parentbufs[active_src];
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
-
- active_src = impunge_sh->active_source;
-
- STACK_WIND_COOKIE (impunge_frame,
- afr_sh_entry_impunge_recreate_lookup_cbk,
- (void *) (long) child_index,
- priv->children[active_src],
- priv->children[active_src]->fops->lookup,
- &impunge_local->loc, 0);
-
+ recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources,
+ priv->child_count);
+ GF_ASSERT (recreate_count);
+ impunge_local->call_count = recreate_count;
+ for (i = 0; i < priv->child_count; i++) {
+ if (afr_sh_need_recreate (impunge_sh, sh->sources, i,
+ priv->child_count)) {
+ (void)afr_sh_entry_impunge_create (impunge_frame, this,
+ i, buf,
+ postparent);
+ recreate_count--;
+ }
+ }
+ GF_ASSERT (!recreate_count);
return 0;
}
-
-int
-afr_sh_entry_impunge_entry_cbk (call_frame_t *impunge_frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *x,
- struct iatt *postparent)
+void
+afr_sh_entry_common_lookup_done (call_frame_t *impunge_frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
- int call_count = 0;
- int child_index = 0;
call_frame_t *frame = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
- int32_t impunge_ret_child = 0;
-
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
- frame = impunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
- child_index = (long) cookie;
-
- if ((op_ret == -1 && op_errno == ENOENT)
- || (IA_ISLNK (impunge_sh->impunging_entry_mode))) {
-
- /*
- * A symlink's target might have changed, so
- * always go down the recreate path for them.
- */
-
- /* decrease call_count in recreate-callback */
-
- gf_log (this->name, GF_LOG_TRACE,
- "missing entry %s on %s",
- impunge_local->loc.path,
- priv->children[child_index]->name);
-
- afr_sh_entry_impunge_recreate (impunge_frame, this,
- child_index);
- return 0;
- }
+ unsigned int recreate_count = 0;
+ unsigned int gfid_miss_count = 0;
+ unsigned int children_up_count = 0;
+ uuid_t gfid = {0};
+ int active_src = 0;
- if (op_ret == 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s exists under %s",
- impunge_local->loc.path,
- priv->children[child_index]->name);
+ priv = this->private;
+ AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
+ frame, local, sh);
+ active_src = impunge_sh->active_source;
- impunge_sh->parentbuf = *postparent;
+ if (op_ret < 0)
+ goto done;
+ if (impunge_sh->child_errno[active_src]) {
+ op_ret = -1;
+ op_errno = impunge_sh->child_errno[active_src];
+ goto done;
+ }
+
+ gfid_miss_count = afr_gfid_missing_count (this->name,
+ impunge_sh->success_children,
+ impunge_sh->buf, priv->child_count,
+ impunge_local->loc.path);
+ children_up_count = afr_up_children_count (impunge_local->child_up,
+ priv->child_count);
+ if ((gfid_miss_count == children_up_count) &&
+ (children_up_count < priv->child_count)) {
+ op_ret = -1;
+ op_errno = ENODATA;
+ gf_log (this->name, GF_LOG_ERROR, "Not all children are up, "
+ "gfid should not be assigned in this state for %s",
+ impunge_local->loc.path);
+ goto done;
+ }
+
+ if (gfid_miss_count) {
+ afr_update_gfid_from_iatts (gfid, impunge_sh->buf,
+ impunge_sh->success_children,
+ priv->child_count);
+ if (uuid_is_null (gfid))
+ uuid_generate (gfid);
+ afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc,
+ afr_sh_entry_common_lookup_done, gfid,
+ AFR_LOOKUP_FAIL_CONFLICTS |
+ AFR_LOOKUP_FAIL_MISSING_GFIDS);
} else {
- gf_log (this->name, GF_LOG_WARNING,
- "looking up %s under %s failed (%s)",
- impunge_local->loc.path,
- priv->children[child_index]->name,
- strerror (op_errno));
- }
-
- LOCK (&impunge_frame->lock);
- {
- call_count = --impunge_local->call_count;
- }
- UNLOCK (&impunge_frame->lock);
-
- if (call_count == 0) {
- impunge_ret_child = impunge_sh->impunge_ret_child;
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, impunge_ret_child, op_ret,
- op_errno);
+ recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources,
+ priv->child_count);
+ if (!recreate_count) {
+ op_ret = 0;
+ op_errno = 0;
+ goto done;
+ }
+ afr_sh_entry_call_impunge_recreate (impunge_frame, this);
}
-
- return 0;
+ return;
+done:
+ afr_sh_entry_call_impunge_done (impunge_frame, this,
+ op_ret, op_errno);
+ return;
}
-
int
afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
gf_dirent_t *entry)
@@ -1827,12 +1740,10 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
int ret = -1;
call_frame_t *impunge_frame = NULL;
afr_local_t *impunge_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
int active_src = 0;
- int i = 0;
- int call_count = 0;
int op_errno = 0;
int op_ret = -1;
+ mode_t entry_mode = 0;
priv = this->private;
local = frame->local;
@@ -1857,70 +1768,34 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
"inspecting existance of %s under %s",
entry->d_name, local->loc.path);
- impunge_frame = copy_frame (frame);
- if (!impunge_frame) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory.");
- op_errno = ENOMEM;
+ entry_mode = st_mode_from_ia (entry->d_stat.ia_prot,
+ entry->d_stat.ia_type);
+ ret = afr_impunge_frame_create (frame, this, active_src, active_src,
+ entry_mode, &impunge_frame);
+ if (ret) {
+ op_errno = -ret;
goto out;
}
- ALLOC_OR_GOTO (impunge_local, afr_local_t, out);
-
- impunge_frame->local = impunge_local;
- impunge_sh = &impunge_local->self_heal;
- impunge_sh->sh_frame = frame;
- impunge_sh->active_source = active_src;
- impunge_sh->impunge_ret_child = active_src;
-
- impunge_sh->impunging_entry_mode =
- st_mode_from_ia (entry->d_stat.ia_prot, entry->d_stat.ia_type);
-
- ret = build_child_loc (this, &impunge_local->loc, &local->loc, entry->d_name);
+ impunge_local = impunge_frame->local;
+ ret = afr_build_child_loc (this, &impunge_local->loc, &local->loc,
+ entry->d_name);
if (ret != 0) {
op_errno = ENOMEM;
goto out;
}
- for (i = 0; i < priv->child_count; i++) {
- if (i == active_src)
- continue;
- if (local->child_up[i] == 0)
- continue;
- if (sh->sources[i] == 1)
- continue;
- call_count++;
- }
-
- impunge_local->call_count = call_count;
-
- for (i = 0; i < priv->child_count; i++) {
- if (i == active_src)
- continue;
- if (local->child_up[i] == 0)
- continue;
- if (sh->sources[i] == 1)
- continue;
-
- gf_log (this->name, GF_LOG_TRACE,
- "looking up %s on %s", impunge_local->loc.path,
- priv->children[i]->name);
-
- STACK_WIND_COOKIE (impunge_frame,
- afr_sh_entry_impunge_entry_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->lookup,
- &impunge_local->loc, 0);
-
- if (!--call_count)
- break;
- }
+ afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc,
+ afr_sh_entry_common_lookup_done, NULL,
+ AFR_LOOKUP_FAIL_CONFLICTS);
- ret = 0;
+ op_ret = 0;
out:
- if (ret == -1)
+ if (ret) {
+ if (impunge_frame)
+ AFR_STACK_DESTROY (impunge_frame);
sh->impunge_done (frame, this, active_src, op_ret, op_errno);
+ }
return 0;
}
@@ -2217,8 +2092,9 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
}
-int
-afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)
+void
+afr_sh_entry_fix (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -2231,6 +2107,13 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)
sh = &local->self_heal;
priv = this->private;
+ if (op_ret < 0) {
+ sh->op_failed = 1;
+ afr_sh_set_error (sh, op_errno);
+ afr_sh_entry_finish (frame, this);
+ goto out;
+ }
+
if (sh->forced_merge) {
sh->source = -1;
goto heal;
@@ -2246,7 +2129,7 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)
local->loc.path);
afr_sh_entry_finish (frame, this);
- return 0;
+ return;
}
source = afr_sh_select_source (sh->sources, priv->child_count);
@@ -2262,33 +2145,8 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)
heal:
afr_sh_entry_sync_prepare (frame, this);
-
- return 0;
-}
-
-
-
-int
-afr_sh_entry_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- int call_count = 0;
- afr_local_t *local = NULL;
-
- local = frame->local;
- afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent, &local->loc);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- afr_sh_entry_fix (frame, this);
- }
-
- return 0;
+out:
+ return;
}
int
@@ -2312,7 +2170,9 @@ afr_sh_post_nonblocking_entry_cbk (call_frame_t *frame, xlator_t *this)
gf_log (this->name, GF_LOG_DEBUG, "Non Blocking entrylks done "
"for %s. Proceeding to FOP", local->loc.path);
afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_entry_lookup_cbk, _gf_false);
+ afr_sh_entry_fix, NULL,
+ AFR_LOOKUP_FAIL_CONFLICTS |
+ AFR_LOOKUP_FAIL_MISSING_GFIDS);
}
return 0;
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
index 9999fdcdbd2..efc8412615f 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -459,8 +459,9 @@ afr_sh_metadata_sync_prepare (call_frame_t *frame, xlator_t *this)
}
-int
-afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
+void
+afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -473,6 +474,12 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
sh = &local->self_heal;
priv = this->private;
+ if (op_ret < 0) {
+ sh->op_failed = 1;
+ afr_sh_set_error (sh, op_errno);
+ afr_sh_metadata_finish (frame, this);
+ goto out;
+ }
nsources = afr_build_sources (this, sh->xattr, sh->buf,
sh->pending_matrix, sh->sources,
sh->success_children,
@@ -483,7 +490,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
local->loc.path);
afr_sh_metadata_finish (frame, this);
- return 0;
+ goto out;
}
if ((nsources == -1)
@@ -510,7 +517,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
local->govinda_gOvinda = 1;
afr_sh_metadata_finish (frame, this);
- return 0;
+ goto out;
}
source = afr_sh_select_source (sh->sources, priv->child_count);
@@ -520,7 +527,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
"No active sources found.");
afr_sh_metadata_finish (frame, this);
- return 0;
+ goto out;
}
sh->source = source;
@@ -547,32 +554,8 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
}
afr_sh_metadata_sync_prepare (frame, this);
-
- return 0;
-}
-
-
-int
-afr_sh_metadata_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- afr_local_t *local = NULL;
- int call_count = 0;
-
- local = frame->local;
-
- afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent, &local->loc);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_sh_metadata_fix (frame, this);
-
- return 0;
+out:
+ return;
}
int
@@ -597,7 +580,9 @@ afr_sh_metadata_post_nonblocking_inodelk_cbk (call_frame_t *frame,
"inodelks done for %s. Proceeding to FOP",
local->loc.path);
afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_metadata_lookup_cbk, _gf_false);
+ afr_sh_metadata_fix, NULL,
+ AFR_LOOKUP_FAIL_CONFLICTS |
+ AFR_LOOKUP_FAIL_MISSING_GFIDS);
}
return 0;
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
index d27d9e09b5b..30450d97c8f 100644
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ b/xlators/cluster/afr/src/afr-self-heald.c
@@ -24,8 +24,11 @@
#include "afr.h"
#include "syncop.h"
#include "afr-self-heald.h"
+#include "afr-self-heal-common.h"
static int
+_crawl_directory (loc_t *loc, pid_t pid, uuid_t gfid);
+static int
get_pathinfo_host (char *pathinfo, char *hostname, size_t size)
{
char *start = NULL;
@@ -81,20 +84,99 @@ out:
return ret;
}
+static void
+_generate_gfid_on_empty (uuid_t gfid)
+{
+ if (uuid_is_null (gfid))
+ uuid_generate (gfid);
+}
+
+static void
+_empty_gfid_on_set (uuid_t gfid, int lookup_status, struct iatt *iatt)
+{
+ if (lookup_status || !uuid_compare (gfid, iatt->ia_gfid))
+ uuid_clear (gfid);
+}
+
+static void
+_fill_loc_info (loc_t *loc, struct iatt *iatt, struct iatt *parent)
+{
+ afr_update_loc_gfids (loc, iatt, parent);
+ uuid_copy (loc->inode->gfid, iatt->ia_gfid);
+}
+
+static int
+_perform_self_heal (xlator_t *this, loc_t *parentloc, gf_dirent_t *entries,
+ uuid_t gfid, off_t *offset, pid_t pid)
+{
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ struct iatt iatt = {0};
+ struct iatt parent = {0};;
+ int ret = 0;
+ loc_t entry_loc = {0};
+ afr_private_t *priv = NULL;
+ dict_t *xattr_req = NULL;
+
+ priv = this->private;
+
+ xattr_req = dict_new ();
+ if (!xattr_req) {
+ ret = -1;
+ goto out;
+ }
+
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ *offset = entry->d_off;
+ if (IS_ENTRY_CWD (entry->d_name) ||
+ IS_ENTRY_PARENT (entry->d_name))
+ continue;
+
+ ret = dict_reset (xattr_req);
+ if (ret)
+ goto out;
+
+ loc_wipe (&entry_loc);
+ ret = afr_build_child_loc (this, &entry_loc,
+ parentloc, entry->d_name);
+ if (ret)
+ goto out;
+
+ _generate_gfid_on_empty (gfid);
+ ret = afr_set_dict_gfid (xattr_req, gfid);
+ if (ret)
+ goto out;
+ gf_log (this->name, GF_LOG_DEBUG, "lookup %s", entry_loc.path);
+
+ ret = syncop_lookup (this, &entry_loc, xattr_req,
+ &iatt, NULL, &parent);
+ _empty_gfid_on_set (gfid, ret, &iatt);
+ //Don't fail the crawl if lookup fails as it
+ //could be because of split-brain
+ if (ret || (!IA_ISDIR (iatt.ia_type)))
+ continue;
+ _fill_loc_info (&entry_loc, &iatt, &parent);
+ ret = _crawl_directory (&entry_loc, pid, gfid);
+ }
+ ret = 0;
+out:
+ if (xattr_req)
+ dict_unref (xattr_req);
+ if (entry_loc.path)
+ loc_wipe (&entry_loc);
+ return ret;
+}
+
static int
-_crawl_directory (loc_t *loc, pid_t pid)
+_crawl_directory (loc_t *loc, pid_t pid, uuid_t gfid)
{
xlator_t *this = NULL;
afr_private_t *priv = NULL;
fd_t *fd = NULL;
off_t offset = 0;
- loc_t entry_loc = {0};
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
gf_dirent_t entries;
struct iatt iatt = {0};
struct iatt parent = {0};;
- char *file_path = NULL;
int ret = 0;
gf_boolean_t free_entries = _gf_false;
@@ -138,42 +220,14 @@ _crawl_directory (loc_t *loc, pid_t pid)
if (list_empty (&entries.list))
goto out;
- list_for_each_entry_safe (entry, tmp, &entries.list, list) {
- offset = entry->d_off;
- if (IS_ENTRY_CWD (entry->d_name) ||
- IS_ENTRY_PARENT (entry->d_name))
- continue;
-
- file_path = afr_build_file_path (loc, entry);
- if (!file_path) {
- ret = -1;
- goto out;
- }
-
- loc_wipe (&entry_loc);
- afr_build_child_loc (loc, &entry_loc,
- file_path, entry->d_name);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "found readdir entry=%s", entry->d_name);
-
- ret = syncop_lookup (this, &entry_loc, NULL,
- &iatt, NULL, &parent);
-
- //Don't fail the crawl if lookup fails as it
- //could be because of split-brain
- if (ret || (!IA_ISDIR (iatt.ia_type)))
- continue;
- ret = _crawl_directory (&entry_loc, pid);
- }
-
+ ret = _perform_self_heal (this, loc, &entries, gfid, &offset, pid);
gf_dirent_free (&entries);
free_entries = _gf_false;
}
+ if (fd)
+ fd_unref (fd);
ret = 0;
out:
- if (entry_loc.path)
- loc_wipe (&entry_loc);
if (free_entries)
gf_dirent_free (&entries);
return ret;
@@ -331,6 +385,7 @@ afr_crawl_directory (xlator_t *this, pid_t pid)
loc_t loc = {0};
gf_boolean_t crawl = _gf_false;
int ret = 0;
+ uuid_t gfid = {0};
priv = this->private;
shd = &priv->shd;
@@ -357,7 +412,7 @@ afr_crawl_directory (xlator_t *this, pid_t pid)
afr_build_root_loc (priv->root_inode, &loc);
while (crawl) {
- ret = _crawl_directory (&loc, pid);
+ ret = _crawl_directory (&loc, pid, gfid);
if (ret)
gf_log (this->name, GF_LOG_ERROR, "Crawl failed");
else
@@ -470,43 +525,3 @@ afr_set_root_gfid (dict_t *dict)
return ret;
}
-
-char *
-afr_build_file_path (loc_t *loc, gf_dirent_t *entry)
-{
- xlator_t *this = NULL;
- char *file_path = NULL;
- int pathlen = 0;
- size_t total_size = 0;
- char *fmt = NULL;
-
- this = THIS;
-
- pathlen = STRLEN_0 (loc->path);
-
- if (IS_ROOT_PATH (loc->path)) {
- total_size = pathlen + entry->d_len;
- fmt = "%s%s";
- } else {
- total_size = pathlen + entry->d_len + 1; /* for the extra '/' in the path */
- fmt = "%s/%s";
- }
-
- file_path = GF_CALLOC (1, total_size + 1, gf_afr_mt_char);
- if (!file_path)
- goto out;
-
- snprintf(file_path, total_size, fmt, loc->path, entry->d_name);
-out:
- return file_path;
-}
-
-void
-afr_build_child_loc (loc_t *parent, loc_t *child, char *path, char *name)
-{
- child->path = path;
- child->name = name;
-
- child->parent = inode_ref (parent->inode);
- child->inode = inode_new (parent->inode->table);
-}
diff --git a/xlators/cluster/afr/src/afr-self-heald.h b/xlators/cluster/afr/src/afr-self-heald.h
index c85c97b25e4..5d7892fa785 100644
--- a/xlators/cluster/afr/src/afr-self-heald.h
+++ b/xlators/cluster/afr/src/afr-self-heald.h
@@ -37,8 +37,4 @@ void afr_build_root_loc (inode_t *inode, loc_t *loc);
int afr_set_root_gfid (dict_t *dict);
-char * afr_build_file_path (loc_t *loc, gf_dirent_t *entry);
-
-void
-afr_build_child_loc (loc_t *parent, loc_t *child, char *path, char *name);
#endif /* __AFR_SELF_HEALD_H__ */
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index becbd261f57..0f4db7d91f1 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -48,6 +48,8 @@ typedef int (*afr_impunge_done_cbk_t) (call_frame_t *frame, xlator_t *this,
typedef int (*afr_post_remove_call_t) (call_frame_t *frame, xlator_t *this);
typedef int (*afr_lock_cbk_t) (call_frame_t *frame, xlator_t *this);
+typedef void (*afr_lookup_done_cbk_t) (call_frame_t *frame, xlator_t *this,
+ int32_t op_ret, int32_t op_errno);
typedef enum {
AFR_POS_UNKNOWN,
@@ -204,6 +206,10 @@ typedef struct {
int32_t *fresh_parent_dirs;
/* array of errno's, one for each child */
int *child_errno;
+ /*loc used for lookup*/
+ loc_t lookup_loc;
+ int32_t lookup_flags;
+ afr_lookup_done_cbk_t lookup_done;
int32_t **pending_matrix;
int32_t **delta_matrix;
@@ -979,7 +985,7 @@ gf_boolean_t
afr_conflicting_iattrs (struct iatt *bufs, int32_t *success_children,
unsigned int child_count, const char *path,
const char *xlator_name);
-int
+unsigned int
afr_gfid_missing_count (const char *xlator_name, int32_t *children,
struct iatt *bufs, unsigned int child_count,
const char *path);
diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c
index 0623b817a78..63c89b3c7b2 100644
--- a/xlators/cluster/afr/src/pump.c
+++ b/xlators/cluster/afr/src/pump.c
@@ -332,7 +332,7 @@ pump_save_file_stats (xlator_t *this, const char *path)
}
static int
-gf_pump_traverse_directory (loc_t *loc)
+gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
{
xlator_t *this = NULL;
fd_t *fd = NULL;
@@ -346,7 +346,6 @@ gf_pump_traverse_directory (loc_t *loc)
struct iatt iatt, parent;
dict_t *xattr_rsp;
- char *file_path = NULL;
int ret = 0;
gf_boolean_t is_directory_empty = _gf_true;
@@ -385,15 +384,10 @@ gf_pump_traverse_directory (loc_t *loc)
gf_log (this->name, GF_LOG_DEBUG,
"found readdir entry=%s", entry->d_name);
- file_path = afr_build_file_path (loc, entry);
- if (!file_path) {
- gf_log (this->name, GF_LOG_DEBUG,
- "file path construction failed");
+ ret = afr_build_child_loc (this, &entry_loc, loc,
+ entry->d_name);
+ if (ret)
goto out;
- }
-
- afr_build_child_loc (loc, &entry_loc, file_path,
- entry->d_name);
if (!IS_ENTRY_CWD (entry->d_name) &&
!IS_ENTRY_PARENT (entry->d_name)) {
@@ -401,8 +395,17 @@ gf_pump_traverse_directory (loc_t *loc)
is_directory_empty = _gf_false;
ret = syncop_lookup (this, &entry_loc, NULL,
&iatt, &xattr_rsp, &parent);
-
- memcpy (entry_loc.inode->gfid, iatt.ia_gfid, 16);
+ if (ret)
+ continue;
+
+ if (uuid_is_null (iatt.ia_gfid)) {
+ uuid_generate (gfid);
+ uuid_copy (entry_loc.inode->gfid,
+ gfid);
+ } else {
+ uuid_copy (entry_loc.inode->gfid,
+ iatt.ia_gfid);
+ }
gf_log (this->name, GF_LOG_DEBUG,
"lookup %s => %"PRId64,
@@ -440,7 +443,7 @@ gf_pump_traverse_directory (loc_t *loc)
gf_log (this->name, GF_LOG_TRACE,
"entering dir=%s",
entry->d_name);
- gf_pump_traverse_directory (&entry_loc);
+ gf_pump_traverse_directory (&entry_loc, gfid);
}
}
}
@@ -622,6 +625,7 @@ pump_task (void *data)
struct iatt iatt, parent;
dict_t *xattr_rsp = NULL;
dict_t *xattr_req = NULL;
+ uuid_t gfid = {0};
int ret = -1;
@@ -662,7 +666,7 @@ pump_task (void *data)
goto out;
}
- gf_pump_traverse_directory (&loc);
+ gf_pump_traverse_directory (&loc, gfid);
pump_complete_migration (this);
out: