summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-common.c
diff options
context:
space:
mode:
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 7150f0f002e..9129b278694 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -341,6 +341,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)
{
@@ -598,6 +650,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;
}
@@ -1682,6 +1736,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);