diff options
Diffstat (limited to 'xlators/cluster/afr/src/afr-dir-read.c')
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-read.c | 95 |
1 files changed, 59 insertions, 36 deletions
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c index 8593d0c14..ce941f018 100644 --- a/xlators/cluster/afr/src/afr-dir-read.c +++ b/xlators/cluster/afr/src/afr-dir-read.c @@ -49,7 +49,6 @@ #include "afr-self-heal.h" #include "afr-self-heal-common.h" - int afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this) { @@ -517,24 +516,38 @@ int32_t afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) { - afr_private_t * priv = NULL; - afr_local_t * local = NULL; - xlator_t ** children = NULL; - int call_child = 0; - int ret = 0; - gf_dirent_t * entry = NULL; - gf_dirent_t * tmp = NULL; - int child_index = -1; - uint64_t ctx = 0; - afr_fd_ctx_t *fd_ctx = NULL; - off_t offset = 0; + afr_private_t * priv = NULL; + afr_local_t * local = NULL; + xlator_t ** children = NULL; + int32_t next_call_child = -1; + int ret = 0; + gf_dirent_t * entry = NULL; + gf_dirent_t * tmp = NULL; + int32_t *last_index = NULL; + int32_t read_child = -1; + int32_t *fresh_children = NULL; + uint64_t ctx = 0; + afr_fd_ctx_t *fd_ctx = NULL; + off_t offset = 0; + int32_t call_child = -1; priv = this->private; children = priv->children; local = frame->local; - child_index = (long) cookie; + read_child = (long) cookie; + last_index = &local->cont.readdir.last_index; + fresh_children = local->fresh_children; + + /* the value of the last_index changes if afr_next_call_child is + * called. So to find the call_child of this callback use last_index + * before the next_call_child call. + */ + if (*last_index == -1) + call_child = read_child; + else + call_child = fresh_children[*last_index]; if (priv->strict_readdir) { ret = fd_ctx_get (local->fd, this, &ctx); @@ -548,25 +561,25 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, fd_ctx = (afr_fd_ctx_t *)(long) ctx; - if (child_went_down (op_ret, op_errno)) { - if (all_tried (child_index, priv->child_count)) { - gf_log (this->name, GF_LOG_INFO, - "all options tried going out"); + if (op_ret == -1) { + next_call_child = afr_next_call_child (fresh_children, + local->child_up, + priv->child_count, + last_index, + read_child); + if (next_call_child < 0) goto out; - } - - call_child = ++child_index; - gf_log (this->name, GF_LOG_TRACE, "starting readdir afresh on child %d, offset %"PRId64, - call_child, (uint64_t) 0); + next_call_child, (uint64_t) 0); fd_ctx->failed_over = _gf_true; STACK_WIND_COOKIE (frame, afr_readdirp_cbk, - (void *) (long) call_child, - children[call_child], - children[call_child]->fops->readdirp, local->fd, + (void *) (long) read_child, + children[next_call_child], + children[next_call_child]->fops->readdirp, + local->fd, local->cont.readdir.size, 0); return 0; } @@ -603,12 +616,12 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_log (this->name, GF_LOG_TRACE, "trying to fetch non-duplicate entries " "from offset %"PRId64", child %s", - offset, children[child_index]->name); + offset, children[call_child]->name); STACK_WIND_COOKIE (frame, afr_readdirp_cbk, - (void *) (long) child_index, - children[child_index], - children[child_index]->fops->readdirp, + (void *) (long) read_child, + children[call_child], + children[call_child]->fops->readdirp, local->fd, local->cont.readdir.size, offset); return 0; } @@ -623,7 +636,6 @@ out: return 0; } - int32_t afr_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, int whichop) @@ -637,6 +649,7 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, int ret = -1; int32_t op_ret = -1; int32_t op_errno = 0; + uint64_t read_child = 0; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -646,19 +659,29 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, children = priv->children; ALLOC_OR_GOTO (local, afr_local_t, out); + frame->local = local; + ret = AFR_LOCAL_INIT (local, priv); if (ret < 0) { op_errno = -ret; goto out; } - frame->local = local; + local->fresh_children = afr_fresh_children_create (priv->child_count); + if (!local->fresh_children) { + op_errno = ENOMEM; + goto out; + } - call_child = afr_first_up_child (priv); - if (call_child == -1) { - op_errno = ENOTCONN; - gf_log (this->name, GF_LOG_INFO, - "no child is up"); + read_child = afr_inode_get_read_ctx (this, fd->inode, + local->fresh_children); + op_ret = afr_get_call_child (this, local->child_up, read_child, + local->fresh_children, + &call_child, + &local->cont.readdir.last_index); + if (op_ret < 0) { + op_errno = -op_ret; + op_ret = -1; goto out; } |