diff options
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 1 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-read.c | 55 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 8 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 1 |
5 files changed, 42 insertions, 25 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 3a8a52293aa..0e1b6dce682 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -2292,6 +2292,7 @@ __afr_fd_ctx_set (xlator_t *this, fd_t *fd) pthread_mutex_init (&fd_ctx->delay_lock, NULL); INIT_LIST_HEAD (&fd_ctx->paused_calls); INIT_LIST_HEAD (&fd_ctx->entries); + fd_ctx->call_child = -1; ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx); if (ret) diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c index b661cfa9c85..c6628db6b95 100644 --- a/xlators/cluster/afr/src/afr-dir-read.c +++ b/xlators/cluster/afr/src/afr-dir-read.c @@ -517,6 +517,9 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local = frame->local; + if ((priv->readdir_failover == _gf_false) && (op_ret < 0)) + goto out; + read_child = (long) cookie; last_index = &local->cont.readdir.last_index; fresh_children = local->fresh_children; @@ -623,15 +626,14 @@ int32_t afr_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, int whichop, dict_t *dict) { - afr_private_t * priv = NULL; - xlator_t ** children = NULL; - int call_child = 0; - afr_local_t *local = NULL; - uint64_t ctx = 0; - afr_fd_ctx_t *fd_ctx = NULL; - int ret = -1; - int32_t op_errno = 0; - uint64_t read_child = 0; + afr_private_t *priv = NULL; + xlator_t **children = NULL; + int call_child = 0; + afr_local_t *local = NULL; + afr_fd_ctx_t *fd_ctx = NULL; + int ret = -1; + int32_t op_errno = 0; + uint64_t read_child = 0; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -656,29 +658,33 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, read_child = afr_inode_get_read_ctx (this, fd->inode, local->fresh_children); ret = afr_get_call_child (this, local->child_up, read_child, - local->fresh_children, - &call_child, - &local->cont.readdir.last_index); + local->fresh_children, + &call_child, + &local->cont.readdir.last_index); if (ret < 0) { op_errno = -ret; goto out; } + fd_ctx = afr_fd_ctx_get (fd, this); + if (!fd_ctx) { + op_errno = EBADF; + goto out; + } + + if ((offset == 0) || (fd_ctx->call_child == -1)) { + fd_ctx->call_child = call_child; + } else if ((priv->readdir_failover == _gf_false) && + (call_child != fd_ctx->call_child)) { + op_errno = EBADF; + goto out; + } + local->fd = fd_ref (fd); local->cont.readdir.size = size; local->cont.readdir.dict = (dict)? dict_ref (dict) : NULL; if (priv->strict_readdir) { - ret = fd_ctx_get (fd, this, &ctx); - if (ret < 0) { - gf_log (this->name, GF_LOG_INFO, - "could not get fd ctx for fd=%p", fd); - op_errno = -ret; - goto out; - } - - fd_ctx = (afr_fd_ctx_t *)(long) ctx; - if (fd_ctx->last_tried != call_child) { gf_log (this->name, GF_LOG_TRACE, "first up child has changed from %d to %d, " @@ -705,10 +711,9 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, children[call_child]->fops->readdirp, fd, size, offset, dict); - ret = 0; + return 0; out: - if (ret < 0) - AFR_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL); + AFR_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL); return 0; } diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 51c51e56a72..8c7f452dcd9 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -167,6 +167,8 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("post-op-delay-secs", priv->post_op_delay_secs, options, uint32, out); + GF_OPTION_RECONF ("readdir-failover", priv->readdir_failover, options, + bool, out); ret = 0; out: return ret; @@ -294,6 +296,7 @@ init (xlator_t *this) fix_quorum_options(this,priv,qtype); GF_OPTION_INIT ("post-op-delay-secs", priv->post_op_delay_secs, uint32, out); + GF_OPTION_INIT ("readdir-failover", priv->readdir_failover, bool, out); priv->wait_count = 1; @@ -609,5 +612,10 @@ struct volume_options options[] = { "post-operation phase of the transaction to " "enhance overlap of adjacent write operations.", }, + { .key = {"readdir-failover"}, + .type = GF_OPTION_TYPE_BOOL, + .description = "readdir(p) will not failover if this option is off", + .default_value = "on", + }, { .key = {NULL} }, }; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 554c89a48ec..944f8455b88 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -155,6 +155,7 @@ typedef struct _afr_private { char vol_uuid[UUID_SIZE + 1]; int32_t *last_event; afr_self_heald_t shd; + gf_boolean_t readdir_failover; } afr_private_t; typedef struct { @@ -741,6 +742,7 @@ typedef struct { pthread_mutex_t delay_lock; gf_timer_t *delay_timer; call_frame_t *delay_frame; + int call_child; } afr_fd_ctx_t; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 09c5519fb6b..60e4c6c4371 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -136,6 +136,7 @@ static struct volopt_map_entry glusterd_volopt_map[] = { {"cluster.quorum-type", "cluster/replicate", "quorum-type", NULL, NO_DOC, 0}, {"cluster.quorum-count", "cluster/replicate", "quorum-count", NULL, NO_DOC, 0}, + {"cluster.readdir-failover", "cluster/replicate", NULL, NULL, DOC, 0}, {"cluster.stripe-block-size", "cluster/stripe", "block-size", NULL, DOC, 0}, {"cluster.stripe-coalesce", "cluster/stripe", "coalesce", NULL, DOC, 0}, |