diff options
| author | Pranith Kumar K <pranithk@gluster.com> | 2011-09-27 14:44:01 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2011-09-29 04:14:43 -0700 | 
| commit | fb648cf39c8715e5a25752defdfc95ec0ba04217 (patch) | |
| tree | 20fe412c9a9b20b4ab2fca157a735cf453acea53 /xlators | |
| parent | 09cfa5dffa79abd833354a26783db9edcfb69105 (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.c | 5 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 464 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.h | 19 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 546 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 49 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 169 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.h | 4 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 8 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/pump.c | 32 | 
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:  | 
