summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/cluster/afr/src/afr-common.c65
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.c20
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c29
-rw-r--r--xlators/cluster/afr/src/afr.h19
4 files changed, 121 insertions, 12 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 59b8038dcac..2fd7879d923 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -1188,6 +1188,62 @@ afr_handle_quota_size (afr_local_t *local, xlator_t *this,
}
}
+static int
+afr_lookup_select_parent_read_child (xlator_t *this, inode_t *parent,
+ afr_local_t *local)
+{
+ int i = 0;
+ int child_index = -1;
+ int par_read_child = -1;
+ int par_read_child_iter = -1;
+ int *fresh_children = NULL;
+ int *success_children = NULL;
+ afr_private_t *priv = NULL;
+
+ priv = this->private;
+ success_children = local->cont.lookup.success_children;
+
+ if (!parent)
+ return 0;
+
+ fresh_children = afr_children_create (priv->child_count);
+
+ par_read_child = afr_inode_get_read_ctx (this, parent, fresh_children);
+
+ for (i = 0; i < priv->child_count; i++) {
+ child_index = success_children[i];
+
+ if (child_index == -1)
+ break;
+
+ if (par_read_child_iter == -1) {
+ par_read_child_iter = child_index;
+ continue;
+ }
+
+ if ((par_read_child_iter != par_read_child) && fresh_children &&
+ (afr_is_child_present (fresh_children, priv->child_count,
+ child_index)))
+ par_read_child_iter = child_index;
+
+ if (child_index == par_read_child)
+ par_read_child_iter = child_index;
+ }
+
+ /* At the end of the for-loop, the only reason why @par_read_child_iter
+ * could be -1 is when this LOOKUP has failed on all sub-volumes.
+ * So it is okay to send an arbitrary subvolume (0 in this case)
+ * as parent read child.
+ */
+
+ if (par_read_child_iter == -1)
+ par_read_child_iter = 0;
+
+ GF_FREE (fresh_children);
+ return par_read_child_iter;
+
+}
+
int
afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
{
@@ -1198,8 +1254,10 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
int32_t *sources = NULL;
afr_private_t *priv = NULL;
int32_t read_child = -1;
+ int32_t par_read_child = -1;
int ret = 0;
int i = 0;
+ inode_t *parent = NULL;
GF_ASSERT (local);
@@ -1207,6 +1265,7 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
postparent = &local->cont.lookup.postparent;
xattr = &local->cont.lookup.xattr;
priv = this->private;
+ parent = local->loc.parent;
read_child = afr_inode_get_read_ctx (this, local->cont.lookup.inode,
local->fresh_children);
@@ -1239,7 +1298,11 @@ afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
*xattr = dict_ref (local->cont.lookup.xattrs[read_child]);
*buf = local->cont.lookup.bufs[read_child];
- *postparent = local->cont.lookup.postparents[read_child];
+
+ par_read_child = afr_lookup_select_parent_read_child (this, parent,
+ local);
+
+ *postparent = local->cont.lookup.postparents[par_read_child];
if (dict_get (local->xattr_req, QUOTA_SIZE_KEY))
afr_handle_quota_size (local, this, *xattr);
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c
index 689dd84e646..d94cb0ca699 100644
--- a/xlators/cluster/afr/src/afr-dir-read.c
+++ b/xlators/cluster/afr/src/afr-dir-read.c
@@ -422,14 +422,32 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
dict_t *xdata)
{
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
+ gf_dirent_t *entry = NULL;
+ int par_read_child = (long) cookie;
+ int32_t read_child = -1;
if (op_ret == -1)
goto out;
local = frame->local;
+
afr_readdir_filter_trash_dir (entries, local->fd);
+ list_for_each_entry (entry, &entries->list, list) {
+ if (entry->inode) {
+ read_child = -1;
+
+ read_child = afr_inode_get_read_ctx (this, entry->inode,
+ NULL);
+ if (read_child != par_read_child) {
+ inode_unref (entry->inode);
+ entry->inode = NULL;
+ continue;
+ }
+ }
+ }
+
out:
AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, NULL);
return 0;
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index 3cdec64536d..f996181cd2e 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -80,26 +80,35 @@ __dir_entry_fop_common_cbk (call_frame_t *frame, int child_index,
struct iatt *postparent, struct iatt *prenewparent,
struct iatt *postnewparent)
{
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
+ inode_t *parent = NULL;
+ inode_t *parent2 = NULL;
local = frame->local;
+ parent = local->loc.parent;
+ parent2 = local->newloc.parent;
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
if (op_ret > -1) {
local->op_ret = op_ret;
+ AFR_UPDATE_PARENT_BUF (parent, this, child_index, local,
+ local->cont.dir_fop.preparent,
+ local->cont.dir_fop.postparent,
+ preparent, postparent);
+
+ AFR_UPDATE_PARENT_BUF (parent2, this, child_index, local,
+ local->cont.dir_fop.prenewparent,
+ local->cont.dir_fop.postnewparent,
+ prenewparent, postnewparent);
+
if ((local->success_count == 0) ||
(child_index == local->read_child_index)) {
- local->cont.dir_fop.preparent = *preparent;
- local->cont.dir_fop.postparent = *postparent;
if (buf)
local->cont.dir_fop.buf = *buf;
- if (prenewparent)
- local->cont.dir_fop.prenewparent = *prenewparent;
- if (postnewparent)
- local->cont.dir_fop.postnewparent = *postnewparent;
}
local->cont.dir_fop.inode = inode;
@@ -934,8 +943,8 @@ afr_link_unwind (call_frame_t *frame, xlator_t *this)
local->op_ret, local->op_errno,
local->cont.dir_fop.inode,
&local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent,
+ &local->cont.dir_fop.prenewparent,
+ &local->cont.dir_fop.postnewparent,
NULL);
}
@@ -958,7 +967,7 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
{
__dir_entry_fop_common_cbk (frame, child_index, this,
op_ret, op_errno, inode, buf,
- preparent, postparent, NULL, NULL);
+ NULL, NULL, preparent, postparent);
}
UNLOCK (&frame->lock);
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 87ad67c6384..2548900127f 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -1195,6 +1195,25 @@ afr_xattr_array_destroy (dict_t **xattr, unsigned int child_count);
} \
} while (0)
+#define AFR_UPDATE_PARENT_BUF(parent, this, child_index, local, \
+ dst_preparent, dst_postparent, \
+ src_preparent, src_postparent) do { \
+ int __par_read_child = -1; \
+ if (parent) { \
+ __par_read_child = afr_inode_get_read_ctx (this, parent, \
+ NULL); \
+ if (__par_read_child < 0) \
+ __par_read_child = local->read_child_index; \
+ if ((local->success_count == 0) || \
+ (__par_read_child == child_index)) { \
+ if (src_preparent) \
+ dst_preparent = *src_preparent; \
+ if (src_postparent) \
+ dst_postparent = *src_postparent; \
+ } \
+ } \
+} while (0)
+
int
afr_fd_report_unstable_write (xlator_t *this, fd_t *fd);