diff options
author | Anand Avati <avati@gluster.com> | 2011-03-10 03:21:21 +0000 |
---|---|---|
committer | Vijay Bellur <vijay@dev.gluster.com> | 2011-03-14 03:09:07 -0700 |
commit | 2108ee66f226a124fd2ec20692e9941ed15464a5 (patch) | |
tree | 0126148edc09ac7c491444d906e4835c7449ffdd /xlators/cluster/afr | |
parent | 3145f70fc27d8259b885049bcf7a737f4b7de569 (diff) |
afr-entry-self-heal: fixes to detected renames (gfid based)
- perform expunge first (before impunge) to be able to delete renamed away files
- perform readdirp instead of readdir to get gfid along with entry names
- if gfid mismatch is found, expunge the entry
Signed-off-by: Anand Avati <avati@gluster.com>
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 2500 (Self Healing not working)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2500
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 53 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 1 |
2 files changed, 39 insertions, 15 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index dff64610d..2fac06a52 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -344,6 +344,13 @@ out: int +afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this); + +int +afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this, + int active_src); + +int afr_sh_entry_expunge_all (call_frame_t *frame, xlator_t *this); int @@ -620,6 +627,7 @@ afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie, int source = 0; call_frame_t *frame = NULL; int active_src = 0; + int need_expunge = 0; priv = this->private; @@ -629,14 +637,31 @@ afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie, active_src = expunge_sh->active_source; source = (long) cookie; - if (op_ret == -1 && op_errno == ENOENT && postparent) { + if (op_ret == -1 && op_errno == ENOENT) + need_expunge = 1; + if (!uuid_is_null (expunge_sh->entrybuf.ia_gfid) && + !uuid_is_null (buf->ia_gfid) && + (uuid_compare (expunge_sh->entrybuf.ia_gfid, buf->ia_gfid) != 0)) { + char uuidbuf1[64]; + char uuidbuf2[64]; + gf_log (this->name, GF_LOG_DEBUG, + "entry %s found on %s with mismatching gfid (%s/%s)", + expunge_local->loc.path, + priv->children[source]->name, + uuid_utoa_r (expunge_sh->entrybuf.ia_gfid, uuidbuf1), + uuid_utoa_r (buf->ia_gfid, uuidbuf2)); + need_expunge = 1; + } + + if (need_expunge) { gf_log (this->name, GF_LOG_TRACE, "missing entry %s on %s", expunge_local->loc.path, priv->children[source]->name); - expunge_sh->parentbuf = *postparent; + if (postparent) + expunge_sh->parentbuf = *postparent; afr_sh_entry_expunge_purge (expunge_frame, this, active_src); @@ -665,7 +690,7 @@ afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie, int afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this, - char *name) + gf_dirent_t *entry) { afr_private_t *priv = NULL; afr_local_t *local = NULL; @@ -677,6 +702,7 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this, int active_src = 0; int source = 0; int op_errno = 0; + char *name = NULL; priv = this->private; local = frame->local; @@ -685,6 +711,8 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this, active_src = sh->active_source; source = sh->source; + name = entry->d_name; + if ((strcmp (name, ".") == 0) || (strcmp (name, "..") == 0) || ((strcmp (local->loc.path, "/") == 0) @@ -713,6 +741,8 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this, expunge_sh = &expunge_local->self_heal; expunge_sh->sh_frame = frame; expunge_sh->active_source = active_src; + expunge_sh->entrybuf = entry->d_stat; + ret = build_child_loc (this, &expunge_local->loc, &local->loc, name); if (ret != 0) { @@ -790,7 +820,7 @@ afr_sh_entry_expunge_readdir_cbk (call_frame_t *frame, void *cookie, local->call_count = entry_count; list_for_each_entry (entry, &entries->list, list) { - afr_sh_entry_expunge_entry (frame, this, entry->d_name); + afr_sh_entry_expunge_entry (frame, this, entry); } return 0; @@ -810,7 +840,7 @@ afr_sh_entry_expunge_subvol (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, afr_sh_entry_expunge_readdir_cbk, priv->children[active_src], - priv->children[active_src]->fops->readdir, + priv->children[active_src]->fops->readdirp, sh->healing_fd, sh->block_size, sh->offset); return 0; @@ -858,20 +888,13 @@ afr_sh_entry_expunge_all (call_frame_t *frame, xlator_t *this) return 0; out: - afr_sh_entry_erase_pending (frame, this); + afr_sh_entry_impunge_all (frame, this); return 0; } int -afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this); - -int -afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this, - int active_src); - -int afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this, int active_src) { @@ -1885,7 +1908,7 @@ afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this) if (active_src == -1) { /* completed creating missing files on all subvolumes */ - afr_sh_entry_expunge_all (frame, this); + afr_sh_entry_erase_pending (frame, this); return 0; } @@ -1944,7 +1967,7 @@ afr_sh_entry_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->loc.path); sh->active_source = -1; - afr_sh_entry_impunge_all (frame, this); + afr_sh_entry_expunge_all (frame, this); } return 0; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 3efa484b7..e6cd9bf49 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -131,6 +131,7 @@ typedef struct { /* array of stat's, one for each child */ struct iatt *buf; struct iatt parentbuf; + struct iatt entrybuf; /* array of xattr's, one for each child */ dict_t **xattr; |