diff options
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 65 | 
1 files changed, 64 insertions, 1 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 59b8038dcac..2fd7879d923 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1188,6 +1188,62 @@ afr_handle_quota_size (afr_local_t *local, xlator_t *this,          }  } +static int +afr_lookup_select_parent_read_child (xlator_t *this, inode_t *parent, +                                     afr_local_t *local) +{ +        int             i                   = 0; +        int             child_index         = -1; +        int             par_read_child      = -1; +        int             par_read_child_iter = -1; +        int            *fresh_children      = NULL; +        int            *success_children    = NULL; +        afr_private_t  *priv                = NULL; + +        priv = this->private; +        success_children = local->cont.lookup.success_children; + +        if (!parent) +                return 0; + +        fresh_children = afr_children_create (priv->child_count); + +        par_read_child = afr_inode_get_read_ctx (this, parent, fresh_children); + +        for (i = 0; i < priv->child_count; i++) { +                child_index = success_children[i]; + +                if (child_index == -1) +                        break; + +                if (par_read_child_iter == -1) { +                        par_read_child_iter = child_index; +                        continue; +                } + +                if ((par_read_child_iter != par_read_child) && fresh_children && +                    (afr_is_child_present (fresh_children, priv->child_count, +                                           child_index))) +                        par_read_child_iter = child_index; + +                if (child_index == par_read_child) +                        par_read_child_iter = child_index; +        } + +        /* At the end of the for-loop, the only reason why @par_read_child_iter +         * could be -1 is when this LOOKUP has failed on all sub-volumes. +         * So it is okay to send an arbitrary subvolume (0 in this case) +         * as parent read child. +         */ + +        if (par_read_child_iter == -1) +                par_read_child_iter = 0; + +        GF_FREE (fresh_children); +        return par_read_child_iter; + +} +  int  afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)  { @@ -1198,8 +1254,10 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)          int32_t         *sources = NULL;          afr_private_t   *priv = NULL;          int32_t         read_child = -1; +        int32_t         par_read_child = -1;          int             ret = 0;          int             i = 0; +        inode_t        *parent = NULL;          GF_ASSERT (local); @@ -1207,6 +1265,7 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)          postparent = &local->cont.lookup.postparent;          xattr = &local->cont.lookup.xattr;          priv = this->private; +        parent = local->loc.parent;          read_child = afr_inode_get_read_ctx (this, local->cont.lookup.inode,                                               local->fresh_children); @@ -1239,7 +1298,11 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)                  *xattr = dict_ref (local->cont.lookup.xattrs[read_child]);          *buf = local->cont.lookup.bufs[read_child]; -        *postparent = local->cont.lookup.postparents[read_child]; + +        par_read_child = afr_lookup_select_parent_read_child (this, parent, +                                                              local); + +        *postparent = local->cont.lookup.postparents[par_read_child];          if (dict_get (local->xattr_req, QUOTA_SIZE_KEY))                  afr_handle_quota_size (local, this, *xattr);  | 
