summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-common.c
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2015-06-25 00:22:41 +0530
committerVijay Bellur <vbellur@redhat.com>2015-06-26 19:30:33 -0700
commit0104b5869d89ac58cb13e10417626455c8ba2143 (patch)
tree5db665e349e5787e308487f8474652cd346df93a /xlators/cluster/afr/src/afr-common.c
parentb335fbe14e0afbec3cf50409707f3c8df5d5c01d (diff)
afr: Block fops when file is in split-brain
For directories, block metadata FOPS. For non-directories, block data and metadata FOPS. Do not block entry FOPS. Change-Id: Id7f656f4a513b9d33c457dd7f2d58028dbef8e61 BUG: 1235007 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/11371 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
-rw-r--r--xlators/cluster/afr/src/afr-common.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index f644c9dc200..b42772fda09 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -336,6 +336,58 @@ out:
}
int
+afr_inode_get_readable (call_frame_t *frame, inode_t *inode, xlator_t *this,
+ unsigned char *readable, int *event_p, int type)
+{
+
+ afr_private_t *priv = this->private;
+ afr_local_t *local = frame->local;
+ unsigned char *data = alloca0 (priv->child_count);
+ unsigned char *metadata = alloca0 (priv->child_count);
+ int data_count = 0;
+ int metadata_count = 0;
+ int event_generation = 0;
+ int ret = 0;
+
+ /* We don't care about split-brains for entry transactions. */
+ if (type == AFR_ENTRY_TRANSACTION || type == AFR_ENTRY_RENAME_TRANSACTION)
+ return 0;
+
+ ret = afr_inode_read_subvol_get (inode, this, data, metadata,
+ &event_generation);
+ if (ret == -1)
+ return -EIO;
+
+ data_count = AFR_COUNT (data, priv->child_count);
+ metadata_count = AFR_COUNT (metadata, priv->child_count);
+
+ if (inode->ia_type == IA_IFDIR) {
+ /* For directories, allow even if it is in data split-brain. */
+ if (type == AFR_METADATA_TRANSACTION) {
+ if (!metadata_count)
+ return -EIO;
+ }
+ } else {
+ /* For files, abort in case of data/metadata split-brain. */
+ if (!data_count || !metadata_count)
+ return -EIO;
+ }
+
+ if (type == AFR_METADATA_TRANSACTION && readable)
+ memcpy (readable, metadata, priv->child_count * sizeof *metadata);
+ if (type == AFR_DATA_TRANSACTION && readable) {
+ if (!data_count)
+ memcpy (readable, local->child_up,
+ priv->child_count * sizeof *readable);
+ else
+ memcpy (readable, data, priv->child_count * sizeof *data);
+ }
+ if (event_p)
+ *event_p = event_generation;
+ return 0;
+}
+
+int
afr_inode_split_brain_choice_get (inode_t *inode, xlator_t *this,
int *spb_choice)
{
@@ -593,6 +645,8 @@ afr_accuse_smallfiles (xlator_t *this, struct afr_reply *replies,
for (i = 0; i < priv->child_count; i++) {
if (data_accused[i])
continue;
+ if ((priv->arbiter_count == 1) && (i == ARBITER_BRICK_INDEX))
+ continue;
if (replies[i].poststat.ia_size < maxsize)
data_accused[i] = 1;
}
@@ -1677,6 +1731,10 @@ afr_local_discovery_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
* the slowest local subvolume is far preferable to a remote one.
*/
if (is_local) {
+ /* Don't set arbiter as read child. */
+ if ((priv->arbiter_count == 1) &&
+ (child_index == ARBITER_BRICK_INDEX))
+ goto out;
gf_log (this->name, GF_LOG_INFO,
"selecting local read_child %s",
priv->children[child_index]->name);