diff options
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-write.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index ea5514065ea..a45e6d6ef68 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -2013,20 +2013,28 @@ ec_writev_start(ec_fop_data_t *fop) if (err != 0) { goto failed_fd; } + tail = fop->size - fop->user_size - fop->head; if (fop->head > 0) { - found_stripe = ec_get_and_merge_stripe(ec, fop, EC_STRIPE_HEAD); - if (!found_stripe) { - if (ec_make_internal_fop_xdata(&xdata)) { - err = -ENOMEM; - goto failed_xdata; + if (current > fop->offset) { + found_stripe = ec_get_and_merge_stripe(ec, fop, EC_STRIPE_HEAD); + if (!found_stripe) { + if (ec_make_internal_fop_xdata(&xdata)) { + err = -ENOMEM; + goto failed_xdata; + } + ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, + ec_writev_merge_head, NULL, fd, ec->stripe_size, + fop->offset, 0, xdata); + } + } else { + memset(fop->vector[0].iov_base, 0, fop->head); + memset(fop->vector[0].iov_base + fop->size - tail, 0, tail); + if (ec->stripe_cache && (fop->size <= ec->stripe_size)) { + ec_add_stripe_in_cache(ec, fop); } - ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, - ec_writev_merge_head, NULL, fd, ec->stripe_size, - fop->offset, 0, xdata); } } - tail = fop->size - fop->user_size - fop->head; if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size))) { /* Current locking scheme will make sure the 'current' below will * never decrease while the fop is in progress, so the checks will |