diff options
author | Ravishankar N <ravishankar@redhat.com> | 2016-02-29 05:16:50 +0000 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2016-03-04 09:32:18 -0800 |
commit | 8ab87137c855c9a0551a9100c146e4ca76dbbda2 (patch) | |
tree | c86167ff1a04f29ae91786df6471e73039242518 /xlators | |
parent | bf80b9005240811d931090afcfee8ca0b02f8212 (diff) |
afr: do not set arbiter as a readable subvol in inode context
Problem:
If afr_lookup_done() or afr_read_subvol_select_by_policy() chooses the
arbiter brick to serve the stat() data, file size will be reported as
zero from the mount, despite other data bricks being available. This can
break programs like tar which use the stat info to decide how much to read.
Fix:
In the inode-context, mark arbiter as a non-readable subvol for both
data and metadata.
It it to be noted that by making this fix, we are *not* going to serve
metadata FOPS anymore from the arbiter brick despite the brick storing
the metadata. It makes sense to do this because the ever increasing
over-loaded FOPs (getxattr returning stat data etc.) and compound FOPS
in gluster will otherwise make it difficult to add checks in code to
handle corner cases.
Change-Id: Ic60b25d77fd05e0897481b7fcb3716d4f2101001
BUG: 1310171
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reported-by: Mat Clayton <mat@mixcloud.com>
Reviewed-on: http://review.gluster.org/13539
Reviewed-by: Anuradha Talur <atalur@redhat.com>
Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index a7b6ee85a61..5e1acf2ebf4 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -691,6 +691,10 @@ afr_replies_interpret (call_frame_t *frame, xlator_t *this, inode_t *inode, data_readable[i] = 1; metadata_readable[i] = 1; } + if (AFR_IS_ARBITER_BRICK (priv, ARBITER_BRICK_INDEX)) { + data_readable[ARBITER_BRICK_INDEX] = 0; + metadata_readable[ARBITER_BRICK_INDEX] = 0; + } for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) { @@ -1773,9 +1777,14 @@ unwind: read_subvol = spb_choice; else read_subvol = afr_first_up_child (frame, this); + } par_read_subvol = afr_get_parent_read_subvol (this, parent, replies, readable); + if (AFR_IS_ARBITER_BRICK (priv, read_subvol) && local->op_ret == 0) { + local->op_ret = -1; + local->op_errno = ENOTCONN; + } AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, local->inode, &local->replies[read_subvol].poststat, @@ -2222,6 +2231,10 @@ unwind: else read_subvol = afr_first_up_child (frame, this); } + if (AFR_IS_ARBITER_BRICK (priv, read_subvol) && local->op_ret == 0) { + local->op_ret = -1; + local->op_errno = ENOTCONN; + } AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, local->inode, &local->replies[read_subvol].poststat, |