diff options
author | karthik-us <ksubrahm@redhat.com> | 2019-02-21 16:17:44 +0530 |
---|---|---|
committer | Ravishankar N <ravishankar@redhat.com> | 2019-03-08 04:03:08 +0000 |
commit | 2a0f905c905de4ad1e74bf4c7998adf087756785 (patch) | |
tree | f66363f512ea65a5e886bbc0651d51b313877af6 /xlators/cluster | |
parent | 91f98e03ab654f212323d385bfc6fa3c0f2e4110 (diff) |
cluster/afr: Add quorum checks to open & opendir fops
Problem:
Currently even if open & opendir fails on quorum number of bricks,
but succeeds on atleast one brick, it will result in success. This leads
to inconsistency in the behaviour with other operations following the
open, which has quorum checks.
Fix:
Add quorum checks to open & opendir fops to avoid inconsistency.
Change-Id: If8fcb82072a6dc45ea6d4a6754b79763215eba2a
fixes: bz#1634664
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 18 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-read.c | 15 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-open.c | 15 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 2 |
4 files changed, 48 insertions, 2 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 45b96e33970..8a14be98ac0 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -7013,3 +7013,21 @@ afr_lookup_has_quorum(call_frame_t *frame, xlator_t *this, return _gf_false; } + +void +afr_handle_replies_quorum(call_frame_t *frame, xlator_t *this) +{ + afr_local_t *local = frame->local; + afr_private_t *priv = this->private; + unsigned char *success_replies = NULL; + + success_replies = alloca0(priv->child_count); + afr_fill_success_replies(local, priv, success_replies); + + if (priv->quorum_count && !afr_has_quorum(success_replies, this, NULL)) { + local->op_errno = afr_final_errno(local, priv); + if (!local->op_errno) + local->op_errno = afr_quorum_errno(priv); + local->op_ret = -1; + } +} diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c index 6307b637f8d..e7ba4a5ddcc 100644 --- a/xlators/cluster/afr/src/afr-dir-read.c +++ b/xlators/cluster/afr/src/afr-dir-read.c @@ -45,6 +45,10 @@ afr_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, fd_ctx = local->fd_ctx; child_index = (long)cookie; + local->replies[child_index].valid = 1; + local->replies[child_index].op_ret = op_ret; + local->replies[child_index].op_errno = op_errno; + LOCK(&frame->lock); { if (op_ret == -1) { @@ -61,9 +65,12 @@ afr_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, call_count = afr_frame_return(frame); - if (call_count == 0) + if (call_count == 0) { + afr_handle_replies_quorum(frame, this); AFR_STACK_UNWIND(opendir, frame, local->op_ret, local->op_errno, local->fd, NULL); + } + return 0; } @@ -84,6 +91,12 @@ afr_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) goto out; local->op = GF_FOP_OPENDIR; + + if (priv->quorum_count && !afr_has_quorum(local->child_up, this, NULL)) { + op_errno = afr_quorum_errno(priv); + goto out; + } + if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; diff --git a/xlators/cluster/afr/src/afr-open.c b/xlators/cluster/afr/src/afr-open.c index ff72c73a9f4..dd568160521 100644 --- a/xlators/cluster/afr/src/afr-open.c +++ b/xlators/cluster/afr/src/afr-open.c @@ -73,6 +73,10 @@ afr_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, local = frame->local; fd_ctx = local->fd_ctx; + local->replies[child_index].valid = 1; + local->replies[child_index].op_ret = op_ret; + local->replies[child_index].op_errno = op_errno; + LOCK(&frame->lock); { if (op_ret == -1) { @@ -90,7 +94,11 @@ afr_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, call_count = afr_frame_return(frame); if (call_count == 0) { - if ((fd_ctx->flags & O_TRUNC) && (local->op_ret >= 0)) { + afr_handle_replies_quorum(frame, this); + if (local->op_ret == -1) { + AFR_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, NULL, + NULL); + } else if (fd_ctx->flags & O_TRUNC) { STACK_WIND(frame, afr_open_ftruncate_cbk, this, this->fops->ftruncate, fd, 0, NULL); } else { @@ -161,6 +169,11 @@ afr_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, goto out; } + if (priv->quorum_count && !afr_has_quorum(local->child_up, this, NULL)) { + op_errno = afr_quorum_errno(priv); + goto out; + } + if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 2cc3797675e..bb80eb508ea 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1332,4 +1332,6 @@ afr_lookup_has_quorum(call_frame_t *frame, xlator_t *this, void afr_mark_new_entry_changelog(call_frame_t *frame, xlator_t *this); +void +afr_handle_replies_quorum(call_frame_t *frame, xlator_t *this); #endif /* __AFR_H__ */ |