diff options
| author | Xavier Hernandez <xhernandez@datalab.es> | 2015-08-07 12:37:52 +0200 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-08-14 02:11:13 -0700 | 
| commit | fc3da7299dc2adaf66076bfbfebe4a87582f7008 (patch) | |
| tree | 77aa815bca39a82182ec656fa7913d612584b7c1 /xlators/cluster/ec/src | |
| parent | cfac0a9c78ead389ec261010a1c094bc60ca2810 (diff) | |
cluster/ec: Fix write size in self-heal
Self-heal was always using a fixed block size to heal a file. This
was incorrect for dispersed volumes with a number of data bricks not
being a power of 2.
This patch adjusts the block size to a multiple of the stripe size
of the volume. It also propagates errors detected during the data
heal to stop healing the file and not mark it as healed.
This is a backport if http//review.gluster.org/11862
Change-Id: I5104ae4bfed8585ca40cb45831ca20582566370c
BUG: 1236050
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: http://review.gluster.org/11869
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster/ec/src')
| -rw-r--r-- | xlators/cluster/ec/src/ec-data.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 9 | 
2 files changed, 10 insertions, 0 deletions
diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h index 285f71e702d..8a48a7ca824 100644 --- a/xlators/cluster/ec/src/ec-data.h +++ b/xlators/cluster/ec/src/ec-data.h @@ -283,6 +283,7 @@ struct _ec_heal      fd_t             *fd;      int32_t           partial;      int32_t           done; +    int32_t           error;      gf_boolean_t      nameheal;      uintptr_t         available;      uintptr_t         good; diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index d095aceec00..f76839db38f 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -1777,6 +1777,7 @@ ec_heal_block_done (call_frame_t *frame, void *cookie, xlator_t *this,          fop->heal = NULL;          heal->fop = NULL; +        heal->error = op_ret < 0 ? op_errno : 0;          syncbarrier_wake (heal->data);          return 0;  } @@ -1787,6 +1788,9 @@ ec_sync_heal_block (call_frame_t *frame, xlator_t *this, ec_heal_t *heal)          ec_heal_block (frame, this, heal->bad|heal->good, EC_MINIMUM_ONE,                         ec_heal_block_done, heal);          syncbarrier_wait (heal->data, 1); +        if (heal->error != 0) { +                return -heal->error; +        }          if (heal->bad == 0)                  return -ENOTCONN;          return 0; @@ -1812,6 +1816,11 @@ ec_rebuild_data (call_frame_t *frame, ec_t *ec, fd_t *fd, uint64_t size,          pool = ec->xl->ctx->iobuf_pool;          heal->total_size = size;          heal->size = iobpool_default_pagesize (pool); +        /* We need to adjust the size to a multiple of the stripe size of the +         * volume. Otherwise writes would need to fill gaps (head and/or tail) +         * with existent data from the bad bricks. This could be garbage on a +         * damaged file or it could fail if there aren't enough bricks. */ +        heal->size -= heal->size % ec->stripe_size;          heal->bad       = ec_char_array_to_mask (healed_sinks, ec->nodes);          heal->good      = ec_char_array_to_mask (sources, ec->nodes);          heal->iatt.ia_type = IA_IFREG;  | 
