summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2011-09-27 14:44:01 +0530
committerVijay Bellur <vijay@gluster.com>2011-10-19 03:17:17 -0700
commitb80a2a150b874031df35af8d4f06657906024861 (patch)
tree9205dd82c4614d14104cd27a2ac4ddde42a3d8bf
parenteab187ce06f6d72aeba297604e132d181da4c502 (diff)
cluster/afr: Handle files without gfid
Change-Id: Ie831ae8542c1382c17fb7837cd18b0e4e4d3db75 BUG: 3734 Reviewed-on: http://review.gluster.com/619 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--xlators/cluster/afr/src/afr-common.c30
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c478
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.h27
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c12
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c584
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c93
-rw-r--r--xlators/cluster/afr/src/afr.h10
-rw-r--r--xlators/cluster/afr/src/pump.c109
-rw-r--r--xlators/cluster/afr/src/pump.h1
9 files changed, 610 insertions, 734 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 69e980a03d5..bc8c828e55a 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -456,10 +456,14 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
if (sh->child_success)
GF_FREE (sh->child_success);
+ if (sh->fresh_children)
+ GF_FREE (sh->fresh_children);
if (sh->fresh_parent_dirs)
GF_FREE (sh->fresh_parent_dirs);
loc_wipe (&sh->parent_loc);
+ loc_wipe (&sh->lookup_loc);
+
}
@@ -980,12 +984,12 @@ afr_launch_self_heal (call_frame_t *frame, xlator_t *this,
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;
@@ -1538,6 +1542,7 @@ afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)
int32_t *child_success = NULL;
struct iatt *iatts = NULL;
int i = 0;
+ int32_t *sources = NULL;
GF_ASSERT (local);
local->cont.lookup.xattrs = GF_CALLOC (child_count,
@@ -1565,6 +1570,11 @@ afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)
local->cont.lookup.child_success = child_success;
+ sources = GF_CALLOC (sizeof (*sources), child_count, gf_afr_mt_int32_t);
+ if (NULL == sources)
+ goto out;
+
+ local->cont.lookup.sources = sources;
ret = 0;
out:
return ret;
@@ -3188,21 +3198,19 @@ afr_reset_children (int32_t *fresh_children, int32_t child_count)
}
int32_t*
-afr_fresh_children_create (int32_t child_count)
+afr_children_create (unsigned int child_count)
{
- int32_t *fresh_children = NULL;
+ int32_t *children = NULL;
int i = 0;
- GF_ASSERT (child_count > 0);
-
- fresh_children = GF_CALLOC (child_count, sizeof (*fresh_children),
- gf_afr_mt_int32_t);
- if (NULL == fresh_children)
+ children = GF_CALLOC (child_count, sizeof (*children),
+ gf_afr_mt_int32_t);
+ if (NULL == children)
goto out;
for (i = 0; i < child_count; i++)
- fresh_children[i] = -1;
+ children[i] = -1;
out:
- return fresh_children;
+ return children;
}
void
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 568368b9ccd..b925b0adcef 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -970,12 +970,44 @@ afr_sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
return 0;
}
-static void
+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->child_success = afr_children_create (child_count);
+ if (!sh->child_success)
+ 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,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent)
+ dict_t *xattr, struct iatt *postparent,
+ loc_t *loc)
{
int child_index = 0;
afr_local_t *local = NULL;
@@ -999,8 +1031,7 @@ afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,
} else {
gf_log (this->name, GF_LOG_ERROR,
"path %s on subvolume %s => -1 (%s)",
- local->loc.path,
- priv->children[child_index]->name,
+ loc->path, priv->children[child_index]->name,
strerror (op_errno));
local->self_heal.child_errno[child_index] = op_errno;
}
@@ -1027,6 +1058,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,
@@ -1037,26 +1118,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;
@@ -1065,8 +1137,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
@@ -1143,12 +1215,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;
@@ -1156,23 +1228,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->child_success,
- 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->child_success,
- sh->buf, priv->child_count,
- local->loc.path) ||
- afr_conflicting_iattrs (sh->buf, sh->child_success,
- 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;
}
@@ -1204,22 +1263,22 @@ 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;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
local = frame->local;
sh = &local->self_heal;
@@ -1227,12 +1286,45 @@ afr_sh_missing_entries_lookup_cbk (call_frame_t *frame, void *cookie,
afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
op_errno, inode, buf, xattr,
- postparent);
+ 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->child_success,
+ 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->child_success,
+ 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;
}
@@ -1335,8 +1427,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
@@ -1347,7 +1441,7 @@ afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)
afr_children_copy (sh->child_success,
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;
@@ -1500,35 +1594,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->child_success,
+ sh->fresh_parent_dirs,
+ sh->sources, child_count);
+ afr_get_fresh_children (sh->child_success, 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->child_success,
- 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->child_success,
- sh->fresh_parent_dirs,
- sh->sources, priv->child_count);
- afr_get_fresh_children (sh->child_success, 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
@@ -1536,6 +1629,8 @@ afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this)
sh->child_errno,
priv->child_count, ENOENT);
if (fresh_child_enoents == fresh_parent_count) {
+ gf_log (this->name, GF_LOG_INFO, "Deleting stale file %s",
+ local->loc.path);
afr_sh_set_error (sh, ENOENT);
sh->op_failed = 1;
afr_sh_purge_entry (frame, this);
@@ -1558,32 +1653,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_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent);
- 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;
@@ -1606,28 +1684,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->child_success,
- 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->child_success,
- 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;
}
@@ -1636,9 +1700,9 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
sh->child_success,
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;
}
@@ -1651,34 +1715,14 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)
afr_get_fresh_children (sh->child_success, 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_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent);
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_sh_find_fresh_parents (frame, this);
-
- return 0;
+ return;
}
void
@@ -1696,6 +1740,7 @@ afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)
afr_reset_children (sh->child_success, 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
@@ -1703,7 +1748,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;
@@ -1725,16 +1771,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",
- local->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,
@@ -1742,7 +1791,7 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
local->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,
@@ -1781,8 +1830,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;
@@ -1793,8 +1842,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) {
@@ -1805,8 +1856,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;
@@ -1982,8 +2034,6 @@ afr_self_heal_completion_cbk (call_frame_t *bgsh_frame, xlator_t *this)
afr_set_split_brain (this, sh->inode, split_brain);
- afr_self_heal_type_str_get(sh, sh_type_str,
- sizeof(sh_type_str));
afr_self_heal_type_str_get (sh, sh_type_str,
sizeof(sh_type_str));
if (sh->op_failed) {
@@ -2020,32 +2070,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);
- afr_set_lk_owner (frame, this);
-
- 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,
@@ -2053,9 +2090,16 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
local->self_heal.need_data_self_heal,
local->self_heal.need_entry_self_heal);
+ op_errno = ENOMEM;
sh_frame = copy_frame (frame);
sh_frame->root->pid = SELF_HEAL_PID;
+ if (!sh_frame)
+ goto out;
+ afr_set_lk_owner (sh_frame, this);
+
sh_local = afr_local_copy (local, this);
+ if (!sh_local)
+ goto out;
sh_frame->local = sh_local;
sh = &sh_local->self_heal;
@@ -2064,42 +2108,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 (int),
- gf_afr_mt_int);
- sh->xattr = GF_CALLOC (priv->child_count, sizeof (dict_t *),
- gf_afr_mt_dict_t);
+ sh->success = GF_CALLOC (priv->child_count, sizeof (*sh->success),
+ gf_afr_mt_char);
+ 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->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;
}
- sh->child_success = afr_fresh_children_create (priv->child_count);
- sh->fresh_children = afr_fresh_children_create (priv->child_count);
- sh->fresh_parent_dirs = afr_fresh_children_create (priv->child_count);
+ 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->need_missing_entry_self_heal) {
@@ -2114,7 +2183,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;
}
@@ -2168,3 +2242,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 043ebea2da6..7a06c2f4b13 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);
@@ -84,7 +84,8 @@ void
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_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);
@@ -95,4 +96,18 @@ int
afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,
int child_index, struct iatt *buf,
struct iatt *postparent);
+afr_local_t *
+afr_local_copy (afr_local_t *l, xlator_t *this);
+void
+afr_sh_set_error (afr_self_heal_t *sh, int32_t op_errno);
+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-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index 6ce7106698d..11d6745b446 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -812,11 +812,8 @@ afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,
if (NULL == pending_matrix)
goto out;
- sources = GF_CALLOC (sizeof (*sources), priv->child_count,
- gf_afr_mt_int32_t);
- if (NULL == sources)
- goto out;
-
+ sources = local->cont.lookup.sources;
+ memset (sources, 0, sizeof (*sources) * priv->child_count);
afr_build_pending_matrix (priv->pending_key, pending_matrix,
xattr, txn_type, priv->child_count);
@@ -840,13 +837,8 @@ afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,
config_read_child,
valid_children);
ret = 0;
- local->cont.lookup.sources = sources;
out:
afr_destroy_pending_matrix (pending_matrix, priv->child_count);
- if (-1 == ret) {
- if (sources)
- GF_FREE (sources);
- }
gf_log (this->name, GF_LOG_DEBUG, "returning read_child: %d", read_child);
return read_child;
}
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
index 3977ae101f6..e32b507631a 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);
@@ -759,7 +723,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;
@@ -916,15 +880,47 @@ afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this,
int32_t op_errno)
{
int call_count = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ local = frame->local;
+ sh = &local->self_heal;
call_count = afr_frame_return (frame);
+ if (op_ret == -1)
+ sh->op_failed = 1;
- if (call_count == 0)
+ if (call_count == 0) {
+ if (sh->op_failed) {
+ afr_sh_entry_finish (frame, this);
+ goto out;
+ }
afr_sh_entry_impunge_subvol (frame, this, active_src);
-
+ }
+out:
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,
@@ -935,21 +931,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 active_src = 0;
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;
- active_src = impunge_sh->active_source;
child_index = (long) cookie;
if (op_ret == 0) {
@@ -971,12 +958,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;
}
@@ -1059,7 +1043,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,
@@ -1072,27 +1055,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;
@@ -1110,7 +1086,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
xattr = dict_new ();
if (!xattr) {
- sh->op_failed = 1;
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
goto out;
}
@@ -1119,7 +1094,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
gf_common_mt_int32_t);
if (!pending_array) {
- sh->op_failed = 1;
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
goto out;
}
@@ -1147,7 +1121,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
parent_loc = GF_CALLOC (1, sizeof (*parent_loc),
gf_afr_mt_loc_t);
if (!parent_loc) {
- sh->op_failed = 1;
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
goto out;
}
@@ -1182,12 +1155,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;
}
@@ -1214,6 +1184,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",
@@ -1256,6 +1227,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",
@@ -1290,32 +1262,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,
@@ -1351,20 +1313,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;
- 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;
@@ -1388,12 +1341,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;
}
@@ -1434,19 +1384,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;
@@ -1491,12 +1434,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;
}
@@ -1536,19 +1476,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;
@@ -1574,12 +1507,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;
}
@@ -1659,177 +1589,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;
+ GF_ASSERT (impunge_sh->impunging_entry_mode);
+ GF_ASSERT (impunge_sh->child_errno);
+ GF_ASSERT (sources);
- child_index = (long) cookie;
-
- 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->child_success;
+ 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;
int active_src = 0;
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;
- active_src = impunge_sh->active_source;
-
- if ((op_ret == -1 && op_errno == ENOENT)
- || (IA_ISLNK (impunge_sh->impunging_entry_mode))) {
+ unsigned int recreate_count = 0;
+ unsigned int gfid_miss_count = 0;
+ unsigned int children_up_count = 0;
+ uuid_t gfid = {0};
- /*
- * 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;
- }
-
- 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->child_success,
+ impunge_sh->buf, priv->child_count,
+ impunge_local->loc.path);
+ children_up_count = afr_up_children_count (priv->child_count,
+ impunge_local->child_up);
+ 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->child_success,
+ 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)
@@ -1840,12 +1755,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;
@@ -1870,70 +1783,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++;
- }
+ afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc,
+ afr_sh_entry_common_lookup_done, NULL,
+ AFR_LOOKUP_FAIL_CONFLICTS);
- 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;
- }
-
- 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;
}
@@ -2194,7 +2071,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
priv = this->private;
source = sh->source;
-
for (i = 0; i < priv->child_count; i++) {
if (sh->sources[i] == 0 && local->child_up[i] == 1) {
active_sinks++;
@@ -2204,6 +2080,7 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
if (source != -1)
sh->success[source] = 1;
+ sh->active_sinks = active_sinks;
if (active_sinks == 0) {
gf_log (this->name, GF_LOG_TRACE,
"no active sinks for self-heal on dir %s",
@@ -2218,7 +2095,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
afr_sh_entry_finish (frame, this);
return 0;
}
- sh->active_sinks = active_sinks;
if (source != -1)
gf_log (this->name, GF_LOG_DEBUG,
@@ -2238,8 +2114,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;
@@ -2252,6 +2129,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;
@@ -2273,54 +2157,18 @@ 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);
sh->source = source;
+
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)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- int call_count = -1;
- int child_index = (long) cookie;
-
- local = frame->local;
- sh = &local->self_heal;
-
- LOCK (&frame->lock);
- {
- if (op_ret != -1) {
- sh->xattr[child_index] = dict_ref (xattr);
- sh->buf[child_index] = *buf;
- sh->child_success[sh->success_count] = child_index;
- sh->success_count++;
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- afr_sh_entry_fix (frame, this);
- }
-
- return 0;
+out:
+ return;
}
int
@@ -2344,7 +2192,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 03b91dae300..af2f76d94f9 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -461,8 +461,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;
@@ -475,23 +476,23 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
sh = &local->self_heal;
priv = this->private;
- afr_build_pending_matrix (priv->pending_key, sh->pending_matrix,
- sh->xattr, AFR_METADATA_TRANSACTION,
- priv->child_count);
-
- afr_sh_print_pending_matrix (sh->pending_matrix, this);
-
- nsources = afr_mark_sources (sh->sources, sh->pending_matrix, sh->buf,
- priv->child_count, AFR_SELF_HEAL_METADATA,
- sh->child_success, this->name);
-
+ 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->child_success,
+ AFR_METADATA_TRANSACTION);
if (nsources == 0) {
gf_log (this->name, GF_LOG_TRACE,
"No self-heal needed for %s",
local->loc.path);
afr_sh_metadata_finish (frame, this);
- return 0;
+ goto out;
}
if ((nsources == -1)
@@ -518,7 +519,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);
@@ -528,7 +529,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;
@@ -546,62 +547,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;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
- int child_index = 0;
-
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
-
- child_index = (long) cookie;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "path %s on subvolume %s is of mode 0%o",
- local->loc.path,
- priv->children[child_index]->name,
- buf->ia_type);
-
- sh->buf[child_index] = *buf;
- if (xattr)
- sh->xattr[child_index] = dict_ref (xattr);
- sh->child_success[sh->success_count] = child_index;
- sh->success_count++;
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "path %s on subvolume %s => -1 (%s)",
- local->loc.path,
- priv->children[child_index]->name,
- strerror (op_errno));
-
- sh->child_errno[child_index] = op_errno;
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_sh_metadata_fix (frame, this);
-
- return 0;
+out:
+ return;
}
int
@@ -626,7 +573,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.h b/xlators/cluster/afr/src/afr.h
index bc85fd71d15..f99ce471994 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -47,6 +47,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 struct _afr_private {
gf_lock_t lock; /* to guard access to child_count, etc */
@@ -170,6 +172,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;
@@ -1018,7 +1024,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);
@@ -1032,5 +1038,5 @@ int32_t
afr_resultant_errno_get (int32_t *children,
int *child_errno, unsigned int child_count);
int32_t*
-afr_fresh_children_create (int32_t child_count);
+afr_children_create (unsigned int child_count);
#endif /* __AFR_H__ */
diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c
index 585a0686edc..b756e1664fc 100644
--- a/xlators/cluster/afr/src/pump.c
+++ b/xlators/cluster/afr/src/pump.c
@@ -29,6 +29,7 @@
#include "afr-common.c"
#include "defaults.c"
+uint64_t pump_pid = 0;
static int
pump_mark_start_pending (xlator_t *this)
{
@@ -148,71 +149,6 @@ pump_set_resume_path (xlator_t *this, const char *path)
return ret;
}
-static void
-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);
-}
-
-static char *
-build_file_path (loc_t *loc, gf_dirent_t *entry)
-{
- xlator_t *this = NULL;
- char *file_path = NULL;
- int pathlen = 0;
- int total_size = 0;
-
- this = THIS;
-
- pathlen = STRLEN_0 (loc->path);
-
- if (IS_ROOT_PATH (loc->path)) {
- total_size = pathlen + entry->d_len;
- file_path = GF_CALLOC (1, total_size, gf_afr_mt_char);
- if (!file_path) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- return NULL;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "constructing file path of size=%d"
- "pathlen=%d, d_len=%d",
- total_size, pathlen,
- entry->d_len);
-
- snprintf(file_path, total_size, "%s%s", loc->path, entry->d_name);
-
- } else {
- total_size = pathlen + entry->d_len + 1; /* for the extra '/' in the path */
- file_path = GF_CALLOC (1, total_size + 1, gf_afr_mt_char);
- if (!file_path) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- return NULL;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "constructing file path of size=%d"
- "pathlen=%d, d_len=%d",
- total_size, pathlen,
- entry->d_len);
-
- snprintf(file_path, total_size, "%s/%s", loc->path, entry->d_name);
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "path=%s and d_name=%s", loc->path, entry->d_name);
- gf_log (this->name, GF_LOG_TRACE,
- "constructed file_path=%s of size=%d", file_path, total_size);
-
- return file_path;
-}
-
static int
pump_save_path (xlator_t *this, const char *path)
{
@@ -400,7 +336,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;
afr_private_t *priv = NULL;
@@ -415,9 +351,6 @@ gf_pump_traverse_directory (loc_t *loc)
struct iatt iatt, parent;
dict_t *xattr_rsp;
- int source = 0;
-
- char *file_path = NULL;
int ret = 0;
gf_boolean_t is_directory_empty = _gf_true;
@@ -427,14 +360,14 @@ gf_pump_traverse_directory (loc_t *loc)
GF_ASSERT (loc->inode);
- fd = fd_create (loc->inode, PUMP_PID);
+ fd = fd_create (loc->inode, pump_pid);
if (!fd) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to create fd for %s", loc->path);
goto out;
}
- ret = syncop_opendir (priv->children[source], loc, fd);
+ ret = syncop_opendir (this, loc, fd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"opendir failed on %s", loc->path);
@@ -445,7 +378,7 @@ gf_pump_traverse_directory (loc_t *loc)
"pump opendir on %s returned=%d",
loc->path, ret);
- while (syncop_readdirp (priv->children[source], fd, 131072, offset, &entries)) {
+ while (syncop_readdirp (this, fd, 131072, offset, &entries)) {
if (list_empty (&entries.list)) {
gf_log (this->name, GF_LOG_TRACE,
@@ -457,25 +390,30 @@ gf_pump_traverse_directory (loc_t *loc)
gf_log (this->name, GF_LOG_DEBUG,
"found readdir entry=%s", entry->d_name);
- file_path = 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;
- }
-
- build_child_loc (loc, &entry_loc, file_path, entry->d_name);
-
if (!IS_ENTRY_CWD (entry->d_name) &&
!IS_ENTRY_PARENT (entry->d_name)) {
is_directory_empty = _gf_false;
ret = syncop_lookup (this, &entry_loc, NULL,
&iatt, &xattr_rsp, &parent);
+ if (ret)
+ continue;
entry_loc.ino = iatt.ia_ino;
entry_loc.inode->ino = iatt.ia_ino;
- memcpy (entry_loc.inode->gfid, iatt.ia_gfid, 16);
+
+ 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,
@@ -513,7 +451,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);
}
}
}
@@ -687,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;
@@ -727,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:
@@ -771,8 +710,8 @@ pump_start (call_frame_t *pump_frame, xlator_t *this)
priv = this->private;
pump_priv = priv->pump_private;
- if (!pump_frame->root->lk_owner)
- pump_frame->root->lk_owner = PUMP_LK_OWNER;
+ pump_frame->root->lk_owner = (uint64_t) (unsigned long)pump_frame->root;
+ pump_pid = (uint64_t) (unsigned long)pump_frame->root;
ret = synctask_new (pump_priv->env, pump_task,
pump_task_completion,
diff --git a/xlators/cluster/afr/src/pump.h b/xlators/cluster/afr/src/pump.h
index 0c0b57fc2d3..19bb96f8c6a 100644
--- a/xlators/cluster/afr/src/pump.h
+++ b/xlators/cluster/afr/src/pump.h
@@ -26,7 +26,6 @@
#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"
#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
-#define PUMP_PID 696969
#define PUMP_LK_OWNER 696969
#define IS_ROOT_PATH(path) (!strcmp (path, "/"))