diff options
author | Pranith Kumar K <pranithk@gluster.com> | 2012-04-01 15:48:26 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2012-04-04 16:22:38 -0700 |
commit | 42a0889d93450e6f1f3472ec0818e678412346c2 (patch) | |
tree | bf016743dadee60295d4caf31f7244b5e5a48844 /xlators/cluster/afr/src/afr-self-heal-algorithm.c | |
parent | 69f70038171862daedcbbccf0eaba3d1f8d885f5 (diff) |
cluster/afr: Handle self-heal of files with holes
Change-Id: I6c04fe3022f234455d52620f42b9add80fc6abe4
BUG: 765424
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Reviewed-on: http://review.gluster.com/3065
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/cluster/afr/src/afr-self-heal-algorithm.c')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-algorithm.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-algorithm.c b/xlators/cluster/afr/src/afr-self-heal-algorithm.c index 6bd0adcd851..99a2108361c 100644 --- a/xlators/cluster/afr/src/afr-self-heal-algorithm.c +++ b/xlators/cluster/afr/src/afr-self-heal-algorithm.c @@ -456,6 +456,35 @@ sh_loop_write_cbk (call_frame_t *loop_frame, void *cookie, xlator_t *this, return 0; } +static void +sh_prune_writes_needed (call_frame_t *sh_frame, call_frame_t *loop_frame, + afr_private_t *priv) +{ + afr_local_t *sh_local = NULL; + afr_self_heal_t *sh = NULL; + afr_local_t *loop_local = NULL; + afr_self_heal_t *loop_sh = NULL; + int i = 0; + + sh_local = sh_frame->local; + sh = &sh_local->self_heal; + + if (!strcmp (sh->algo->name, "diff")) + return; + + loop_local = loop_frame->local; + loop_sh = &loop_local->self_heal; + + /* full self-heal guarantees there exists atleast 1 file with size 0 + * That means for other files we can preserve holes that come after + * its size before 'trim' + */ + for (i = 0; i < priv->child_count; i++) { + if (loop_sh->write_needed[i] && + ((loop_sh->offset + 1) > sh->buf[i].ia_size)) + loop_sh->write_needed[i] = 0; + } +} static int sh_loop_read_cbk (call_frame_t *loop_frame, void *cookie, @@ -499,16 +528,15 @@ sh_loop_read_cbk (call_frame_t *loop_frame, void *cookie, goto out; } - if (loop_sh->file_has_holes && iov_0filled (vector, count) == 0) { - gf_log (this->name, GF_LOG_DEBUG, "0 filled block"); - sh_loop_return (sh_frame, this, loop_frame, - op_ret, op_errno); - goto out; - } + if (loop_sh->file_has_holes && iov_0filled (vector, count) == 0) + sh_prune_writes_needed (sh_frame, loop_frame, priv); call_count = sh_number_of_writes_needed (loop_sh->write_needed, priv->child_count); - GF_ASSERT (call_count > 0); + if (call_count == 0) { + sh_loop_return (sh_frame, this, loop_frame, 0, 0); + goto out; + } loop_local->call_count = call_count; for (i = 0; i < priv->child_count; i++) { |