From 2a0f905c905de4ad1e74bf4c7998adf087756785 Mon Sep 17 00:00:00 2001 From: karthik-us Date: Thu, 21 Feb 2019 16:17:44 +0530 Subject: 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 --- xlators/cluster/afr/src/afr-common.c | 18 ++++++++++++++++++ xlators/cluster/afr/src/afr-dir-read.c | 15 ++++++++++++++- xlators/cluster/afr/src/afr-open.c | 15 ++++++++++++++- 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__ */ -- cgit