diff options
author | N Balachandran <nbalacha@redhat.com> | 2017-07-14 15:18:19 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2017-12-26 05:25:33 +0000 |
commit | 85a389cfced2c299faa37b6f930c2cd0ca8c72b9 (patch) | |
tree | 09099228c814ae9f4ab5f48b9b62f00dea72d297 /xlators/cluster/dht/src/dht-inode-read.c | |
parent | f13023862edc868d4da87609412341aecd041ed8 (diff) |
cluster/dht: Add migration checks to dht_(f)xattrop
The dht_(f)xattrop implementation did not implement
migration phase1/phase2 checks which could cause issues
with rebalance on sharded volumes.
This does not solve the issue where fops may reach the target
out of order.
Change-Id: I2416fc35115e60659e35b4b717fd51f20746586c
BUG: 1471031
Signed-off-by: N Balachandran <nbalacha@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src/dht-inode-read.c')
-rw-r--r-- | xlators/cluster/dht/src/dht-inode-read.c | 241 |
1 files changed, 224 insertions, 17 deletions
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c index a9e47664a81..fa63fefb903 100644 --- a/xlators/cluster/dht/src/dht-inode-read.c +++ b/xlators/cluster/dht/src/dht-inode-read.c @@ -24,8 +24,9 @@ int dht_lk2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret); int dht_fsync2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret); - - +int +dht_common_xattrop2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, + int ret); int dht_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -1246,13 +1247,163 @@ err: return 0; } -/* Currently no translators on top of 'distribute' will be using - * below fops, hence not implementing 'migration' related checks - */ + +int +dht_common_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) +{ + dht_local_t *local = NULL; + call_frame_t *call_frame = NULL; + xlator_t *prev = NULL; + xlator_t *src_subvol = NULL; + xlator_t *dst_subvol = NULL; + struct iatt stbuf = {0,}; + int ret = -1; + inode_t *inode = NULL; + + local = frame->local; + call_frame = cookie; + prev = call_frame->this; + + local->op_errno = op_errno; + + if ((op_ret == -1) && !dht_inode_missing (op_errno)) { + gf_msg_debug (this->name, op_errno, + "subvolume %s returned -1.", + prev->name); + goto out; + } + + if (local->call_cnt != 1) + goto out; + + ret = dht_read_iatt_from_xdata (this, xdata, &stbuf); + + if ((!op_ret) && (ret)) { + /* This is a potential problem and can cause corruption + * with sharding. + * Oh well. We tried. + */ + goto out; + } + + local->op_ret = op_ret; + local->rebalance.target_op_fn = dht_common_xattrop2; + if (xdata) + local->rebalance.xdata = dict_ref (xdata); + + if (dict) + local->rebalance.dict = dict_ref (dict); + + /* Phase 2 of migration */ + if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (&stbuf)) { + ret = dht_rebalance_complete_check (this, frame); + if (!ret) + return 0; + } + + /* Check if the rebalance phase1 is true */ + if (IS_DHT_MIGRATION_PHASE1 (&stbuf)) { + + inode = local->loc.inode ? local->loc.inode : local->fd->inode; + dht_inode_ctx_get_mig_info (this, inode, &src_subvol, + &dst_subvol); + + if (dht_mig_info_is_invalid (local->cached_subvol, src_subvol, + dst_subvol) || + !dht_fd_open_on_dst (this, local->fd, dst_subvol)) { + + ret = dht_rebalance_in_progress_check (this, frame); + if (!ret) + return 0; + } else { + dht_common_xattrop2 (this, dst_subvol, frame, 0); + return 0; + } + } + + +out: + if (local->fop == GF_FOP_XATTROP) { + DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, + dict, xdata); + } else { + DHT_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, + dict, xdata); + } + + return 0; +} + + +int +dht_common_xattrop2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, + int ret) +{ + dht_local_t *local = NULL; + int32_t op_errno = EINVAL; + + if ((frame == NULL) || (frame->local == NULL)) + goto out; + + local = frame->local; + op_errno = local->op_errno; + + if (we_are_not_migrating (ret)) { + /* This dht xlator is not migrating the file. Unwind and + * pass on the original mode bits so the higher DHT layer + * can handle this. + */ + if (local->fop == GF_FOP_XATTROP) { + DHT_STACK_UNWIND (xattrop, frame, local->op_ret, + op_errno, local->rebalance.dict, + local->rebalance.xdata); + } else { + DHT_STACK_UNWIND (fxattrop, frame, local->op_ret, + op_errno, local->rebalance.dict, + local->rebalance.xdata); + } + + return 0; + } + + if (subvol == NULL) + goto out; + + local->call_cnt = 2; /* This is the second attempt */ + + if (local->fop == GF_FOP_XATTROP) { + STACK_WIND (frame, dht_common_xattrop_cbk, subvol, + subvol->fops->xattrop, &local->loc, + local->rebalance.flags, local->rebalance.xattr, + local->xattr_req); + } else { + STACK_WIND (frame, dht_common_xattrop_cbk, subvol, + subvol->fops->fxattrop, local->fd, + local->rebalance.flags, local->rebalance.xattr, + local->xattr_req); + } + + return 0; + +out: + + /* If local is unavailable we could be unwinding the wrong + * function here */ + + if (local && (local->fop == GF_FOP_XATTROP)) { + DHT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL); + } else { + DHT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL); + } + return 0; +} + int dht_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) + int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict, xdata); return 0; @@ -1263,9 +1414,10 @@ int dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - xlator_t *subvol = NULL; + xlator_t *subvol = NULL; int op_errno = -1; - dht_local_t *local = NULL; + dht_local_t *local = NULL; + int ret = -1; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); @@ -1287,11 +1439,33 @@ dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, goto err; } - local->call_cnt = 1; + /* Todo : Handle dirs as well. At the moment the only xlator above dht + * that uses xattrop is sharding and that is only for files */ + + if (IA_ISDIR (loc->inode->ia_type)) { + STACK_WIND (frame, dht_xattrop_cbk, subvol, + subvol->fops->xattrop, loc, flags, dict, xdata); + + } else { + local->xattr_req = xdata ? dict_ref(xdata) : dict_new (); + local->call_cnt = 1; - STACK_WIND (frame, dht_xattrop_cbk, - subvol, subvol->fops->xattrop, - loc, flags, dict, xdata); + local->rebalance.xattr = dict_ref (dict); + local->rebalance.flags = flags; + + ret = dht_request_iatt_in_xdata (this, local->xattr_req); + + if (ret) { + gf_msg_debug (this->name, 0, + "Failed to set dictionary key %s file=%s", + DHT_IATT_IN_XDATA_KEY, loc->path); + } + + STACK_WIND (frame, dht_common_xattrop_cbk, subvol, + subvol->fops->xattrop, loc, + local->rebalance.flags, local->rebalance.xattr, + local->xattr_req); + } return 0; @@ -1318,6 +1492,8 @@ dht_fxattrop (call_frame_t *frame, xlator_t *this, { xlator_t *subvol = NULL; int op_errno = -1; + dht_local_t *local = NULL; + int ret = -1; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); @@ -1331,10 +1507,39 @@ dht_fxattrop (call_frame_t *frame, xlator_t *this, goto err; } - STACK_WIND (frame, - dht_fxattrop_cbk, - subvol, subvol->fops->fxattrop, - fd, flags, dict, xdata); + local = dht_local_init (frame, NULL, fd, GF_FOP_FXATTROP); + if (!local) { + op_errno = ENOMEM; + goto err; + } + + /* Todo : Handle dirs as well. At the moment the only xlator above dht + * that uses xattrop is sharding and that is only for files */ + + if (IA_ISDIR (fd->inode->ia_type)) { + STACK_WIND (frame, dht_fxattrop_cbk, subvol, + subvol->fops->fxattrop, fd, flags, dict, xdata); + + } else { + local->xattr_req = xdata ? dict_ref(xdata) : dict_new (); + local->call_cnt = 1; + + local->rebalance.xattr = dict_ref (dict); + local->rebalance.flags = flags; + + ret = dht_request_iatt_in_xdata (this, local->xattr_req); + + if (ret) { + gf_msg_debug (this->name, 0, + "Failed to set dictionary key %s fd=%p", + DHT_IATT_IN_XDATA_KEY, fd); + } + + STACK_WIND (frame, dht_common_xattrop_cbk, subvol, + subvol->fops->fxattrop, fd, + local->rebalance.flags, local->rebalance.xattr, + local->xattr_req); + } return 0; @@ -1345,6 +1550,9 @@ err: return 0; } +/* Currently no translators on top of 'distribute' will be using + * below fops, hence not implementing 'migration' related checks + */ int dht_inodelk_cbk (call_frame_t *frame, void *cookie, @@ -1406,7 +1614,6 @@ dht_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - dht_lk_inode_unref (frame, op_ret); DHT_STACK_UNWIND (finodelk, frame, op_ret, op_errno, xdata); return 0; |