diff options
| author | Pranith Kumar K <pranithk@gluster.com> | 2012-07-25 09:56:58 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-07-25 15:02:39 -0700 | 
| commit | 75ee490213b7f7673970ef80dee3bcc567848c26 (patch) | |
| tree | ae3680385a4fec07cd8b6bb5f1551cbfb6c91c9b | |
| parent | 787d52d8e8bf415e48fa41ff9c7fef4693804903 (diff) | |
cluster/afr: Perform data self-heal for non regular files
RCA:
Data self-heal for non regular files open the files
and then proceeds using that fd. This approach
does not work for symlinks because open on symlink opens
the file resolved by it.
Fix:
If the file is not a regular file then perform self-heal using
loc. It needs to get 'big' lock and then perform lookup to get
changelog then erase data part of chagelog, then unlock.
Test cases:
Automated at
https://github.com/pranithk/gluster-tests/blob/master/afr/special-file-self-heal-test.sh
Change-Id: I924a922f5135872efe2cccf2e712ada082c5689f
BUG: 811317
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Reviewed-on: http://review.gluster.com/3724
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-by: Anand Avati <avati@redhat.com>
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 91 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.h | 4 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-data.c | 146 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 63 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 75 | 
5 files changed, 162 insertions, 217 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index b5b4627f6..f082685e2 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -135,8 +135,7 @@ afr_sh_print_pending_matrix (int32_t *pending_matrix[], xlator_t *this)                          ptr += sprintf (ptr, "%d ", pending_matrix[i][j]);                  }                  sprintf (ptr, "]"); -                gf_log (this->name, GF_LOG_DEBUG, -                        "pending_matrix: %s", buf); +                gf_log (this->name, GF_LOG_DEBUG, "pending_matrix: %s", buf);          }          GF_FREE (buf); @@ -2426,3 +2425,91 @@ out:          return ret;  } + +int +afr_sh_erase_pending (call_frame_t *frame, xlator_t *this, +                      afr_transaction_type type, afr_fxattrop_cbk_t cbk, +                      int (*finish)(call_frame_t *frame, xlator_t *this)) +{ +        afr_local_t     *local = NULL; +        afr_self_heal_t *sh = NULL; +        afr_private_t   *priv = NULL; +        int              call_count = 0; +        int              i = 0; +        dict_t          **erase_xattr = NULL; +        int             ret = -1; + +        local = frame->local; +        sh = &local->self_heal; +        priv = this->private; + +        afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, +                                 sh->success, priv->child_count, type); + +        erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count, +                                 gf_afr_mt_dict_t); +        if (!erase_xattr) +                goto out; + +        for (i = 0; i < priv->child_count; i++) { +                if (sh->xattr[i]) { +                        call_count++; +                        erase_xattr[i] = dict_new (); +                        if (!erase_xattr[i]) +                                goto out; +                } +        } + +        afr_sh_delta_to_xattr (this, sh->delta_matrix, erase_xattr, +                               priv->child_count, type); + +        gf_log (this->name, GF_LOG_DEBUG, "Delta matrix for: %s", +                lkowner_utoa (&frame->root->lk_owner)); +        afr_sh_print_pending_matrix (sh->delta_matrix, this); +        local->call_count = call_count; +        if (call_count == 0) { +                ret = 0; +                finish (frame, this); +                goto out; +        } + +        for (i = 0; i < priv->child_count; i++) { +                if (!erase_xattr[i]) +                        continue; + +                if (sh->healing_fd) {//true for ENTRY, reg file DATA transaction +                        STACK_WIND_COOKIE (frame, cbk, (void *) (long) i, +                                           priv->children[i], +                                           priv->children[i]->fops->fxattrop, +                                           sh->healing_fd, +                                           GF_XATTROP_ADD_ARRAY, erase_xattr[i], +                                           NULL); +                } else { +                        STACK_WIND_COOKIE (frame, cbk, (void *) (long) i, +                                           priv->children[i], +                                           priv->children[i]->fops->xattrop, +                                           &local->loc, +                                           GF_XATTROP_ADD_ARRAY, erase_xattr[i], +                                           NULL); +                } +        } + +        ret = 0; +out: +        if (erase_xattr) { +                for (i = 0; i < priv->child_count; i++) { +                        if (erase_xattr[i]) { +                                dict_unref (erase_xattr[i]); +                        } +                } +        } + +        GF_FREE (erase_xattr); + +        if (ret < 0) { +                sh->op_failed = _gf_true; +                finish (frame, this); +        } + +        return 0; +} diff --git a/xlators/cluster/afr/src/afr-self-heal-common.h b/xlators/cluster/afr/src/afr-self-heal-common.h index cea554670..6eabd1766 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.h +++ b/xlators/cluster/afr/src/afr-self-heal-common.h @@ -125,4 +125,8 @@ afr_children_intersection_get (int32_t *set1, int32_t *set2,  int  afr_get_no_xattr_dir_read_child (xlator_t *this, int32_t *success_children,                                   struct iatt *bufs); +int +afr_sh_erase_pending (call_frame_t *frame, xlator_t *this, +                      afr_transaction_type type, afr_fxattrop_cbk_t cbk, +                      int (*finish)(call_frame_t *frame, xlator_t *this));  #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 2edee5fd4..1672b4f28 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -121,6 +121,11 @@ afr_sh_data_close (call_frame_t *frame, xlator_t *this)          sh    = &local->self_heal;          priv  = this->private; +        if (!sh->healing_fd) { +                //This happens when file is non-reg +                afr_sh_data_done (frame, this); +                return 0; +        }          call_count        = afr_set_elem_count_get (sh->success,                                                      priv->child_count);          local->call_count = call_count; @@ -395,66 +400,9 @@ out:  int  afr_sh_data_erase_pending (call_frame_t *frame, xlator_t *this)  { -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        afr_private_t   *priv = NULL; -        int              call_count = 0; -        int              i = 0; -        dict_t          **erase_xattr = NULL; - -        local = frame->local; -        sh = &local->self_heal; -        priv = this->private; - -        afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, sh->success, -                                 priv->child_count, AFR_DATA_TRANSACTION); -        gf_log (this->name, GF_LOG_DEBUG, "Delta matrix for: %s", -                lkowner_utoa (&frame->root->lk_owner)); -        afr_sh_print_pending_matrix (sh->delta_matrix, this); - -        erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count, -                                 gf_afr_mt_dict_t); - -        for (i = 0; i < priv->child_count; i++) { -                if (sh->xattr[i]) { -                        call_count++; - -                        erase_xattr[i] = get_new_dict(); -                        dict_ref (erase_xattr[i]); -                } -        } - -        afr_sh_delta_to_xattr (this, sh->delta_matrix, erase_xattr, -                               priv->child_count, AFR_DATA_TRANSACTION); - -        GF_ASSERT (call_count); -        local->call_count = call_count; -        for (i = 0; i < priv->child_count; i++) { -                if (!erase_xattr[i]) -                        continue; - -                gf_log (this->name, GF_LOG_DEBUG, -                        "erasing pending flags from %s on %s", -                        local->loc.path, priv->children[i]->name); - -                STACK_WIND_COOKIE (frame, afr_sh_data_erase_pending_cbk, -                                   (void *) (long) i, -                                   priv->children[i], -                                   priv->children[i]->fops->fxattrop, -                                   sh->healing_fd, -                                   GF_XATTROP_ADD_ARRAY, erase_xattr[i], -                                   NULL); -                if (!--call_count) -                        break; -        } - -        for (i = 0; i < priv->child_count; i++) { -                if (erase_xattr[i]) { -                        dict_unref (erase_xattr[i]); -                } -        } -        GF_FREE (erase_xattr); - +        afr_sh_erase_pending (frame, this, AFR_DATA_TRANSACTION, +                              afr_sh_data_erase_pending_cbk, +                              afr_sh_data_finish);          return 0;  } @@ -868,27 +816,6 @@ out:  }  int -afr_sh_data_special_file_fix (call_frame_t *frame, xlator_t *this) -{ -        afr_private_t   *priv = NULL; -        afr_self_heal_t *sh = NULL; -        afr_local_t     *local = NULL; -        int             i = 0; - -        local = frame->local; -        sh = &local->self_heal; -        priv = this->private; - -        for (i = 0; i < priv->child_count ; i++) -                if (1 == local->child_up[i]) -                        sh->success[i] = 1; - -        afr_sh_data_erase_pending (frame, this); - -        return 0; -} - -int  afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,                         xlator_t *this, int32_t op_ret, int32_t op_errno,                         struct iatt *buf, dict_t *xdata) @@ -938,10 +865,7 @@ afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,                          afr_sh_data_fail (frame, this);                          goto out;                  } -                if (IA_ISREG (sh->type)) -                        afr_sh_data_fxattrop_fstat_done (frame, this); -                else -                        afr_sh_data_special_file_fix (frame, this); +                afr_sh_data_fxattrop_fstat_done (frame, this);          }  out:          return 0; @@ -1382,6 +1306,50 @@ afr_sh_data_open (call_frame_t *frame, xlator_t *this)          return 0;  } +void +afr_sh_non_reg_fix (call_frame_t *frame, xlator_t *this, +                    int32_t op_ret, int32_t op_errno) +{ +        afr_private_t   *priv = NULL; +        afr_self_heal_t *sh = NULL; +        afr_local_t     *local = NULL; +        int             i = 0; + +        if (op_ret < 0) { +                afr_sh_data_fail (frame, this); +                return; +        } + +        local = frame->local; +        sh = &local->self_heal; +        priv = this->private; + +        for (i = 0; i < priv->child_count ; i++) { +                if (1 == local->child_up[i]) +                        sh->success[i] = 1; +        } + +        afr_sh_erase_pending (frame, this, AFR_DATA_TRANSACTION, +                              afr_sh_data_erase_pending_cbk, +                              afr_sh_data_finish); +} + +int +afr_sh_non_reg_lock_success (call_frame_t *frame, xlator_t *this) +{ +        afr_local_t   *local = NULL; +        afr_self_heal_t *sh = NULL; + +        local = frame->local; +        sh = &local->self_heal; +        sh->data_lock_held = _gf_true; +        afr_sh_common_lookup (frame, this, &local->loc, +                              afr_sh_non_reg_fix, NULL, +                              AFR_LOOKUP_FAIL_CONFLICTS | +                              AFR_LOOKUP_FAIL_MISSING_GFIDS, +                              NULL); +        return 0; +}  int  afr_self_heal_data (call_frame_t *frame, xlator_t *this) @@ -1397,7 +1365,13 @@ afr_self_heal_data (call_frame_t *frame, xlator_t *this)          if (sh->do_data_self_heal &&              afr_data_self_heal_enabled (priv->data_self_heal)) { -                afr_sh_data_open (frame, this); +                if (IA_ISREG (sh->type)) { +                        afr_sh_data_open (frame, this); +                } else { +                        afr_sh_data_lock (frame, this, 0, 0, +                                          afr_sh_non_reg_lock_success, +                                          afr_sh_data_fail); +                }          } else {                  gf_log (this->name, GF_LOG_TRACE,                          "not doing data self heal on %s", diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index a23a74d72..14ce3aa9f 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -157,73 +157,20 @@ afr_sh_entry_erase_pending (call_frame_t *frame, xlator_t *this)  {          afr_local_t     *local = NULL;          afr_self_heal_t *sh = NULL; -        afr_private_t   *priv = NULL; -        int              call_count = 0; -        int              i = 0; -        dict_t          **erase_xattr = NULL; -        int              need_unwind = 0;          local = frame->local;          sh = &local->self_heal; -        priv = this->private;          if (sh->entries_skipped) { -                need_unwind = 1;                  sh->op_failed = _gf_true;                  goto out;          } -        afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, sh->success, -                                 priv->child_count, AFR_ENTRY_TRANSACTION); - -        erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count, -                                 gf_afr_mt_dict_t); - -        for (i = 0; i < priv->child_count; i++) { -                if (sh->xattr[i]) { -                        call_count++; - -                        erase_xattr[i] = get_new_dict(); -                        dict_ref (erase_xattr[i]); -                } -        } - -        if (call_count == 0) -                need_unwind = 1; - -        afr_sh_delta_to_xattr (this, sh->delta_matrix, erase_xattr, -                               priv->child_count, AFR_ENTRY_TRANSACTION); - -        local->call_count = call_count; -        for (i = 0; i < priv->child_count; i++) { -                if (!erase_xattr[i]) -                        continue; - -                gf_log (this->name, GF_LOG_TRACE, -                        "erasing pending flags from %s on %s", -                        local->loc.path, priv->children[i]->name); - -                STACK_WIND_COOKIE (frame, afr_sh_entry_erase_pending_cbk, -                                   (void *) (long) i, -                                   priv->children[i], -                                   priv->children[i]->fops->xattrop, -                                   &local->loc, -                                   GF_XATTROP_ADD_ARRAY, erase_xattr[i], -                                   NULL); -                if (!--call_count) -                        break; -        } - -        for (i = 0; i < priv->child_count; i++) { -                if (erase_xattr[i]) { -                        dict_unref (erase_xattr[i]); -                } -        } -        GF_FREE (erase_xattr); - +        afr_sh_erase_pending (frame, this, AFR_ENTRY_TRANSACTION, +                              afr_sh_entry_erase_pending_cbk, +                              afr_sh_entry_finish); +        return 0;  out: -        if (need_unwind) -                afr_sh_entry_finish (frame, this); - +        afr_sh_entry_finish (frame, this);          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 1bb22a09b..147ab98d4 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -132,80 +132,13 @@ afr_sh_metadata_erase_pending_cbk (call_frame_t *frame, void *cookie,          return 0;  } -  int  afr_sh_metadata_erase_pending (call_frame_t *frame, xlator_t *this)  { -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        afr_private_t   *priv = NULL; -        int              call_count = 0; -        int              i = 0; -        dict_t          **erase_xattr = NULL; - - -        local = frame->local; -        sh = &local->self_heal; -        priv = this->private; - -        afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, -                                 sh->success, priv->child_count, -                                 AFR_METADATA_TRANSACTION); - -        erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count, -                                 gf_afr_mt_dict_t); -        if (!erase_xattr) -                return -ENOMEM; - -        for (i = 0; i < priv->child_count; i++) { -                if (sh->xattr[i]) { -                        call_count++; - -                        erase_xattr[i] = get_new_dict(); -                        dict_ref (erase_xattr[i]); -                } -        } - -        afr_sh_delta_to_xattr (this, sh->delta_matrix, erase_xattr, -                               priv->child_count, AFR_METADATA_TRANSACTION); - -        local->call_count = call_count; - -        if (call_count == 0) { -                gf_log (this->name, GF_LOG_INFO, -                        "metadata of %s not healed on any subvolume", -                        local->loc.path); - -                afr_sh_metadata_finish (frame, this); -        } - -        for (i = 0; i < priv->child_count; i++) { -                if (!erase_xattr[i]) -                        continue; - -                gf_log (this->name, GF_LOG_TRACE, -                        "erasing pending flags from %s on %s", -                        local->loc.path, priv->children[i]->name); - -                STACK_WIND_COOKIE (frame, afr_sh_metadata_erase_pending_cbk, -                                   (void *) (long) i, -                                   priv->children[i], -                                   priv->children[i]->fops->xattrop, -                                   &local->loc, -                                   GF_XATTROP_ADD_ARRAY, erase_xattr[i], -                                   NULL); -                if (!--call_count) -                        break; -        } - -        for (i = 0; i < priv->child_count; i++) { -                if (erase_xattr[i]) { -                        dict_unref (erase_xattr[i]); -                } -        } -        GF_FREE (erase_xattr); - -        return 0; +         afr_sh_erase_pending (frame, this, AFR_METADATA_TRANSACTION, +                               afr_sh_metadata_erase_pending_cbk, +                               afr_sh_metadata_finish); +         return 0;  }  | 
