diff options
| author | Pranith Kumar K <pranithk@gluster.com> | 2011-09-27 14:44:01 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2011-10-19 03:17:17 -0700 | 
| commit | b80a2a150b874031df35af8d4f06657906024861 (patch) | |
| tree | 9205dd82c4614d14104cd27a2ac4ddde42a3d8bf | |
| parent | eab187ce06f6d72aeba297604e132d181da4c502 (diff) | |
cluster/afr: Handle files without gfid
Change-Id: Ie831ae8542c1382c17fb7837cd18b0e4e4d3db75
BUG: 3734
Reviewed-on: http://review.gluster.com/619
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 30 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 478 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.h | 27 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-data.c | 12 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 584 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 93 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 10 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/pump.c | 109 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/pump.h | 1 | 
9 files changed, 610 insertions, 734 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 69e980a03d5..bc8c828e55a 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -456,10 +456,14 @@ afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)          if (sh->child_success)                  GF_FREE (sh->child_success); +        if (sh->fresh_children) +                GF_FREE (sh->fresh_children);          if (sh->fresh_parent_dirs)                  GF_FREE (sh->fresh_parent_dirs);          loc_wipe (&sh->parent_loc); +        loc_wipe (&sh->lookup_loc); +  } @@ -980,12 +984,12 @@ afr_launch_self_heal (call_frame_t *frame, xlator_t *this,          afr_self_heal (frame, this, inode);  } -int +unsigned int  afr_gfid_missing_count (const char *xlator_name, int32_t *success_children,                          struct iatt *bufs, unsigned int child_count,                          const char *path)  { -        int             gfid_miss_count   = 0; +        unsigned int    gfid_miss_count   = 0;          int             i              = 0;          struct iatt     *child1        = NULL; @@ -1538,6 +1542,7 @@ afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)          int32_t           *child_success = NULL;          struct iatt       *iatts         = NULL;          int               i              = 0; +        int32_t           *sources         = NULL;          GF_ASSERT (local);          local->cont.lookup.xattrs = GF_CALLOC (child_count, @@ -1565,6 +1570,11 @@ afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)          local->cont.lookup.child_success = child_success; +        sources = GF_CALLOC (sizeof (*sources), child_count, gf_afr_mt_int32_t); +        if (NULL == sources) +                goto out; + +        local->cont.lookup.sources = sources;          ret = 0;  out:          return ret; @@ -3188,21 +3198,19 @@ afr_reset_children (int32_t *fresh_children, int32_t child_count)  }  int32_t* -afr_fresh_children_create (int32_t child_count) +afr_children_create (unsigned int child_count)  { -        int32_t           *fresh_children = NULL; +        int32_t           *children = NULL;          int               i               = 0; -        GF_ASSERT (child_count > 0); - -        fresh_children = GF_CALLOC (child_count, sizeof (*fresh_children), -                                    gf_afr_mt_int32_t); -        if (NULL == fresh_children) +        children = GF_CALLOC (child_count, sizeof (*children), +                              gf_afr_mt_int32_t); +        if (NULL == children)                  goto out;          for (i = 0; i < child_count; i++) -                fresh_children[i] = -1; +                children[i] = -1;  out: -        return fresh_children; +        return children;  }  void diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 568368b9ccd..b925b0adcef 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -970,12 +970,44 @@ afr_sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)          return 0;  } -static void +int +afr_sh_common_create (afr_self_heal_t *sh, unsigned int child_count) +{ +        int     ret = -ENOMEM; +        sh->buf = GF_CALLOC (child_count, sizeof (*sh->buf), +                             gf_afr_mt_iatt); +        if (!sh->buf) +                goto out; +        sh->parentbufs = GF_CALLOC (child_count, sizeof (*sh->parentbufs), +                                    gf_afr_mt_iatt); +        if (!sh->parentbufs) +                goto out; +        sh->child_errno = GF_CALLOC (child_count, sizeof (*sh->child_errno), +                                     gf_afr_mt_int); +        if (!sh->child_errno) +                goto out; +        sh->child_success = afr_children_create (child_count); +        if (!sh->child_success) +                goto out; +        sh->fresh_children = afr_children_create (child_count); +        if (!sh->fresh_children) +                goto out; +        sh->xattr = GF_CALLOC (child_count, sizeof (*sh->xattr), +                               gf_afr_mt_dict_t); +        if (!sh->xattr) +                goto out; +        ret = 0; +out: +        return ret; +} + +void  afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,                                     xlator_t *this,                                     int32_t op_ret, int32_t op_errno,                                     inode_t *inode, struct iatt *buf, -                                   dict_t *xattr, struct iatt *postparent) +                                   dict_t *xattr, struct iatt *postparent, +                                   loc_t *loc)  {          int              child_index = 0;          afr_local_t     *local = NULL; @@ -999,8 +1031,7 @@ afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,                  } else {                          gf_log (this->name, GF_LOG_ERROR,                                  "path %s on subvolume %s => -1 (%s)", -                                local->loc.path, -                                priv->children[child_index]->name, +                                loc->path, priv->children[child_index]->name,                                  strerror (op_errno));                          local->self_heal.child_errno[child_index] = op_errno;                  } @@ -1027,6 +1058,56 @@ afr_valid_ia_type (ia_type_t ia_type)          return _gf_false;  } +int +afr_impunge_frame_create (call_frame_t *frame, xlator_t *this, +                          int active_source, int ret_child, mode_t entry_mode, +                          call_frame_t **impunge_frame) +{ +        afr_local_t     *local         = NULL; +        afr_local_t     *impunge_local = NULL; +        afr_self_heal_t *sh            = NULL; +        afr_self_heal_t *impunge_sh    = NULL; +        int32_t         op_errno       = 0; +        afr_private_t   *priv          = NULL; +        int             ret            = 0; +        call_frame_t    *new_frame     = NULL; + +        op_errno = ENOMEM; +        priv = this->private; +        new_frame = copy_frame (frame); +        if (!new_frame) { +                goto out; +        } + +        ALLOC_OR_GOTO (impunge_local, afr_local_t, out); + +        local = frame->local; +        sh = &local->self_heal; +        new_frame->local = impunge_local; +        impunge_sh = &impunge_local->self_heal; +        impunge_sh->sh_frame = frame; +        impunge_sh->active_source = active_source; +        impunge_sh->impunge_ret_child = ret_child; +        impunge_sh->impunging_entry_mode = entry_mode; +        impunge_local->child_up  = memdup (local->child_up, +                                           sizeof (*local->child_up) * +                                           priv->child_count); +        if (!impunge_local->child_up) +                goto out; + +        ret = afr_sh_common_create (impunge_sh, priv->child_count); +        if (ret) { +                op_errno = -ret; +                goto out; +        } +        op_errno = 0; +        *impunge_frame = new_frame; +out: +        if (op_errno && new_frame) +                AFR_STACK_DESTROY (new_frame); +        return -op_errno; +} +  void  afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,                                      int child_index, struct iatt *buf, @@ -1037,26 +1118,17 @@ afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,          afr_local_t     *local = NULL;          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *sh = NULL; -        afr_self_heal_t *impunge_sh = NULL; -        int32_t         op_errno = 0; - -        impunge_frame = copy_frame (frame); -        if (!impunge_frame) { -                op_errno = ENOMEM; -                goto out; -        } - -        ALLOC_OR_GOTO (impunge_local, afr_local_t, out); +        int             ret = 0; +        mode_t          mode = 0;          local = frame->local; -        sh = &local->self_heal; -        impunge_frame->local = impunge_local; -        impunge_sh = &impunge_local->self_heal; -        impunge_sh->sh_frame = frame; -        impunge_sh->active_source = sh->source; -        impunge_sh->impunging_entry_mode = st_mode_from_ia (buf->ia_prot, -                                                            buf->ia_type); -        impunge_sh->impunge_ret_child = child_index; +        sh    = &local->self_heal; +        mode = st_mode_from_ia (buf->ia_prot, buf->ia_type); +        ret = afr_impunge_frame_create (frame, this, sh->source, child_index, +                                        mode, &impunge_frame); +        if (ret) +                goto out; +        impunge_local = impunge_frame->local;          loc_copy (&impunge_local->loc, &local->loc);          sh->impunge_done = impunge_done;          impunge_local->call_count = 1; @@ -1065,8 +1137,8 @@ afr_sh_call_entry_impunge_recreate (call_frame_t *frame, xlator_t *this,          return;  out:          gf_log (this->name, GF_LOG_ERROR, "impunge of %s failed, reason: %s", -                local->loc.path, strerror (op_errno)); -        impunge_done (frame, this, child_index, -1, op_errno); +                local->loc.path, strerror (-ret)); +        impunge_done (frame, this, child_index, -1, -ret);  }  int @@ -1143,12 +1215,12 @@ out:  }  void -afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this) +afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this, +                                    int32_t op_ret, int32_t op_errno)  {          afr_local_t     *local = NULL;          afr_self_heal_t *sh = NULL;          afr_private_t   *priv = NULL; -        int32_t         op_errno = 0;          ia_type_t       ia_type = IA_INVAL;          int32_t         nsources = 0; @@ -1156,23 +1228,10 @@ afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this)          sh = &local->self_heal;          priv = this->private; -        if (afr_get_children_count (sh->child_success, -                                    priv->child_count) == 0) { -                op_errno = afr_resultant_errno_get (NULL, sh->child_errno, -                                                    priv->child_count); -                goto out; -        } - -        if (afr_gfid_missing_count (this->name, sh->child_success, -                                    sh->buf, priv->child_count, -                                    local->loc.path) || -            afr_conflicting_iattrs (sh->buf, sh->child_success, -                                    priv->child_count, local->loc.path, -                                    this->name)) { -                //this can happen if finding the fresh parent dir failed -                local->govinda_gOvinda = 1; -                sh->op_failed = 1; -                op_errno = EIO; +        if (op_ret < 0) { +                if (op_errno == EIO) +                        local->govinda_gOvinda = 1; +                // EIO can happen if finding the fresh parent dir failed                  goto out;          } @@ -1204,22 +1263,22 @@ afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this)          sh_missing_entries_create (frame, this);          return;  out: +        sh->op_failed = 1;          afr_sh_set_error (sh, op_errno);          afr_sh_missing_entries_finish (frame, this);          return;  }  static int -afr_sh_missing_entries_lookup_cbk (call_frame_t *frame, void *cookie, -                                   xlator_t *this, int32_t op_ret, -                                   int32_t op_errno, inode_t *inode, -                                   struct iatt *buf, dict_t *xattr, -                                   struct iatt *postparent) +afr_sh_common_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                          int32_t op_ret, int32_t op_errno, inode_t *inode, +                          struct iatt *buf, dict_t *xattr, +                          struct iatt *postparent)  {          int                     call_count = 0;          afr_local_t             *local = NULL; -        afr_self_heal_t         *sh = NULL; -        afr_private_t           *priv = NULL; +        afr_self_heal_t         *sh    = NULL; +        afr_private_t           *priv  = NULL;          local = frame->local;          sh = &local->self_heal; @@ -1227,12 +1286,45 @@ afr_sh_missing_entries_lookup_cbk (call_frame_t *frame, void *cookie,          afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,                                             op_errno, inode, buf, xattr, -                                           postparent); +                                           postparent, &sh->lookup_loc);          call_count = afr_frame_return (frame); -        if (call_count == 0) -                afr_sh_missing_entries_lookup_done (frame, this); +        if (call_count) +                goto out; +        op_ret = -1; +        if (!sh->success_count) { +                op_errno = afr_resultant_errno_get (NULL, sh->child_errno, +                                                    priv->child_count); +                gf_log (this->name, GF_LOG_ERROR, "Failed to lookup %s, " +                        "reason %s", sh->lookup_loc.path, +                        strerror (op_errno)); +                goto done; +        } + +        if ((sh->lookup_flags & AFR_LOOKUP_FAIL_CONFLICTS) && +            (afr_conflicting_iattrs (sh->buf, sh->child_success, +                                     priv->child_count, +                                     sh->lookup_loc.path, this->name))) { +                op_errno = EIO; +                gf_log (this->name, GF_LOG_ERROR, "Conflicting entries " +                        "for %s", sh->lookup_loc.path); +                goto done; +        } +        if ((sh->lookup_flags & AFR_LOOKUP_FAIL_MISSING_GFIDS) && +            (afr_gfid_missing_count (this->name, sh->child_success, +                                     sh->buf, priv->child_count, +                                     sh->lookup_loc.path))) { +                op_errno = ENODATA; +                gf_log (this->name, GF_LOG_ERROR, "Missing Gfids " +                        "for %s", sh->lookup_loc.path); +                goto done; +        } +        op_ret = 0; + +done: +        sh->lookup_done (frame, this, op_ret, op_errno); +out:          return 0;  } @@ -1335,8 +1427,10 @@ afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)                                              sh->buf, priv->child_count,                                              local->loc.path)) {                          afr_sh_common_lookup (frame, this, &local->loc, -                                              afr_sh_missing_entries_lookup_cbk, -                                              _gf_true); +                                              afr_sh_missing_entries_lookup_done, +                                              sh->sh_gfid_req, +                                              AFR_LOOKUP_FAIL_CONFLICTS| +                                              AFR_LOOKUP_FAIL_MISSING_GFIDS);                  } else {                          //No need to set gfid so goto missing entries lookup done                          //Behave as if you have done the lookup @@ -1347,7 +1441,7 @@ afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)                          afr_children_copy (sh->child_success,                                             sh->fresh_children,                                             priv->child_count); -                        afr_sh_missing_entries_lookup_done (frame, this); +                        afr_sh_missing_entries_lookup_done (frame, this, 0, 0);                  }          }          return 0; @@ -1500,35 +1594,34 @@ afr_sh_save_child_iatts_from_policy (int32_t *children, struct iatt *bufs,  }  void -afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this) +afr_get_children_of_fresh_parent_dirs (afr_self_heal_t *sh, +                                       unsigned int child_count) +{ +        afr_children_intersection_get (sh->child_success, +                                       sh->fresh_parent_dirs, +                                       sh->sources, child_count); +        afr_get_fresh_children (sh->child_success, sh->sources, +                                sh->fresh_children, child_count); +        memset (sh->sources, 0, sizeof (*sh->sources) * child_count); +} + +void +afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this, +                             int32_t op_ret, int32_t op_errno)  {          afr_local_t      *local = NULL;          afr_self_heal_t  *sh = NULL;          afr_private_t    *priv = NULL;          int32_t          fresh_child_enoents = 0;          int32_t          fresh_parent_count = 0; -        int32_t          op_errno = 0;          local = frame->local;          sh = &local->self_heal;          priv = this->private; -        if (afr_get_children_count (sh->child_success, -                                    priv->child_count) == 0) { -                op_errno = afr_resultant_errno_get (NULL, sh->child_errno, -                                                    priv->child_count); +        if (op_ret < 0)                  goto fail; -        } - -        //make intersection of (success_children & fresh_parent_dirs) fresh_children -        //the other success_children will be added to it if they are not stale -        afr_children_intersection_get (sh->child_success, -                                       sh->fresh_parent_dirs, -                                       sh->sources, priv->child_count); -        afr_get_fresh_children (sh->child_success, sh->sources, -                                sh->fresh_children, priv->child_count); -        memset (sh->sources, 0, sizeof (*sh->sources) * priv->child_count); - +        afr_get_children_of_fresh_parent_dirs (sh, priv->child_count);          fresh_parent_count = afr_get_children_count (sh->fresh_parent_dirs,                                                       priv->child_count);          //we need the enoent count of the subvols present in fresh_parent_dirs @@ -1536,6 +1629,8 @@ afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this)                                                 sh->child_errno,                                                 priv->child_count, ENOENT);          if (fresh_child_enoents == fresh_parent_count) { +                gf_log (this->name, GF_LOG_INFO, "Deleting stale file %s", +                        local->loc.path);                  afr_sh_set_error (sh, ENOENT);                  sh->op_failed = 1;                  afr_sh_purge_entry (frame, this); @@ -1558,32 +1653,15 @@ afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this)          return;  fail: +        sh->op_failed = 1;          afr_sh_set_error (sh, op_errno);          afr_sh_missing_entries_finish (frame, this);          return;  } -static int -afr_sh_children_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                            int32_t op_ret, int32_t op_errno, inode_t *inode, -                            struct iatt *buf, dict_t *xattr, -                            struct iatt *postparent) -{ -        int              call_count = 0; - -        afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret, -                                           op_errno, inode, buf, xattr, -                                           postparent); -        call_count = afr_frame_return (frame); - -        if (call_count == 0) -                afr_sh_children_lookup_done (frame, this); - -        return 0; -} - -static int -afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this) +static void +afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this, +                           int32_t op_ret, int32_t op_errno)  {          afr_self_heal_t *sh  = NULL;          afr_private_t   *priv = NULL; @@ -1606,28 +1684,14 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)           * create so fail with EIO,           * If there are conflicting xattr fail with EIO.           */ -        if (afr_get_children_count (sh->child_success, -                                    priv->child_count) == 0) { -                gf_log (this->name, GF_LOG_ERROR, "Parent dir lookup failed " -                        "for %s, in missing entry self-heal, continuing with " -                        "the rest of the self-heals", local->loc.path); +        if (op_ret < 0)                  goto out; -        } -          enoent_count = afr_errno_count (NULL, sh->child_errno,                                          priv->child_count, ENOENT);          if (enoent_count > 0) { -                gf_log (this->name, GF_LOG_INFO, "Parent dir missing for %s," -                        " in missing entry self-heal, continuing with the rest" -                        " of the self-heals", local->loc.path); -                goto out; -        } - -        if (afr_conflicting_iattrs (sh->buf, sh->child_success, -                                    priv->child_count, sh->parent_loc.path, -                                    this->name)) { -                gf_log (this->name, GF_LOG_INFO, "conflicting stat info for " -                        "parent dirs of %s", local->loc.path); +                gf_log (this->name, GF_LOG_ERROR, "Parent dir missing for %s," +                        " in missing entry self-heal, aborting self-heal", +                        local->loc.path);                  goto out;          } @@ -1636,9 +1700,9 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)                                        sh->child_success,                                        AFR_ENTRY_TRANSACTION);          if (nsources < 0) { -                gf_log (this->name, GF_LOG_INFO, "No sources for dir of %s," -                        " in missing entry self-heal, continuing with the rest" -                        " of the self-heals", local->loc.path); +                gf_log (this->name, GF_LOG_ERROR, "No sources for dir of %s," +                        " in missing entry self-heal, aborting self-heal", +                        local->loc.path);                  goto out;          } @@ -1651,34 +1715,14 @@ afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this)          afr_get_fresh_children (sh->child_success, sh->sources,                                  sh->fresh_parent_dirs, priv->child_count);          afr_sh_common_lookup (frame, this, &local->loc, -                              afr_sh_children_lookup_cbk, _gf_false); -        return 0; +                              afr_sh_children_lookup_done, NULL, 0); +        return;  out:          afr_sh_set_error (sh, EIO);          sh->op_failed = 1;          afr_sh_missing_entries_finish (frame, this); -        return 0; -} - -int -afr_sh_conflicting_entry_lookup_cbk (call_frame_t *frame, void *cookie, -                                     xlator_t *this, -                                     int32_t op_ret, int32_t op_errno, -                                     inode_t *inode, struct iatt *buf, -                                     dict_t *xattr, struct iatt *postparent) -{ -        int              call_count = 0; - -        afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret, -                                           op_errno, inode, buf, xattr, -                                           postparent); -        call_count = afr_frame_return (frame); - -        if (call_count == 0) -                afr_sh_find_fresh_parents (frame, this); - -        return 0; +        return;  }  void @@ -1696,6 +1740,7 @@ afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)          afr_reset_children (sh->child_success, child_count);          afr_reset_children (sh->fresh_children, child_count);          afr_reset_xattr (sh->xattr, child_count); +        loc_wipe (&sh->lookup_loc);  }  /* afr self-heal state will be lost if this call is made @@ -1703,7 +1748,8 @@ afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)   */  int  afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, -                      afr_lookup_cbk_t lookup_cbk, gf_boolean_t set_gfid) +                      afr_lookup_done_cbk_t lookup_done , uuid_t gfid, +                      int32_t flags)  {          afr_local_t    *local = NULL;          int             i = 0; @@ -1725,16 +1771,19 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,          if (xattr_req) {                  afr_xattr_req_prepare (this, xattr_req, loc->path); -                if (set_gfid) { +                if (gfid) {                          gf_log (this->name, GF_LOG_DEBUG,                                  "looking up %s with gfid: %s", -                                local->loc.path, uuid_utoa (sh->sh_gfid_req)); -                        GF_ASSERT (!uuid_is_null (sh->sh_gfid_req)); -                        afr_set_dict_gfid (xattr_req, sh->sh_gfid_req); +                                loc->path, uuid_utoa (gfid)); +                        GF_ASSERT (!uuid_is_null (gfid)); +                        afr_set_dict_gfid (xattr_req, gfid);                  }          }          afr_sh_common_reset (sh, priv->child_count); +        sh->lookup_done = lookup_done; +        loc_copy (&sh->lookup_loc, loc); +        sh->lookup_flags = flags;          for (i = 0; i < priv->child_count; i++) {                  if (local->child_up[i]) {                          gf_log (this->name, GF_LOG_DEBUG, @@ -1742,7 +1791,7 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,                                  local->loc.path, priv->children[i]->name);                          STACK_WIND_COOKIE (frame, -                                           lookup_cbk, +                                           afr_sh_common_lookup_cbk,                                             (void *) (long) i,                                             priv->children[i],                                             priv->children[i]->fops->lookup, @@ -1781,8 +1830,8 @@ afr_sh_post_nb_entrylk_conflicting_sh_cbk (call_frame_t *frame, xlator_t *this)                  gf_log (this->name, GF_LOG_DEBUG,                          "Non blocking entrylks done. Proceeding to FOP");                  afr_sh_common_lookup (frame, this, &sh->parent_loc, -                                      afr_sh_conflicting_entry_lookup_cbk, -                                      _gf_false); +                                      afr_sh_find_fresh_parents, +                                      NULL, AFR_LOOKUP_FAIL_CONFLICTS);          }          return 0; @@ -1793,8 +1842,10 @@ afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)  {          afr_internal_lock_t *int_lock = NULL;          afr_local_t         *local    = NULL; +        afr_self_heal_t     *sh       = NULL;          local    = frame->local; +        sh       = &local->self_heal;          int_lock = &local->internal_lock;          if (int_lock->lock_op_ret < 0) { @@ -1805,8 +1856,9 @@ afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)                  gf_log (this->name, GF_LOG_DEBUG,                          "Non blocking entrylks done. Proceeding to FOP");                  afr_sh_common_lookup (frame, this, &local->loc, -                                      afr_sh_missing_entries_lookup_cbk, -                                      _gf_true); +                                      afr_sh_missing_entries_lookup_done, +                                      sh->sh_gfid_req, AFR_LOOKUP_FAIL_CONFLICTS| +                                      AFR_LOOKUP_FAIL_MISSING_GFIDS);          }          return 0; @@ -1982,8 +2034,6 @@ afr_self_heal_completion_cbk (call_frame_t *bgsh_frame, xlator_t *this)          afr_set_split_brain (this, sh->inode, split_brain); -        afr_self_heal_type_str_get(sh, sh_type_str, -                                   sizeof(sh_type_str));          afr_self_heal_type_str_get (sh, sh_type_str,                                      sizeof(sh_type_str));          if (sh->op_failed) { @@ -2020,32 +2070,19 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)          afr_self_heal_t *sh = NULL;          afr_private_t   *priv = NULL;          int              i = 0; +        int32_t          op_errno = 0; +        int              ret = 0; +        afr_self_heal_t *orig_sh = NULL;          call_frame_t *sh_frame = NULL;          afr_local_t  *sh_local = NULL;          local = frame->local; +        orig_sh = &local->self_heal;          priv  = this->private;          GF_ASSERT (local->loc.path); -        afr_set_lk_owner (frame, this); - -        if (local->self_heal.background) { -                LOCK (&priv->lock); -                { -                        if (priv->background_self_heals_started -                            < priv->background_self_heal_count) { -                                priv->background_self_heals_started++; - - -                        } else { -                                local->self_heal.background = _gf_false; -                        } -                } -                UNLOCK (&priv->lock); -        } -          gf_log (this->name, GF_LOG_TRACE,                  "performing self heal on %s (metadata=%d data=%d entry=%d)",                  local->loc.path, @@ -2053,9 +2090,16 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)                  local->self_heal.need_data_self_heal,                  local->self_heal.need_entry_self_heal); +        op_errno = ENOMEM;          sh_frame        = copy_frame (frame);          sh_frame->root->pid = SELF_HEAL_PID; +        if (!sh_frame) +                goto out; +        afr_set_lk_owner (sh_frame, this); +          sh_local        = afr_local_copy (local, this); +        if (!sh_local) +                goto out;          sh_frame->local = sh_local;          sh              = &sh_local->self_heal; @@ -2064,42 +2108,67 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)          sh->completion_cbk = afr_self_heal_completion_cbk; -        sh->buf = GF_CALLOC (priv->child_count, sizeof (struct iatt), -                             gf_afr_mt_iatt); -        sh->parentbufs = GF_CALLOC (priv->child_count, sizeof (struct iatt), -                                    gf_afr_mt_iatt); -        sh->child_errno = GF_CALLOC (priv->child_count, sizeof (int), -                                     gf_afr_mt_int); -        sh->success = GF_CALLOC (priv->child_count, sizeof (int), -                                 gf_afr_mt_int); -        sh->xattr = GF_CALLOC (priv->child_count, sizeof (dict_t *), -                               gf_afr_mt_dict_t); +        sh->success = GF_CALLOC (priv->child_count, sizeof (*sh->success), +                                 gf_afr_mt_char); +        if (!sh->success) +                goto out;          sh->sources = GF_CALLOC (sizeof (*sh->sources), priv->child_count,                                   gf_afr_mt_int); +        if (!sh->sources) +                goto out;          sh->locked_nodes = GF_CALLOC (sizeof (*sh->locked_nodes),                                        priv->child_count,                                        gf_afr_mt_int); +        if (!sh->locked_nodes) +                goto out;          sh->pending_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,                                          gf_afr_mt_int32_t); +        if (!sh->pending_matrix) +                goto out;          for (i = 0; i < priv->child_count; i++) {                  sh->pending_matrix[i] = GF_CALLOC (sizeof (int32_t),                                                     priv->child_count,                                                     gf_afr_mt_int32_t); +                if (!sh->pending_matrix[i]) +                        goto out;          }          sh->delta_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,                                        gf_afr_mt_int32_t); +        if (!sh->delta_matrix) +                goto out;          for (i = 0; i < priv->child_count; i++) {                  sh->delta_matrix[i] = GF_CALLOC (sizeof (int32_t),                                                   priv->child_count,                                                   gf_afr_mt_int32_t); +                if (!sh->delta_matrix) +                        goto out; +        } +        sh->fresh_parent_dirs = afr_children_create (priv->child_count); +        if (!sh->fresh_parent_dirs) +                goto out; +        ret = afr_sh_common_create (sh, priv->child_count); +        if (ret) { +                op_errno = -ret; +                goto out;          } -        sh->child_success = afr_fresh_children_create (priv->child_count); -        sh->fresh_children = afr_fresh_children_create (priv->child_count); -        sh->fresh_parent_dirs = afr_fresh_children_create (priv->child_count); +        if (local->self_heal.background) { +                LOCK (&priv->lock); +                { +                        if (priv->background_self_heals_started +                            < priv->background_self_heal_count) { +                                priv->background_self_heals_started++; + + +                        } else { +                                local->self_heal.background = _gf_false; +                        } +                } +                UNLOCK (&priv->lock); +        }          FRAME_SU_DO (sh_frame, afr_local_t);          if (sh->need_missing_entry_self_heal) { @@ -2114,7 +2183,12 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)                  afr_sh_missing_entries_done (sh_frame, this);          } +        op_errno = 0; +out: +        if (op_errno) { +                orig_sh->unwind (frame, this, -1, op_errno); +        }          return 0;  } @@ -2168,3 +2242,47 @@ afr_self_heal_type_for_transaction (afr_transaction_type type)          }          return sh_type;  } + +int +afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name) +{ +        int   ret = -1; + +        if (!child) { +                goto out; +        } + +        if (strcmp (parent->path, "/") == 0) +                ret = gf_asprintf ((char **)&child->path, "/%s", name); +        else +                ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path, +                                   name); + +        if (-1 == ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "asprintf failed while setting child path"); +        } + +        if (!child->path) { +                goto out; +        } + +        child->name = strrchr (child->path, '/'); +        if (child->name) +                child->name++; + +        child->parent = inode_ref (parent->inode); +        child->inode = inode_new (parent->inode->table); + +        if (!child->inode) { +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        if (ret == -1) +                loc_wipe (child); + +        return ret; +} diff --git a/xlators/cluster/afr/src/afr-self-heal-common.h b/xlators/cluster/afr/src/afr-self-heal-common.h index 043ebea2da6..7a06c2f4b13 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.h +++ b/xlators/cluster/afr/src/afr-self-heal-common.h @@ -29,11 +29,11 @@ typedef enum {          AFR_SELF_HEAL_INVALID = -1,  } afr_self_heal_type; -typedef int -(*afr_lookup_cbk_t) (call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, inode_t *inode, -                     struct iatt *buf, dict_t *xattr, -                     struct iatt *postparent); +typedef enum { +        AFR_LOOKUP_FAIL_CONFLICTS = 1, +        AFR_LOOKUP_FAIL_MISSING_GFIDS = 2, +} afr_lookup_flags_t; +  int  afr_sh_select_source (int sources[], int child_count); @@ -84,7 +84,8 @@ void  afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count);  int  afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, -                      afr_lookup_cbk_t lookup_cbk, gf_boolean_t set_gfid); +                      afr_lookup_done_cbk_t lookup_cbk, uuid_t uuid, +                      int32_t flags);  int  afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,                               int active_src, struct iatt *buf); @@ -95,4 +96,18 @@ int  afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,                               int child_index, struct iatt *buf,                               struct iatt *postparent); +afr_local_t * +afr_local_copy (afr_local_t *l, xlator_t *this); +void +afr_sh_set_error (afr_self_heal_t *sh, int32_t op_errno); +typedef int +(*afr_fxattrop_cbk_t) (call_frame_t *frame, void *cookie, +                       xlator_t *this, int32_t op_ret, int32_t op_errno, +                       dict_t *xattr); +int +afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name); +int +afr_impunge_frame_create (call_frame_t *frame, xlator_t *this, +                          int active_source, int ret_child, mode_t entry_mode, +                          call_frame_t **impunge_frame);  #endif /* __AFR_SELF_HEAL_COMMON_H__ */ diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 6ce7106698d..11d6745b446 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -812,11 +812,8 @@ afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,          if (NULL == pending_matrix)                  goto out; -        sources = GF_CALLOC (sizeof (*sources), priv->child_count, -                             gf_afr_mt_int32_t); -        if (NULL == sources) -                goto out; - +        sources = local->cont.lookup.sources; +        memset (sources, 0, sizeof (*sources) * priv->child_count);          afr_build_pending_matrix (priv->pending_key, pending_matrix,                                    xattr, txn_type, priv->child_count); @@ -840,13 +837,8 @@ afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,                                                          config_read_child,                                                          valid_children);          ret = 0; -        local->cont.lookup.sources = sources;  out:          afr_destroy_pending_matrix (pending_matrix, priv->child_count); -        if (-1 == ret) { -                if (sources) -                        GF_FREE (sources); -        }          gf_log (this->name, GF_LOG_DEBUG, "returning read_child: %d", read_child);          return read_child;  } diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 3977ae101f6..e32b507631a 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -49,6 +49,15 @@  #include "afr-self-heal.h"  #include "afr-self-heal-common.h" +#define AFR_INIT_SH_FRAME_VALS(_frame, _local, _sh, _sh_frame, _sh_local, _sh_sh)\ +        do {\ +                _local = _frame->local;\ +                _sh = &_local->self_heal;\ +                _sh_frame = _sh->sh_frame;\ +                _sh_local = _sh_frame->local;\ +                _sh_sh    = &_sh_local->self_heal;\ +        } while (0); +  int  afr_sh_entry_done (call_frame_t *frame, xlator_t *this)  { @@ -298,51 +307,6 @@ next_active_sink (call_frame_t *frame, xlator_t *this,          return next_active_sink;  } - -int -build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name) -{ -        int   ret = -1; - -        if (!child) { -                goto out; -        } - -        if (strcmp (parent->path, "/") == 0) -                ret = gf_asprintf ((char **)&child->path, "/%s", name); -        else -                ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path, -                                   name); - -        if (-1 == ret) { -                gf_log (this->name, GF_LOG_ERROR, -                        "asprintf failed while setting child path"); -        } - -        if (!child->path) { -                goto out; -        } - -        child->name = strrchr (child->path, '/'); -        if (child->name) -                child->name++; - -        child->parent = inode_ref (parent->inode); -        child->inode = inode_new (parent->inode->table); - -        if (!child->inode) { -                goto out; -        } - -        ret = 0; -out: -        if (ret == -1) -                loc_wipe (child); - -        return ret; -} - -  int  afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this); @@ -759,7 +723,7 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,          expunge_sh->active_source = active_src;          expunge_sh->entrybuf = entry->d_stat; -        ret = build_child_loc (this, &expunge_local->loc, &local->loc, name); +        ret = afr_build_child_loc (this, &expunge_local->loc, &local->loc, name);          if (ret != 0) {                  op_errno = EINVAL;                  goto out; @@ -916,15 +880,47 @@ afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this,                                   int32_t op_errno)  {          int              call_count = 0; +        afr_local_t      *local = NULL; +        afr_self_heal_t  *sh = NULL; +        local = frame->local; +        sh = &local->self_heal;          call_count = afr_frame_return (frame); +        if (op_ret == -1) +                sh->op_failed = 1; -        if (call_count == 0) +        if (call_count == 0) { +                if (sh->op_failed) { +                        afr_sh_entry_finish (frame, this); +                        goto out; +                }                  afr_sh_entry_impunge_subvol (frame, this, active_src); - +        } +out:          return 0;  } +void +afr_sh_entry_call_impunge_done (call_frame_t *impunge_frame, xlator_t *this, +                                int32_t op_ret, int32_t op_errno) +{ +        afr_local_t     *impunge_local = NULL; +        afr_local_t     *local = NULL; +        afr_self_heal_t *sh = NULL; +        afr_self_heal_t *impunge_sh = NULL; +        call_frame_t    *frame = NULL; +        int32_t          impunge_ret_child = 0; +        afr_private_t   *priv = NULL; + +        priv = this->private; +        AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, +                                frame, local, sh); + +        impunge_ret_child = impunge_sh->impunge_ret_child; +        AFR_STACK_DESTROY (impunge_frame); +        sh->impunge_done (frame, this, impunge_ret_child, op_ret, +                          op_errno); +}  int  afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie, @@ -935,21 +931,12 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,          int              call_count = 0;          afr_private_t   *priv = NULL;          afr_local_t     *impunge_local = NULL; -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL;          afr_self_heal_t *impunge_sh = NULL; -        call_frame_t    *frame = NULL; -        int              active_src = 0;          int              child_index = 0; -        int32_t          impunge_ret_child = 0;          priv = this->private;          impunge_local = impunge_frame->local;          impunge_sh = &impunge_local->self_heal; -        frame = impunge_sh->sh_frame; -        local = frame->local; -        sh    = &local->self_heal; -        active_src = impunge_sh->active_source;          child_index = (long) cookie;          if (op_ret == 0) { @@ -971,12 +958,9 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,          }          UNLOCK (&impunge_frame->lock); -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); -        } +        if (call_count == 0) +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                op_ret, op_errno);          return 0;  } @@ -1059,7 +1043,6 @@ afr_sh_entry_impunge_parent_setattr_cbk (call_frame_t *setattr_frame,          return 0;  } -  int  afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,                                    xlator_t *this, @@ -1072,27 +1055,20 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,          afr_private_t   *priv             = NULL;          afr_local_t     *impunge_local    = NULL;          afr_self_heal_t *impunge_sh       = NULL; -        call_frame_t    *frame            = NULL;          int              active_src       = 0;          int              child_index      = 0;          int32_t         *pending_array    = NULL;          dict_t          *xattr            = NULL;          int              ret              = 0;          int              idx              = 0; -        afr_local_t     *local            = NULL; -        afr_self_heal_t *sh               = NULL;          call_frame_t    *setattr_frame    = NULL;          int32_t          valid            = 0;          loc_t           *parent_loc       = NULL;          struct iatt      parentbuf        = {0,}; -        int32_t          impunge_ret_child = 0;          priv = this->private;          impunge_local = impunge_frame->local;          impunge_sh = &impunge_local->self_heal; -        frame = impunge_sh->sh_frame; -        local = frame->local; -        sh    = &local->self_heal;          active_src = impunge_sh->active_source;          child_index = (long) cookie; @@ -1110,7 +1086,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,          xattr = dict_new ();          if (!xattr) { -                sh->op_failed = 1;                  gf_log (this->name, GF_LOG_ERROR, "Out of memory");                  goto out;          } @@ -1119,7 +1094,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,                                          gf_common_mt_int32_t);          if (!pending_array) { -                sh->op_failed = 1;                  gf_log (this->name, GF_LOG_ERROR, "Out of memory");                  goto out;          } @@ -1147,7 +1121,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,          parent_loc = GF_CALLOC (1, sizeof (*parent_loc),                                  gf_afr_mt_loc_t);          if (!parent_loc) { -                sh->op_failed = 1;                  gf_log (this->name, GF_LOG_ERROR, "Out of memory");                  goto out;          } @@ -1182,12 +1155,9 @@ out:          }          UNLOCK (&impunge_frame->lock); -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, -1, -                                  op_errno); -        } +        if (call_count == 0) +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                -1, op_errno);          return 0;  } @@ -1214,6 +1184,7 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,          if (!dict)                  gf_log (this->name, GF_LOG_ERROR, "Out of memory"); +        GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));          ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);          if (ret)                  gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed", @@ -1256,6 +1227,7 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this,                  return 0;          } +        GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));          ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);          if (ret)                  gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed", @@ -1290,32 +1262,22 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this,          dict_t          *dict          = NULL;          struct iatt     *buf           = NULL;          int              ret           = 0; -        call_frame_t    *frame         = NULL; -        afr_local_t     *local         = NULL; -        afr_self_heal_t *sh            = NULL;          afr_self_heal_t *impunge_sh    = NULL; -        int32_t          impunge_ret_child = 0;          priv = this->private;          impunge_local = impunge_frame->local;          impunge_sh    = &impunge_local->self_heal; -        frame         = impunge_sh->sh_frame; -        local         = frame->local; -        sh            = &local->self_heal;          buf = &impunge_local->cont.symlink.buf;          dict = dict_new ();          if (!dict) { -                gf_log (this->name, GF_LOG_ERROR, -                        "Out of memory"); -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (impunge_frame, this, impunge_ret_child, -1, -                                  ENOMEM); +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                -1, ENOMEM);                  goto out;          } +        GF_ASSERT (!uuid_is_null (buf->ia_gfid));          ret = afr_set_dict_gfid (dict, buf->ia_gfid);          if (ret)                  gf_log (this->name, GF_LOG_INFO, @@ -1351,20 +1313,11 @@ afr_sh_entry_impunge_symlink_unlink_cbk (call_frame_t *impunge_frame,          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *impunge_sh = NULL;          int              child_index = -1; -        call_frame_t    *frame = NULL;          int              call_count = -1; -        int              active_src = -1; -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        int32_t          impunge_ret_child = 0;          priv          = this->private;          impunge_local = impunge_frame->local;          impunge_sh    = &impunge_local->self_heal; -        frame         = impunge_sh->sh_frame; -        local         = frame->local; -        sh            = &local->self_heal; -        active_src    = impunge_sh->active_source;          child_index = (long) cookie; @@ -1388,12 +1341,9 @@ out:          }          UNLOCK (&impunge_frame->lock); -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); -        } +        if (call_count == 0) +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                op_ret, op_errno);          return 0;  } @@ -1434,19 +1384,12 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *impunge_sh = NULL;          int              child_index = -1; -        call_frame_t    *frame = NULL;          int              call_count = -1;          int              active_src = -1; -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        int32_t          impunge_ret_child = 0;          priv          = this->private;          impunge_local = impunge_frame->local;          impunge_sh    = &impunge_local->self_heal; -        frame         = impunge_sh->sh_frame; -        local         = frame->local; -        sh            = &local->self_heal;          active_src    = impunge_sh->active_source;          child_index = (long) cookie; @@ -1491,12 +1434,9 @@ out:          }          UNLOCK (&impunge_frame->lock); -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); -        } +        if (call_count == 0) +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                op_ret, op_errno);          return 0;  } @@ -1536,19 +1476,12 @@ afr_sh_entry_impunge_readlink_cbk (call_frame_t *impunge_frame, void *cookie,          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *impunge_sh = NULL;          int              child_index = -1; -        call_frame_t    *frame = NULL;          int              call_count = -1;          int              active_src = -1; -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        int32_t          impunge_ret_child = 0;          priv = this->private;          impunge_local = impunge_frame->local;          impunge_sh = &impunge_local->self_heal; -        frame = impunge_sh->sh_frame; -        local         = frame->local; -        sh            = &local->self_heal;          active_src = impunge_sh->active_source;          child_index = (long) cookie; @@ -1574,12 +1507,9 @@ out:          }          UNLOCK (&impunge_frame->lock); -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); -        } +        if (call_count == 0) +                afr_sh_entry_call_impunge_done (impunge_frame, this, +                                                op_ret, op_errno);          return 0;  } @@ -1659,177 +1589,162 @@ afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,          return ret;  } -int -afr_sh_entry_impunge_recreate_lookup_cbk (call_frame_t *impunge_frame, -                                          void *cookie, xlator_t *this, -                                          int32_t op_ret, int32_t op_errno, -                                          inode_t *inode, struct iatt *buf, -                                          dict_t *xattr,struct iatt *postparent) +gf_boolean_t +afr_sh_need_recreate (afr_self_heal_t *impunge_sh, int *sources, +                      unsigned int child, unsigned int child_count)  { -        afr_private_t   *priv = NULL; -        afr_local_t     *impunge_local = NULL; -        afr_local_t     *local = NULL; -        afr_self_heal_t *impunge_sh = NULL; -        afr_self_heal_t *sh = NULL; -        int              active_src = 0; -        int              child_index = 0; -        call_frame_t    *frame = NULL; -        int              call_count = 0; -        int              ret = 0; -        int32_t          impunge_ret_child = 0; +        int32_t         *success_children = NULL; +        gf_boolean_t    recreate = _gf_false; -        priv = this->private; -        impunge_local = impunge_frame->local; -        impunge_sh = &impunge_local->self_heal; -        frame = impunge_sh->sh_frame; -        local = frame->local; -        sh    = &local->self_heal; +        GF_ASSERT (impunge_sh->impunging_entry_mode); +        GF_ASSERT (impunge_sh->child_errno); +        GF_ASSERT (sources); -        child_index = (long) cookie; - -        active_src = impunge_sh->active_source; - -        if (op_ret != 0) { -                gf_log (this->name, GF_LOG_DEBUG, -                        "looking up %s on %s (for %s) failed (%s)", -                        impunge_local->loc.path, -                        priv->children[active_src]->name, -                        priv->children[child_index]->name, -                        strerror (op_errno)); +        success_children = impunge_sh->child_success; +        if (sources[child] || (child == impunge_sh->active_source)) { +                GF_ASSERT (afr_is_child_present (success_children, +                                                 child_count, child));                  goto out;          } -        ret = afr_sh_entry_impunge_create (impunge_frame, this, child_index, buf, -                                           postparent); -        if (ret) +        if (IA_ISLNK (impunge_sh->impunging_entry_mode)) { +                recreate = _gf_true;                  goto out; +        } -        return 0; - +        if (impunge_sh->child_errno[child] == ENOENT) +                recreate = _gf_true;  out: -        LOCK (&impunge_frame->lock); -        { -                call_count = --impunge_local->call_count; -        } -        UNLOCK (&impunge_frame->lock); +        return recreate; +} -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); +unsigned int +afr_sh_recreate_count (afr_self_heal_t *impunge_sh, int *sources, +                       unsigned int child_count) +{ +        int             count = 0; +        int             i = 0; + +        for (i = 0; i < child_count; i++) { +                if (afr_sh_need_recreate (impunge_sh, sources, i, child_count)) +                        count++;          } -        return 0; +        return count;  } -  int -afr_sh_entry_impunge_recreate (call_frame_t *impunge_frame, xlator_t *this, -                               int child_index) +afr_sh_entry_call_impunge_recreate (call_frame_t *impunge_frame, +                                    xlator_t *this)  {          afr_private_t   *priv = NULL;          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *impunge_sh = NULL; +        call_frame_t    *frame = NULL; +        afr_local_t     *local = NULL; +        afr_self_heal_t *sh = NULL; +        struct iatt     *buf = NULL; +        struct iatt     *postparent = NULL; +        unsigned int     recreate_count = 0; +        int              i = 0;          int              active_src = 0; +        priv          = this->private; +        AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, +                                frame, local, sh); +        active_src    = impunge_sh->active_source; +        buf           = &impunge_sh->buf[active_src]; +        postparent    = &impunge_sh->parentbufs[active_src]; -        priv = this->private; -        impunge_local = impunge_frame->local; -        impunge_sh = &impunge_local->self_heal; - -        active_src = impunge_sh->active_source; - -        STACK_WIND_COOKIE (impunge_frame, -                           afr_sh_entry_impunge_recreate_lookup_cbk, -                           (void *) (long) child_index, -                           priv->children[active_src], -                           priv->children[active_src]->fops->lookup, -                           &impunge_local->loc, 0); - +        recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources, +                                                priv->child_count); +        GF_ASSERT (recreate_count); +        impunge_local->call_count = recreate_count; +        for (i = 0; i < priv->child_count; i++) { +                if (afr_sh_need_recreate (impunge_sh, sh->sources, i, +                                          priv->child_count)) { +                        (void)afr_sh_entry_impunge_create (impunge_frame, this, +                                                           i, buf, +                                                           postparent); +                        recreate_count--; +                } +        } +        GF_ASSERT (!recreate_count);          return 0;  } - -int -afr_sh_entry_impunge_entry_cbk (call_frame_t *impunge_frame, void *cookie, -                                xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *buf, dict_t *x, -                                struct iatt *postparent) +void +afr_sh_entry_common_lookup_done (call_frame_t *impunge_frame, xlator_t *this, +                                 int32_t op_ret, int32_t op_errno)  {          afr_private_t   *priv = NULL;          afr_local_t     *impunge_local = NULL;          afr_self_heal_t *impunge_sh = NULL; -        int              call_count = 0; -        int              child_index = 0;          call_frame_t    *frame = NULL;          int              active_src = 0;          afr_local_t     *local = NULL;          afr_self_heal_t *sh = NULL; -        int32_t          impunge_ret_child = 0; - -        priv = this->private; -        impunge_local = impunge_frame->local; -        impunge_sh = &impunge_local->self_heal; -        frame = impunge_sh->sh_frame; -        local         = frame->local; -        sh            = &local->self_heal; -        child_index = (long) cookie; -        active_src = impunge_sh->active_source; - -        if ((op_ret == -1 && op_errno == ENOENT) -            || (IA_ISLNK (impunge_sh->impunging_entry_mode))) { +        unsigned int     recreate_count = 0; +        unsigned int     gfid_miss_count = 0; +        unsigned int     children_up_count = 0; +        uuid_t           gfid = {0}; -                /* -                 * A symlink's target might have changed, so -                 * always go down the recreate path for them. -                 */ - -                /* decrease call_count in recreate-callback */ - -                gf_log (this->name, GF_LOG_TRACE, -                        "missing entry %s on %s", -                        impunge_local->loc.path, -                        priv->children[child_index]->name); - -                afr_sh_entry_impunge_recreate (impunge_frame, this, -                                               child_index); -                return 0; -        } - -        if (op_ret == 0) { -                gf_log (this->name, GF_LOG_TRACE, -                        "%s exists under %s", -                        impunge_local->loc.path, -                        priv->children[child_index]->name); +        priv          = this->private; +        AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, +                                frame, local, sh); +        active_src    = impunge_sh->active_source; -                impunge_sh->parentbuf = *postparent; +        if (op_ret < 0) +                goto done; +        if (impunge_sh->child_errno[active_src]) { +                op_ret = -1; +                op_errno = impunge_sh->child_errno[active_src]; +                goto done; +        } + +        gfid_miss_count = afr_gfid_missing_count (this->name, +                                                  impunge_sh->child_success, +                                                  impunge_sh->buf, priv->child_count, +                                                  impunge_local->loc.path); +        children_up_count = afr_up_children_count (priv->child_count, +                                                   impunge_local->child_up); +        if ((gfid_miss_count == children_up_count) && +            (children_up_count < priv->child_count)) { +                op_ret = -1; +                op_errno = ENODATA; +                gf_log (this->name, GF_LOG_ERROR, "Not all children are up, " +                        "gfid should not be assigned in this state for %s", +                        impunge_local->loc.path); +                goto done; +        } + +        if (gfid_miss_count) { +                afr_update_gfid_from_iatts (gfid, impunge_sh->buf, +                                            impunge_sh->child_success, +                                            priv->child_count); +                if (uuid_is_null (gfid)) +                        uuid_generate (gfid); +                afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc, +                                      afr_sh_entry_common_lookup_done, gfid, +                                      AFR_LOOKUP_FAIL_CONFLICTS | +                                      AFR_LOOKUP_FAIL_MISSING_GFIDS);          } else { -                gf_log (this->name, GF_LOG_WARNING, -                        "looking up %s under %s failed (%s)", -                        impunge_local->loc.path, -                        priv->children[child_index]->name, -                        strerror (op_errno)); -        } - -        LOCK (&impunge_frame->lock); -        { -                call_count = --impunge_local->call_count; -        } -        UNLOCK (&impunge_frame->lock); - -        if (call_count == 0) { -                impunge_ret_child = impunge_sh->impunge_ret_child; -                AFR_STACK_DESTROY (impunge_frame); -                sh->impunge_done (frame, this, impunge_ret_child, op_ret, -                                  op_errno); +                recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources, +                                                        priv->child_count); +                if (!recreate_count) { +                        op_ret = 0; +                        op_errno = 0; +                        goto done; +                } +                afr_sh_entry_call_impunge_recreate (impunge_frame, this);          } - -        return 0; +        return; +done: +        afr_sh_entry_call_impunge_done (impunge_frame, this, +                                        op_ret, op_errno); +        return;  } -  int  afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,                              gf_dirent_t *entry) @@ -1840,12 +1755,10 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,          int              ret = -1;          call_frame_t    *impunge_frame = NULL;          afr_local_t     *impunge_local = NULL; -        afr_self_heal_t *impunge_sh = NULL;          int              active_src = 0; -        int              i = 0; -        int              call_count = 0;          int              op_errno = 0;          int              op_ret = -1; +        mode_t           entry_mode = 0;          priv = this->private;          local = frame->local; @@ -1870,70 +1783,34 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,                  "inspecting existance of %s under %s",                  entry->d_name, local->loc.path); -        impunge_frame = copy_frame (frame); -        if (!impunge_frame) { -                gf_log (this->name, GF_LOG_ERROR, -                        "Out of memory."); -                op_errno = ENOMEM; +        entry_mode = st_mode_from_ia (entry->d_stat.ia_prot, +                                      entry->d_stat.ia_type); +        ret = afr_impunge_frame_create (frame, this, active_src, active_src, +                                        entry_mode, &impunge_frame); +        if (ret) { +                op_errno = -ret;                  goto out;          } -        ALLOC_OR_GOTO (impunge_local, afr_local_t, out); - -        impunge_frame->local = impunge_local; -        impunge_sh = &impunge_local->self_heal; -        impunge_sh->sh_frame = frame; -        impunge_sh->active_source = active_src; -        impunge_sh->impunge_ret_child = active_src; - -        impunge_sh->impunging_entry_mode = -                st_mode_from_ia (entry->d_stat.ia_prot, entry->d_stat.ia_type); - -        ret = build_child_loc (this, &impunge_local->loc, &local->loc, entry->d_name); +        impunge_local = impunge_frame->local; +        ret = afr_build_child_loc (this, &impunge_local->loc, &local->loc, +                                   entry->d_name);          if (ret != 0) {                  op_errno = ENOMEM;                  goto out;          } -        for (i = 0; i < priv->child_count; i++) { -                if (i == active_src) -                        continue; -                if (local->child_up[i] == 0) -                        continue; -                if (sh->sources[i] == 1) -                        continue; -                call_count++; -        } +        afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc, +                              afr_sh_entry_common_lookup_done, NULL, +                              AFR_LOOKUP_FAIL_CONFLICTS); -        impunge_local->call_count = call_count; - -        for (i = 0; i < priv->child_count; i++) { -                if (i == active_src) -                        continue; -                if (local->child_up[i] == 0) -                        continue; -                if (sh->sources[i] == 1) -                        continue; - -                gf_log (this->name, GF_LOG_TRACE, -                        "looking up %s on %s", impunge_local->loc.path, -                        priv->children[i]->name); - -                STACK_WIND_COOKIE (impunge_frame, -                                   afr_sh_entry_impunge_entry_cbk, -                                   (void *) (long) i, -                                   priv->children[i], -                                   priv->children[i]->fops->lookup, -                                   &impunge_local->loc, 0); - -                if (!--call_count) -                        break; -        } - -        ret = 0; +        op_ret = 0;  out: -        if (ret == -1) +        if (ret) { +                if (impunge_frame) +                        AFR_STACK_DESTROY (impunge_frame);                  sh->impunge_done (frame, this, active_src, op_ret, op_errno); +        }          return 0;  } @@ -2194,7 +2071,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)          priv = this->private;          source = sh->source; -          for (i = 0; i < priv->child_count; i++) {                  if (sh->sources[i] == 0 && local->child_up[i] == 1) {                          active_sinks++; @@ -2204,6 +2080,7 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)          if (source != -1)                  sh->success[source] = 1; +        sh->active_sinks = active_sinks;          if (active_sinks == 0) {                  gf_log (this->name, GF_LOG_TRACE,                          "no active sinks for self-heal on dir %s", @@ -2218,7 +2095,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)                  afr_sh_entry_finish (frame, this);                  return 0;          } -        sh->active_sinks = active_sinks;          if (source != -1)                  gf_log (this->name, GF_LOG_DEBUG, @@ -2238,8 +2114,9 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)  } -int -afr_sh_entry_fix (call_frame_t *frame, xlator_t *this) +void +afr_sh_entry_fix (call_frame_t *frame, xlator_t *this, +                  int32_t op_ret, int32_t op_errno)  {          afr_local_t     *local = NULL;          afr_self_heal_t *sh = NULL; @@ -2252,6 +2129,13 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)          sh = &local->self_heal;          priv = this->private; +        if (op_ret < 0) { +                sh->op_failed = 1; +                afr_sh_set_error (sh, op_errno); +                afr_sh_entry_finish (frame, this); +                goto out; +        } +          if (sh->forced_merge) {                  sh->source = -1;                  goto heal; @@ -2273,54 +2157,18 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)                          local->loc.path);                  afr_sh_entry_finish (frame, this); -                return 0; +                return;          }          source = afr_sh_select_source (sh->sources, priv->child_count);          sh->source = source; +  heal:          afr_sh_entry_sync_prepare (frame, this); - -        return 0; -} - - - -int -afr_sh_entry_lookup_cbk (call_frame_t *frame, void *cookie, -                         xlator_t *this, int32_t op_ret, int32_t op_errno, -                         inode_t *inode, struct iatt *buf, dict_t *xattr, -                         struct iatt *postparent) -{ -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; - -        int call_count  = -1; -        int child_index = (long) cookie; - -        local = frame->local; -        sh = &local->self_heal; - -        LOCK (&frame->lock); -        { -                if (op_ret != -1) { -                        sh->xattr[child_index] = dict_ref (xattr); -                        sh->buf[child_index] = *buf; -                        sh->child_success[sh->success_count] = child_index; -                        sh->success_count++; -                } -        } -        UNLOCK (&frame->lock); - -        call_count = afr_frame_return (frame); - -        if (call_count == 0) { -                afr_sh_entry_fix (frame, this); -        } - -        return 0; +out: +        return;  }  int @@ -2344,7 +2192,9 @@ afr_sh_post_nonblocking_entry_cbk (call_frame_t *frame, xlator_t *this)                  gf_log (this->name, GF_LOG_DEBUG, "Non Blocking entrylks done "                          "for %s. Proceeding to FOP", local->loc.path);                  afr_sh_common_lookup (frame, this, &local->loc, -                                      afr_sh_entry_lookup_cbk, _gf_false); +                                      afr_sh_entry_fix, NULL, +                                      AFR_LOOKUP_FAIL_CONFLICTS | +                                      AFR_LOOKUP_FAIL_MISSING_GFIDS);          }          return 0; diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index 03b91dae300..af2f76d94f9 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -461,8 +461,9 @@ afr_sh_metadata_sync_prepare (call_frame_t *frame, xlator_t *this)  } -int -afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this) +void +afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this, +                     int32_t op_ret, int32_t op_errno)  {          afr_local_t     *local = NULL;          afr_self_heal_t *sh = NULL; @@ -475,23 +476,23 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)          sh = &local->self_heal;          priv = this->private; -        afr_build_pending_matrix (priv->pending_key, sh->pending_matrix, -                                  sh->xattr, AFR_METADATA_TRANSACTION, -                                  priv->child_count); - -        afr_sh_print_pending_matrix (sh->pending_matrix, this); - -        nsources = afr_mark_sources (sh->sources, sh->pending_matrix, sh->buf, -                                     priv->child_count, AFR_SELF_HEAL_METADATA, -                                     sh->child_success, this->name); - +        if (op_ret < 0) { +                sh->op_failed = 1; +                afr_sh_set_error (sh, op_errno); +                afr_sh_metadata_finish (frame, this); +                goto out; +        } +        nsources = afr_build_sources (this, sh->xattr, sh->buf, +                                      sh->pending_matrix, sh->sources, +                                      sh->child_success, +                                      AFR_METADATA_TRANSACTION);          if (nsources == 0) {                  gf_log (this->name, GF_LOG_TRACE,                          "No self-heal needed for %s",                          local->loc.path);                  afr_sh_metadata_finish (frame, this); -                return 0; +                goto out;          }          if ((nsources == -1) @@ -518,7 +519,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)                  local->govinda_gOvinda = 1;                  afr_sh_metadata_finish (frame, this); -                return 0; +                goto out;          }          source = afr_sh_select_source (sh->sources, priv->child_count); @@ -528,7 +529,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)                          "No active sources found.");                  afr_sh_metadata_finish (frame, this); -                return 0; +                goto out;          }          sh->source = source; @@ -546,62 +547,8 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)          }          afr_sh_metadata_sync_prepare (frame, this); - -        return 0; -} - - -int -afr_sh_metadata_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                            int32_t op_ret, int32_t op_errno, -                            inode_t *inode, struct iatt *buf, dict_t *xattr, -                            struct iatt *postparent) -{ -        afr_local_t     *local = NULL; -        afr_self_heal_t *sh = NULL; -        afr_private_t   *priv = NULL; -        int              call_count = 0; -        int              child_index = 0; - - -        local = frame->local; -        sh = &local->self_heal; -        priv = this->private; - -        child_index = (long) cookie; - -        LOCK (&frame->lock); -        { -                if (op_ret == 0) { -                        gf_log (this->name, GF_LOG_TRACE, -                                "path %s on subvolume %s is of mode 0%o", -                                local->loc.path, -                                priv->children[child_index]->name, -                                buf->ia_type); - -                        sh->buf[child_index] = *buf; -                        if (xattr) -                                sh->xattr[child_index] = dict_ref (xattr); -                        sh->child_success[sh->success_count] = child_index; -                        sh->success_count++; -                } else { -                        gf_log (this->name, GF_LOG_INFO, -                                "path %s on subvolume %s => -1 (%s)", -                                local->loc.path, -                                priv->children[child_index]->name, -                                strerror (op_errno)); - -                        sh->child_errno[child_index] = op_errno; -                } -        } -        UNLOCK (&frame->lock); - -        call_count = afr_frame_return (frame); - -        if (call_count == 0) -                afr_sh_metadata_fix (frame, this); - -        return 0; +out: +        return;  }  int @@ -626,7 +573,9 @@ afr_sh_metadata_post_nonblocking_inodelk_cbk (call_frame_t *frame,                          "inodelks done for %s. Proceeding to FOP",                          local->loc.path);                  afr_sh_common_lookup (frame, this, &local->loc, -                                      afr_sh_metadata_lookup_cbk, _gf_false); +                                      afr_sh_metadata_fix, NULL, +                                      AFR_LOOKUP_FAIL_CONFLICTS | +                                      AFR_LOOKUP_FAIL_MISSING_GFIDS);          }          return 0; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index bc85fd71d15..f99ce471994 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -47,6 +47,8 @@ typedef int (*afr_impunge_done_cbk_t) (call_frame_t *frame, xlator_t *this,  typedef int (*afr_post_remove_call_t) (call_frame_t *frame, xlator_t *this);  typedef int (*afr_lock_cbk_t) (call_frame_t *frame, xlator_t *this); +typedef void (*afr_lookup_done_cbk_t) (call_frame_t *frame, xlator_t *this, +                                      int32_t op_ret, int32_t op_errno);  typedef struct _afr_private {          gf_lock_t lock;               /* to guard access to child_count, etc */ @@ -170,6 +172,10 @@ typedef struct {          int32_t *fresh_parent_dirs;          /* array of errno's, one for each child */          int *child_errno; +        /*loc used for lookup*/ +        loc_t lookup_loc; +        int32_t lookup_flags; +        afr_lookup_done_cbk_t lookup_done;          int32_t **pending_matrix;          int32_t **delta_matrix; @@ -1018,7 +1024,7 @@ gf_boolean_t  afr_conflicting_iattrs (struct iatt *bufs, int32_t *success_children,                          unsigned int child_count, const char *path,                          const char *xlator_name); -int +unsigned int  afr_gfid_missing_count (const char *xlator_name, int32_t *children,                          struct iatt *bufs, unsigned int child_count,                          const char *path); @@ -1032,5 +1038,5 @@ int32_t  afr_resultant_errno_get (int32_t *children,                           int *child_errno, unsigned int child_count);  int32_t* -afr_fresh_children_create (int32_t child_count); +afr_children_create (unsigned int child_count);  #endif /* __AFR_H__ */ diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c index 585a0686edc..b756e1664fc 100644 --- a/xlators/cluster/afr/src/pump.c +++ b/xlators/cluster/afr/src/pump.c @@ -29,6 +29,7 @@  #include "afr-common.c"  #include "defaults.c" +uint64_t pump_pid = 0;  static int  pump_mark_start_pending (xlator_t *this)  { @@ -148,71 +149,6 @@ pump_set_resume_path (xlator_t *this, const char *path)          return ret;  } -static void -build_child_loc (loc_t *parent, loc_t *child, char *path, char *name) -{ -        child->path = path; -        child->name = name; - -        child->parent = inode_ref (parent->inode); -        child->inode = inode_new (parent->inode->table); -} - -static char * -build_file_path (loc_t *loc, gf_dirent_t *entry) -{ -        xlator_t *this = NULL; -        char *file_path = NULL; -        int pathlen = 0; -        int total_size = 0; - -        this = THIS; - -        pathlen = STRLEN_0 (loc->path); - -        if (IS_ROOT_PATH (loc->path)) { -                total_size = pathlen + entry->d_len; -                file_path = GF_CALLOC (1, total_size, gf_afr_mt_char); -                if (!file_path) { -                        gf_log (this->name, GF_LOG_ERROR, -                                "Out of memory"); -                        return NULL; -                } - -                gf_log (this->name, GF_LOG_TRACE, -                        "constructing file path of size=%d" -                        "pathlen=%d, d_len=%d", -                        total_size, pathlen, -                        entry->d_len); - -                snprintf(file_path, total_size, "%s%s", loc->path, entry->d_name); - -        } else { -                total_size = pathlen + entry->d_len + 1; /* for the extra '/' in the path */ -                file_path = GF_CALLOC (1, total_size + 1, gf_afr_mt_char); -                if (!file_path) { -                        gf_log (this->name, GF_LOG_ERROR, -                                "Out of memory"); -                        return NULL; -                } - -                gf_log (this->name, GF_LOG_TRACE, -                        "constructing file path of size=%d" -                        "pathlen=%d, d_len=%d", -                        total_size, pathlen, -                        entry->d_len); - -                snprintf(file_path, total_size, "%s/%s", loc->path, entry->d_name); -        } - -        gf_log (this->name, GF_LOG_TRACE, -                "path=%s and d_name=%s", loc->path, entry->d_name); -        gf_log (this->name, GF_LOG_TRACE, -                "constructed file_path=%s of size=%d", file_path, total_size); - -        return file_path; -} -  static int  pump_save_path (xlator_t *this, const char *path)  { @@ -400,7 +336,7 @@ pump_save_file_stats (xlator_t *this, const char *path)  }  static int -gf_pump_traverse_directory (loc_t *loc) +gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)  {          xlator_t *this = NULL;          afr_private_t *priv = NULL; @@ -415,9 +351,6 @@ gf_pump_traverse_directory (loc_t *loc)  	struct iatt iatt, parent;  	dict_t *xattr_rsp; -        int source = 0; - -        char *file_path = NULL;          int ret = 0;          gf_boolean_t is_directory_empty = _gf_true; @@ -427,14 +360,14 @@ gf_pump_traverse_directory (loc_t *loc)          GF_ASSERT (loc->inode); -	fd = fd_create (loc->inode, PUMP_PID); +	fd = fd_create (loc->inode, pump_pid);          if (!fd) {                  gf_log (this->name, GF_LOG_ERROR,                          "Failed to create fd for %s", loc->path);                  goto out;          } -        ret = syncop_opendir (priv->children[source], loc, fd); +        ret = syncop_opendir (this, loc, fd);          if (ret < 0) {                  gf_log (this->name, GF_LOG_DEBUG,                          "opendir failed on %s", loc->path); @@ -445,7 +378,7 @@ gf_pump_traverse_directory (loc_t *loc)                  "pump opendir on %s returned=%d",                  loc->path, ret); -        while (syncop_readdirp (priv->children[source], fd, 131072, offset, &entries)) { +        while (syncop_readdirp (this, fd, 131072, offset, &entries)) {                  if (list_empty (&entries.list)) {                          gf_log (this->name, GF_LOG_TRACE, @@ -457,25 +390,30 @@ gf_pump_traverse_directory (loc_t *loc)                          gf_log (this->name, GF_LOG_DEBUG,                                  "found readdir entry=%s", entry->d_name); -                        file_path = build_file_path (loc, entry); -                        if (!file_path) { -                                gf_log (this->name, GF_LOG_DEBUG, -                                        "file path construction failed"); +                        ret = afr_build_child_loc (this, &entry_loc, +                                                   loc, entry->d_name); +                        if (ret)                                  goto out; -                        } - -                        build_child_loc (loc, &entry_loc, file_path, entry->d_name); -                          if (!IS_ENTRY_CWD (entry->d_name) &&                                             !IS_ENTRY_PARENT (entry->d_name)) {                                      is_directory_empty = _gf_false;                                      ret = syncop_lookup (this, &entry_loc, NULL,                                                           &iatt, &xattr_rsp, &parent); +                                    if (ret) +                                            continue;                                      entry_loc.ino = iatt.ia_ino;                                      entry_loc.inode->ino = iatt.ia_ino; -                                    memcpy (entry_loc.inode->gfid, iatt.ia_gfid, 16); + +                                    if (uuid_is_null (iatt.ia_gfid)) { +                                            uuid_generate (gfid); +                                            uuid_copy (entry_loc.inode->gfid, +                                                       gfid); +                                    } else { +                                            uuid_copy (entry_loc.inode->gfid, +                                                       iatt.ia_gfid); +                                    }                                      gf_log (this->name, GF_LOG_DEBUG,                                              "lookup %s => %"PRId64, @@ -513,7 +451,7 @@ gf_pump_traverse_directory (loc_t *loc)                                                      gf_log (this->name, GF_LOG_TRACE,                                                              "entering dir=%s",                                                              entry->d_name); -                                                    gf_pump_traverse_directory (&entry_loc); +                                                    gf_pump_traverse_directory (&entry_loc, gfid);                                              }                                      }                              } @@ -687,6 +625,7 @@ pump_task (void *data)  	struct iatt iatt, parent;  	dict_t *xattr_rsp = NULL;          dict_t *xattr_req = NULL; +        uuid_t gfid = {0};          int ret = -1; @@ -727,7 +666,7 @@ pump_task (void *data)                  goto out;          } -        gf_pump_traverse_directory (&loc); +        gf_pump_traverse_directory (&loc, gfid);          pump_complete_migration (this);  out: @@ -771,8 +710,8 @@ pump_start (call_frame_t *pump_frame, xlator_t *this)  	priv = this->private;          pump_priv = priv->pump_private; -        if (!pump_frame->root->lk_owner) -                pump_frame->root->lk_owner = PUMP_LK_OWNER; +	pump_frame->root->lk_owner = (uint64_t) (unsigned long)pump_frame->root; +	pump_pid = (uint64_t) (unsigned long)pump_frame->root;  	ret = synctask_new (pump_priv->env, pump_task,                              pump_task_completion, diff --git a/xlators/cluster/afr/src/pump.h b/xlators/cluster/afr/src/pump.h index 0c0b57fc2d3..19bb96f8c6a 100644 --- a/xlators/cluster/afr/src/pump.h +++ b/xlators/cluster/afr/src/pump.h @@ -26,7 +26,6 @@  #define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"  #define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect" -#define PUMP_PID 696969  #define PUMP_LK_OWNER 696969  #define IS_ROOT_PATH(path) (!strcmp (path, "/"))  | 
