diff options
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 65 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-read.c | 20 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-write.c | 29 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 19 |
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); |