diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-inode-write.c')
| -rw-r--r-- | xlators/cluster/ec/src/ec-inode-write.c | 199 |
1 files changed, 113 insertions, 86 deletions
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index b915a992a00..9b5fe2a7fdc 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -8,10 +8,6 @@ cases as published by the Free Software Foundation. */ -#include "xlator.h" -#include "defaults.h" - -#include "ec.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" @@ -89,6 +85,8 @@ ec_update_write(ec_fop_data_t *fop, uintptr_t mask, off_t offset, uint64_t size) goto out; } + if (fop->locks[0].lock) + ec_lock_update_good(fop->locks[0].lock, fop); vector.iov_base = iobuf->ptr; vector.iov_len = size; memset(vector.iov_base, 0, vector.iov_len); @@ -183,26 +181,26 @@ ec_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, switch (fop->id) { case GF_FOP_SETXATTR: if (fop->cbks.setxattr) { - fop->cbks.setxattr(frame, cookie, this, op_ret, op_errno, - xdata); + QUORUM_CBK(fop->cbks.setxattr, fop, frame, cookie, this, op_ret, + op_errno, xdata); } break; case GF_FOP_REMOVEXATTR: if (fop->cbks.removexattr) { - fop->cbks.removexattr(frame, cookie, this, op_ret, op_errno, - xdata); + QUORUM_CBK(fop->cbks.removexattr, fop, frame, cookie, this, + op_ret, op_errno, xdata); } break; case GF_FOP_FSETXATTR: if (fop->cbks.fsetxattr) { - fop->cbks.fsetxattr(frame, cookie, this, op_ret, op_errno, - xdata); + QUORUM_CBK(fop->cbks.fsetxattr, fop, frame, cookie, this, + op_ret, op_errno, xdata); } break; case GF_FOP_FREMOVEXATTR: if (fop->cbks.fremovexattr) { - fop->cbks.fremovexattr(frame, cookie, this, op_ret, op_errno, - xdata); + QUORUM_CBK(fop->cbks.fremovexattr, fop, frame, cookie, this, + op_ret, op_errno, xdata); } break; } @@ -281,7 +279,7 @@ ec_manager_xattr(ec_fop_data_t *fop, int32_t state) void ec_removexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_removexattr_cbk_t func, void *data, + uint32_t fop_flags, fop_removexattr_cbk_t func, void *data, loc_t *loc, const char *name, dict_t *xdata) { ec_cbk_t callback = {.removexattr = func}; @@ -295,7 +293,7 @@ ec_removexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_REMOVEXATTR, 0, target, - minimum, ec_wind_removexattr, ec_manager_xattr, + fop_flags, ec_wind_removexattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; @@ -361,7 +359,7 @@ ec_wind_fremovexattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) void ec_fremovexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_fremovexattr_cbk_t func, void *data, + uint32_t fop_flags, fop_fremovexattr_cbk_t func, void *data, fd_t *fd, const char *name, dict_t *xdata) { ec_cbk_t callback = {.fremovexattr = func}; @@ -375,8 +373,8 @@ ec_fremovexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FREMOVEXATTR, 0, target, - minimum, ec_wind_fremovexattr, ec_manager_xattr, - callback, data); + fop_flags, ec_wind_fremovexattr, + ec_manager_xattr, callback, data); if (fop == NULL) { goto out; } @@ -492,16 +490,15 @@ ec_manager_setattr(ec_fop_data_t *fop, int32_t state) if (fop->id == GF_FOP_SETATTR) { if (fop->cbks.setattr != NULL) { - fop->cbks.setattr(fop->req_frame, fop, fop->xl, cbk->op_ret, - cbk->op_errno, &cbk->iatt[0], - &cbk->iatt[1], cbk->xdata); + QUORUM_CBK(fop->cbks.setattr, fop, fop->req_frame, fop, + fop->xl, cbk->op_ret, cbk->op_errno, + &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } else { if (fop->cbks.fsetattr != NULL) { - fop->cbks.fsetattr(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, - &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.fsetattr, fop, fop->req_frame, fop, + fop->xl, cbk->op_ret, cbk->op_errno, + &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } @@ -550,7 +547,7 @@ ec_manager_setattr(ec_fop_data_t *fop, int32_t state) void ec_setattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_setattr_cbk_t func, void *data, loc_t *loc, + uint32_t fop_flags, fop_setattr_cbk_t func, void *data, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_cbk_t callback = {.setattr = func}; @@ -563,9 +560,9 @@ ec_setattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_SETATTR, 0, target, minimum, - ec_wind_setattr, ec_manager_setattr, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_SETATTR, 0, target, + fop_flags, ec_wind_setattr, ec_manager_setattr, + callback, data); if (fop == NULL) { goto out; } @@ -627,7 +624,7 @@ ec_wind_fsetattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) void ec_fsetattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_fsetattr_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_fsetattr_cbk_t func, void *data, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_cbk_t callback = {.fsetattr = func}; @@ -640,9 +637,9 @@ ec_fsetattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETATTR, 0, target, minimum, - ec_wind_fsetattr, ec_manager_setattr, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETATTR, 0, target, + fop_flags, ec_wind_fsetattr, ec_manager_setattr, + callback, data); if (fop == NULL) { goto out; } @@ -707,7 +704,7 @@ ec_wind_setxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) void ec_setxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_setxattr_cbk_t func, void *data, loc_t *loc, + uint32_t fop_flags, fop_setxattr_cbk_t func, void *data, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { ec_cbk_t callback = {.setxattr = func}; @@ -720,9 +717,9 @@ ec_setxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_SETXATTR, 0, target, minimum, - ec_wind_setxattr, ec_manager_xattr, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_SETXATTR, 0, target, + fop_flags, ec_wind_setxattr, ec_manager_xattr, + callback, data); if (fop == NULL) { goto out; } @@ -825,7 +822,7 @@ ec_wind_fsetxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) void ec_fsetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_fsetxattr_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_fsetxattr_cbk_t func, void *data, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { ec_cbk_t callback = {.fsetxattr = func}; @@ -839,7 +836,7 @@ ec_fsetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETXATTR, 0, target, - minimum, ec_wind_fsetxattr, ec_manager_xattr, + fop_flags, ec_wind_fsetxattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; @@ -992,9 +989,9 @@ ec_manager_fallocate(ec_fop_data_t *fop, int32_t state) GF_ASSERT(cbk != NULL); if (fop->cbks.fallocate != NULL) { - fop->cbks.fallocate(fop->req_frame, fop, fop->xl, cbk->op_ret, - cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.fallocate, fop, fop->req_frame, fop, + fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], + &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; @@ -1035,7 +1032,7 @@ ec_manager_fallocate(ec_fop_data_t *fop, int32_t state) void ec_fallocate(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_fallocate_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_fallocate_cbk_t func, void *data, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { ec_cbk_t callback = {.fallocate = func}; @@ -1049,8 +1046,8 @@ ec_fallocate(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FALLOCATE, 0, target, - minimum, ec_wind_fallocate, ec_manager_fallocate, - callback, data); + fop_flags, ec_wind_fallocate, + ec_manager_fallocate, callback, data); if (fop == NULL) { goto out; } @@ -1209,8 +1206,8 @@ ec_manager_discard(ec_fop_data_t *fop, int32_t state) ec_dispatch_all(fop); return EC_STATE_DELAYED_START; } else { - /*Assume discard to have succeeded on mask*/ - fop->good = fop->mask; + /* Assume discard to have succeeded on all bricks */ + ec_succeed_all(fop); } /* Fall through */ @@ -1245,9 +1242,9 @@ ec_manager_discard(ec_fop_data_t *fop, int32_t state) GF_ASSERT(cbk != NULL); if (fop->cbks.discard != NULL) { - fop->cbks.discard(fop->req_frame, fop, fop->xl, cbk->op_ret, - cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.discard, fop, fop->req_frame, fop, fop->xl, + cbk->op_ret, cbk->op_errno, &cbk->iatt[0], + &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; @@ -1289,7 +1286,7 @@ ec_manager_discard(ec_fop_data_t *fop, int32_t state) void ec_discard(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_discard_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_discard_cbk_t func, void *data, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { ec_cbk_t callback = {.discard = func}; @@ -1302,9 +1299,9 @@ ec_discard(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_DISCARD, 0, target, minimum, - ec_wind_discard, ec_manager_discard, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_DISCARD, 0, target, + fop_flags, ec_wind_discard, ec_manager_discard, + callback, data); if (fop == NULL) { goto out; } @@ -1405,6 +1402,7 @@ int32_t ec_manager_truncate(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; + off_t offset_down; switch (state) { case EC_STATE_INIT: @@ -1416,16 +1414,19 @@ ec_manager_truncate(ec_fop_data_t *fop, int32_t state) /* Fall through */ case EC_STATE_LOCK: + offset_down = fop->user_size; + ec_adjust_offset_down(fop->xl->private, &offset_down, _gf_true); + if (fop->id == GF_FOP_TRUNCATE) { ec_lock_prepare_inode( fop, &fop->loc[0], EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, - fop->offset, EC_RANGE_FULL); + offset_down, EC_RANGE_FULL); } else { ec_lock_prepare_fd( fop, fop->fd, EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, - fop->offset, EC_RANGE_FULL); + offset_down, EC_RANGE_FULL); } ec_lock(fop); @@ -1471,17 +1472,15 @@ ec_manager_truncate(ec_fop_data_t *fop, int32_t state) if (fop->id == GF_FOP_TRUNCATE) { if (fop->cbks.truncate != NULL) { - fop->cbks.truncate(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, - &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.truncate, fop, fop->req_frame, fop, + fop->xl, cbk->op_ret, cbk->op_errno, + &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } else { if (fop->cbks.ftruncate != NULL) { - fop->cbks.ftruncate(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, - &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.ftruncate, fop, fop->req_frame, fop, + fop->xl, cbk->op_ret, cbk->op_errno, + &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } @@ -1530,7 +1529,7 @@ ec_manager_truncate(ec_fop_data_t *fop, int32_t state) void ec_truncate(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_truncate_cbk_t func, void *data, loc_t *loc, + uint32_t fop_flags, fop_truncate_cbk_t func, void *data, loc_t *loc, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.truncate = func}; @@ -1543,9 +1542,9 @@ ec_truncate(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_TRUNCATE, 0, target, minimum, - ec_wind_truncate, ec_manager_truncate, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_TRUNCATE, 0, target, + fop_flags, ec_wind_truncate, ec_manager_truncate, + callback, data); if (fop == NULL) { goto out; } @@ -1604,7 +1603,7 @@ ec_wind_ftruncate(ec_t *ec, ec_fop_data_t *fop, int32_t idx) void ec_ftruncate(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_ftruncate_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_ftruncate_cbk_t func, void *data, fd_t *fd, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.ftruncate = func}; @@ -1618,8 +1617,8 @@ ec_ftruncate(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FTRUNCATE, 0, target, - minimum, ec_wind_ftruncate, ec_manager_truncate, - callback, data); + fop_flags, ec_wind_ftruncate, + ec_manager_truncate, callback, data); if (fop == NULL) { goto out; } @@ -1973,6 +1972,23 @@ ec_get_and_merge_stripe(ec_t *ec, ec_fop_data_t *fop, ec_stripe_part_t which) return found; } +static uintptr_t +ec_get_lock_good_mask(inode_t *inode, xlator_t *xl) +{ + ec_lock_t *lock = NULL; + ec_inode_t *ictx = NULL; + LOCK(&inode->lock); + { + ictx = __ec_inode_get(inode, xl); + if (ictx) + lock = ictx->inode_lock; + } + UNLOCK(&inode->lock); + if (lock) + return lock->good_mask; + return 0; +} + void ec_writev_start(ec_fop_data_t *fop) { @@ -2009,20 +2025,29 @@ 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, + ec_get_lock_good_mask(fop->fd->inode, fop->xl), + 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 @@ -2035,8 +2060,10 @@ ec_writev_start(ec_fop_data_t *fop) err = -ENOMEM; goto failed_xdata; } - ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, - ec_writev_merge_tail, NULL, fd, ec->stripe_size, + ec_readv(fop->frame, fop->xl, + ec_get_lock_good_mask(fop->fd->inode, fop->xl), + EC_MINIMUM_MIN, ec_writev_merge_tail, NULL, fd, + ec->stripe_size, fop->offset + fop->size - ec->stripe_size, 0, xdata); } } else { @@ -2211,9 +2238,9 @@ ec_manager_writev(ec_fop_data_t *fop, int32_t state) GF_ASSERT(cbk != NULL); if (fop->cbks.writev != NULL) { - fop->cbks.writev(fop->req_frame, fop, fop->xl, cbk->op_ret, - cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], - cbk->xdata); + QUORUM_CBK(fop->cbks.writev, fop, fop->req_frame, fop, fop->xl, + cbk->op_ret, cbk->op_errno, &cbk->iatt[0], + &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; @@ -2262,7 +2289,7 @@ ec_manager_writev(ec_fop_data_t *fop, int32_t state) void ec_writev(call_frame_t *frame, xlator_t *this, uintptr_t target, - int32_t minimum, fop_writev_cbk_t func, void *data, fd_t *fd, + uint32_t fop_flags, fop_writev_cbk_t func, void *data, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { @@ -2276,7 +2303,7 @@ ec_writev(call_frame_t *frame, xlator_t *this, uintptr_t target, GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = ec_fop_data_allocate(frame, this, GF_FOP_WRITE, 0, target, minimum, + fop = ec_fop_data_allocate(frame, this, GF_FOP_WRITE, 0, target, fop_flags, ec_wind_writev, ec_manager_writev, callback, data); if (fop == NULL) { |
