diff options
| author | Raghavendra G <rgowdapp@redhat.com> | 2015-05-28 16:03:12 +0530 |
|---|---|---|
| committer | Raghavendra G <rgowdapp@redhat.com> | 2015-06-02 22:33:00 -0700 |
| commit | b6eda067d2e2a0b56718ea71522f6c7b06a09f13 (patch) | |
| tree | 82f5909c06abb4fdbb99d11d3fbe3eefea7b8f2c /xlators/cluster/dht/src/dht-common.c | |
| parent | b7842d178a6019bc2c14ecaf18ae5438a46bda29 (diff) | |
cluster/dht: pass a destination subvol to fop2 variants to avoid races.
The destination subvol used in the fop2 variants is either stored in
inode-ctx1 or local->cached_subvol. However, it is not guaranteed that
a value stored in these locations before invocation of fop2 is still
present after the invocation as these locations are shared among
different concurrent operations. So, to preserve the atomicity of
"check dst-subvol and invoke fop2 variant if dst-subvol found", we
pass down the dst-subvol to fop2 variant.
This patch also fixes error handling in some fop2 variants.
Change-Id: Icc226228a246d3f223e3463519736c4495b364d2
BUG: 1142423
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: http://review.gluster.org/10943
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: N Balachandran <nbalacha@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.c')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 78 |
1 files changed, 19 insertions, 59 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index d7b41a8f28a..a6f916aa5c4 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -26,13 +26,13 @@ int run_defrag = 0; -int dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret); +int dht_link2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame); int -dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret); +dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame); int -dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret); +dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame); int @@ -3355,7 +3355,7 @@ dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, inode = (local->fd) ? local->fd->inode : local->loc.inode; dht_inode_ctx_get1 (this, inode, &subvol); if (subvol) { - dht_setxattr2 (this, frame, 0); + dht_setxattr2 (this, subvol, frame); return 0; } ret = dht_rebalance_in_progress_check (this, frame); @@ -3522,30 +3522,15 @@ out: int -dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret) +dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame) { dht_local_t *local = NULL; - xlator_t *subvol = NULL; int op_errno = EINVAL; - inode_t *inode = NULL; - - local = frame->local; - - inode = (local->fd) ? local->fd->inode : local->loc.inode; - dht_inode_ctx_get1 (this, inode, &subvol); - - /* In phase2, dht_migration_complete_check_task will - * reset inode_ctx_reset1 and update local->cached_subvol - * with the dst subvol. - */ - if (!subvol) - subvol = local->cached_subvol; - - if (!subvol) { - op_errno = EINVAL; + if (!frame || !frame->local || !subvol) goto err; - } + + local = frame->local; local->call_cnt = 2; /* This is the second attempt */ @@ -3881,7 +3866,7 @@ dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, inode = (local->fd) ? local->fd->inode : local->loc.inode; dht_inode_ctx_get1 (this, inode, &subvol); if (subvol) { - dht_removexattr2 (this, frame, 0); + dht_removexattr2 (this, subvol, frame); return 0; } ret = dht_rebalance_in_progress_check (this, frame); @@ -3900,32 +3885,15 @@ out: } int -dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret) +dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame) { - dht_local_t *local = NULL; - xlator_t *subvol = NULL; + dht_local_t *local = NULL; int op_errno = EINVAL; - inode_t *inode = NULL; - - local = frame->local; - - inode = (local->fd) ? local->fd->inode : local->loc.inode; - dht_inode_ctx_get1 (this, inode, &subvol); - - /* In phase2, dht_migration_complete_check_task will - * reset inode_ctx_reset1 and update local->cached_subvol - * with the dst subvol. - */ - if (!subvol) - subvol = local->cached_subvol; - - if (!subvol) { - op_errno = EINVAL; + if (!frame || !frame->local || !subvol) goto err; - } - + local = frame->local; local->call_cnt = 2; /* This is the second attempt */ @@ -3942,7 +3910,7 @@ dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret) return 0; err: - DHT_STACK_UNWIND (removexattr, frame, local->op_ret, op_errno, NULL); + DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); return 0; } @@ -5275,7 +5243,7 @@ dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!ret) return 0; } else { - dht_link2 (this, frame, 0); + dht_link2 (this, subvol, frame); return 0; } } @@ -5284,7 +5252,7 @@ dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { ret = dht_inode_ctx_get1 (this, local->loc.inode, &subvol); if (subvol) { - dht_link2 (this, frame, 0); + dht_link2 (this, subvol, frame); return 0; } ret = dht_rebalance_in_progress_check (this, frame); @@ -5302,10 +5270,9 @@ out: int -dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret) +dht_link2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame) { dht_local_t *local = NULL; - xlator_t *subvol = NULL; int op_errno = EINVAL; local = frame->local; @@ -5313,16 +5280,9 @@ dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret) goto err; op_errno = local->op_errno; - if (op_ret == -1) + if (subvol == NULL) { + op_errno = EINVAL; goto err; - - dht_inode_ctx_get1 (this, local->loc.inode, &subvol); - if (!subvol) { - subvol = local->cached_subvol; - if (!subvol) { - op_errno = EINVAL; - goto err; - } } /* Second call to create link file could result in EEXIST as the |
