diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-generic.c')
| -rw-r--r-- | xlators/cluster/ec/src/ec-generic.c | 935 |
1 files changed, 539 insertions, 396 deletions
diff --git a/xlators/cluster/ec/src/ec-generic.c b/xlators/cluster/ec/src/ec-generic.c index 375e49e695c..884deb93669 100644 --- a/xlators/cluster/ec/src/ec-generic.c +++ b/xlators/cluster/ec/src/ec-generic.c @@ -8,24 +8,23 @@ cases as published by the Free Software Foundation. */ -#include "xlator.h" -#include "defaults.h" +#include <glusterfs/byte-order.h> +#include "ec.h" +#include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" -#include "ec-method.h" #include "ec-fops.h" -#include "ec-messages.h" -#include "byte-order.h" /* FOP: flush */ -int32_t ec_flush_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, dict_t *xdata) { - ec_fop_data_t * fop = NULL; - ec_cbk_data_t * cbk = NULL; + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); @@ -35,21 +34,18 @@ int32_t ec_flush_cbk(call_frame_t * frame, void * cookie, xlator_t * this, fop = frame->local; - ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FLUSH, idx, op_ret, op_errno); - if (cbk != NULL) - { - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -59,15 +55,15 @@ int32_t ec_flush_cbk(call_frame_t * frame, void * cookie, xlator_t * this, } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_flush(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_flush(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -76,15 +72,15 @@ void ec_wind_flush(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->xdata); } -int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_flush(ec_fop_data_t *fop, int32_t state) { - ec_cbk_data_t * cbk; + ec_cbk_data_t *cbk; - switch (state) - { + switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_prepare_fd(fop, fop->fd, 0); + ec_lock_prepare_fd(fop, fop->fd, 0, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; @@ -109,8 +105,7 @@ int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.flush != NULL) - { + if (fop->cbks.flush != NULL) { fop->cbks.flush(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } @@ -125,8 +120,7 @@ int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state) case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); - if (fop->cbks.flush != NULL) - { + if (fop->cbks.flush != NULL) { fop->cbks.flush(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } @@ -146,31 +140,71 @@ int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_flush_cbk_t func, void * data, fd_t * fd, - dict_t * xdata) +static int32_t +ec_validate_fd(fd_t *fd, xlator_t *xl) +{ + uint64_t iversion = 0; + uint64_t fversion = 0; + ec_inode_t *inode_ctx = NULL; + ec_fd_t *fd_ctx = NULL; + + LOCK(&fd->lock); + { + fd_ctx = __ec_fd_get(fd, xl); + if (fd_ctx) { + fversion = fd_ctx->bad_version; + } + } + UNLOCK(&fd->lock); + + LOCK(&fd->inode->lock); + { + inode_ctx = __ec_inode_get(fd->inode, xl); + if (inode_ctx) { + iversion = inode_ctx->bad_version; + } + } + UNLOCK(&fd->inode->lock); + if (fversion < iversion) { + return EBADF; + } + return 0; +} + +void +ec_flush(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_flush_cbk_t func, void *data, fd_t *fd, + dict_t *xdata) { - ec_cbk_t callback = { .flush = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.flush = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(FLUSH) %p", frame); + gf_msg_trace("ec", 0, "EC(FLUSH) %p", frame); VALIDATE_OR_GOTO(this, out); 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_FLUSH, 0, target, minimum, - ec_wind_flush, ec_manager_flush, callback, - data); + if (fd) { + error = ec_validate_fd(fd, this); + if (error) { + gf_msg(this->name, GF_LOG_ERROR, EBADF, EC_MSG_FD_BAD, + "Failing %s on %s", gf_fop_list[GF_FOP_FLUSH], + fd->inode ? uuid_utoa(fd->inode->gfid) : ""); + goto out; + } + } + + fop = ec_fop_data_allocate(frame, this, GF_FOP_FLUSH, 0, target, fop_flags, + ec_wind_flush, ec_manager_flush, callback, data); if (fop == NULL) { goto out; } @@ -180,9 +214,9 @@ void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target, if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " - "file descriptor."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } @@ -190,9 +224,9 @@ void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -210,13 +244,13 @@ out: /* FOP: fsync */ -int32_t ec_combine_fsync(ec_fop_data_t * fop, ec_cbk_data_t * dst, - ec_cbk_data_t * src) +int32_t +ec_combine_fsync(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 2)) { - gf_msg (fop->xl->name, GF_LOG_NOTICE, 0, - EC_MSG_IATT_MISMATCH, "Mismatching iatt in " - "answers of 'GF_FOP_FSYNC'"); + gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, + "Mismatching iatt in " + "answers of 'GF_FOP_FSYNC'"); return 0; } @@ -224,12 +258,13 @@ int32_t ec_combine_fsync(ec_fop_data_t * fop, ec_cbk_data_t * dst, return 1; } -int32_t ec_fsync_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, struct iatt * prebuf, - struct iatt * postbuf, dict_t * xdata) +int32_t +ec_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, + dict_t *xdata) { - ec_fop_data_t * fop = NULL; - ec_cbk_data_t * cbk = NULL; + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); @@ -239,32 +274,26 @@ int32_t ec_fsync_cbk(call_frame_t * frame, void * cookie, xlator_t * this, fop = frame->local; - ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNC, idx, op_ret, op_errno); - if (cbk != NULL) - { - if (op_ret >= 0) - { - if (prebuf != NULL) - { + if (cbk != NULL) { + if (op_ret >= 0) { + if (prebuf != NULL) { cbk->iatt[0] = *prebuf; } - if (postbuf != NULL) - { + if (postbuf != NULL) { cbk->iatt[1] = *postbuf; } } - if (xdata != NULL) - { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -274,15 +303,15 @@ int32_t ec_fsync_cbk(call_frame_t * frame, void * cookie, xlator_t * this, } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_fsync(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_fsync(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -291,15 +320,15 @@ void ec_wind_fsync(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->int32, fop->xdata); } -int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_fsync(ec_fop_data_t *fop, int32_t state) { - ec_cbk_data_t * cbk; + ec_cbk_data_t *cbk; - switch (state) - { + switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO); + ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; @@ -317,8 +346,7 @@ int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { - ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, - cbk->count); + ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->fd->inode, @@ -333,8 +361,7 @@ int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.fsync != NULL) - { + if (fop->cbks.fsync != NULL) { fop->cbks.fsync(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); @@ -350,8 +377,7 @@ int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) case -EC_STATE_DELAYED_START: GF_ASSERT(fop->error != 0); - if (fop->cbks.fsync != NULL) - { + if (fop->cbks.fsync != NULL) { fop->cbks.fsync(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } @@ -371,31 +397,40 @@ int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_fsync_cbk_t func, void * data, fd_t * fd, - int32_t datasync, dict_t * xdata) +void +ec_fsync(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_fsync_cbk_t func, void *data, fd_t *fd, + int32_t datasync, dict_t *xdata) { - ec_cbk_t callback = { .fsync = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.fsync = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(FSYNC) %p", frame); + gf_msg_trace("ec", 0, "EC(FSYNC) %p", frame); VALIDATE_OR_GOTO(this, out); 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_FSYNC, 0, target, minimum, - ec_wind_fsync, ec_manager_fsync, callback, - data); + if (fd) { + error = ec_validate_fd(fd, this); + if (error) { + gf_msg(this->name, GF_LOG_ERROR, EBADF, EC_MSG_FD_BAD, + "Failing %s on %s", gf_fop_list[GF_FOP_FSYNC], + fd->inode ? uuid_utoa(fd->inode->gfid) : ""); + goto out; + } + } + + fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNC, 0, target, fop_flags, + ec_wind_fsync, ec_manager_fsync, callback, data); if (fop == NULL) { goto out; } @@ -407,9 +442,9 @@ void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target, if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " - "file descriptor."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } @@ -417,9 +452,9 @@ void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -437,11 +472,12 @@ out: /* FOP: fsyncdir */ -int32_t ec_fsyncdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - ec_fop_data_t * fop = NULL; - ec_cbk_data_t * cbk = NULL; + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); @@ -451,21 +487,18 @@ int32_t ec_fsyncdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this, fop = frame->local; - ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNCDIR, idx, op_ret, op_errno); - if (cbk != NULL) - { - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -475,15 +508,15 @@ int32_t ec_fsyncdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this, } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_fsyncdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_fsyncdir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -492,15 +525,15 @@ void ec_wind_fsyncdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->fd, fop->int32, fop->xdata); } -int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_fsyncdir(ec_fop_data_t *fop, int32_t state) { - ec_cbk_data_t * cbk; + ec_cbk_data_t *cbk; - switch (state) - { + switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_prepare_fd(fop, fop->fd, 0); + ec_lock_prepare_fd(fop, fop->fd, 0, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; @@ -525,8 +558,7 @@ int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.fsyncdir != NULL) - { + if (fop->cbks.fsyncdir != NULL) { fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } @@ -541,10 +573,9 @@ int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state) case -EC_STATE_DELAYED_START: GF_ASSERT(fop->error != 0); - if (fop->cbks.fsyncdir != NULL) - { - fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, -1, - fop->error, NULL); + if (fop->cbks.fsyncdir != NULL) { + fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, -1, fop->error, + NULL); } return EC_STATE_LOCK_REUSE; @@ -562,30 +593,30 @@ int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_fsyncdir_cbk_t func, void * data, - fd_t * fd, int32_t datasync, dict_t * xdata) +void +ec_fsyncdir(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_fsyncdir_cbk_t func, void *data, fd_t *fd, + int32_t datasync, dict_t *xdata) { - ec_cbk_t callback = { .fsyncdir = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.fsyncdir = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(FSYNCDIR) %p", frame); + gf_msg_trace("ec", 0, "EC(FSYNCDIR) %p", frame); VALIDATE_OR_GOTO(this, out); 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_FSYNCDIR, 0, target, - minimum, ec_wind_fsyncdir, ec_manager_fsyncdir, + fop_flags, ec_wind_fsyncdir, ec_manager_fsyncdir, callback, data); if (fop == NULL) { goto out; @@ -598,9 +629,9 @@ void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target, if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " - "file descriptor."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } @@ -608,9 +639,9 @@ void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -628,9 +659,10 @@ out: /* FOP: lookup */ -void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk) +void +ec_lookup_rebuild(ec_t *ec, ec_fop_data_t *fop, ec_cbk_data_t *cbk) { - ec_inode_t * ctx = NULL; + ec_inode_t *ctx = NULL; uint64_t size = 0; int32_t have_size = 0, err; @@ -649,8 +681,7 @@ void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk) LOCK(&cbk->inode->lock); ctx = __ec_inode_get(cbk->inode, fop->xl); - if (ctx != NULL) - { + if (ctx != NULL) { if (ctx->have_version) { cbk->version[0] = ctx->post_version[0]; cbk->version[1] = ctx->post_version[1]; @@ -663,24 +694,22 @@ void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk) UNLOCK(&cbk->inode->lock); - if (cbk->iatt[0].ia_type == IA_IFREG) - { + if (cbk->iatt[0].ia_type == IA_IFREG) { cbk->size = cbk->iatt[0].ia_size; ec_dict_del_number(cbk->xdata, EC_XATTR_SIZE, &cbk->iatt[0].ia_size); - if (have_size) - { + if (have_size) { cbk->iatt[0].ia_size = size; } } } -int32_t ec_combine_lookup(ec_fop_data_t * fop, ec_cbk_data_t * dst, - ec_cbk_data_t * src) +int32_t +ec_combine_lookup(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 2)) { - gf_msg (fop->xl->name, GF_LOG_NOTICE, 0, - EC_MSG_IATT_MISMATCH, "Mismatching iatt in " - "answers of 'GF_FOP_LOOKUP'"); + gf_msg(fop->xl->name, GF_LOG_DEBUG, 0, EC_MSG_IATT_MISMATCH, + "Mismatching iatt in " + "answers of 'GF_FOP_LOOKUP'"); return 0; } @@ -688,14 +717,15 @@ int32_t ec_combine_lookup(ec_fop_data_t * fop, ec_cbk_data_t * dst, return 1; } -int32_t ec_lookup_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, inode_t * inode, - struct iatt * buf, dict_t * xdata, - struct iatt * postparent) +int32_t +ec_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, + struct iatt *postparent) { - ec_fop_data_t * fop = NULL; - ec_cbk_data_t * cbk = NULL; + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; + uint64_t dirty[2] = {0}; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); @@ -704,64 +734,54 @@ int32_t ec_lookup_cbk(call_frame_t * frame, void * cookie, xlator_t * this, fop = frame->local; - ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LOOKUP, idx, op_ret, op_errno); - if (cbk != NULL) - { - if (op_ret >= 0) - { - if (inode != NULL) - { + if (cbk != NULL) { + if (op_ret >= 0) { + if (inode != NULL) { cbk->inode = inode_ref(inode); - if (cbk->inode == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_INODE_REF_FAIL, - "Failed to reference an inode."); + if (cbk->inode == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_INODE_REF_FAIL, + "Failed to reference an inode."); goto out; } } - if (buf != NULL) - { + if (buf != NULL) { cbk->iatt[0] = *buf; } - if (postparent != NULL) - { + if (postparent != NULL) { cbk->iatt[1] = *postparent; } } - if (xdata != NULL) - { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } - ec_dict_del_array (xdata, EC_XATTR_DIRTY, cbk->dirty, - EC_VERSION_SIZE); + ec_dict_del_array(xdata, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); } ec_combine(cbk, ec_combine_lookup); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_lookup(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_lookup(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -770,20 +790,21 @@ void ec_wind_lookup(ec_t * ec, ec_fop_data_t * fop, int32_t idx) &fop->loc[0], fop->xdata); } -int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_lookup(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; int32_t err; - switch (state) - { + switch (state) { case EC_STATE_INIT: if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { - gf_msg (fop->xl->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_LOOKUP_REQ_PREP_FAIL, "Unable to prepare " - "lookup request"); + gf_msg(fop->xl->name, GF_LOG_ERROR, ENOMEM, + EC_MSG_LOOKUP_REQ_PREP_FAIL, + "Unable to prepare " + "lookup request"); fop->error = ENOMEM; @@ -791,7 +812,7 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) } } else { /*TODO: To be handled once we have 'syndromes' */ - dict_del (fop->xdata, GF_CONTENT_KEY); + dict_del(fop->xdata, GF_CONTENT_KEY); } err = dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0); if (err == 0) { @@ -801,16 +822,17 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) err = dict_set_uint64(fop->xdata, EC_XATTR_DIRTY, 0); } if (err != 0) { - gf_msg (fop->xl->name, GF_LOG_ERROR, -err, - EC_MSG_LOOKUP_REQ_PREP_FAIL, "Unable to prepare lookup " - "request"); + gf_msg(fop->xl->name, GF_LOG_ERROR, -err, + EC_MSG_LOOKUP_REQ_PREP_FAIL, + "Unable to prepare lookup " + "request"); fop->error = -err; return EC_STATE_REPORT; } - /* Fall through */ + /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); @@ -826,8 +848,8 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) */ if (!fop->answer && !list_empty(&fop->cbk_list)) { - fop->answer = list_entry (fop->cbk_list.next, ec_cbk_data_t, - list); + fop->answer = list_entry(fop->cbk_list.next, ec_cbk_data_t, + list); } cbk = ec_fop_prepare_answer(fop, _gf_true); @@ -844,8 +866,7 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.lookup != NULL) - { + if (fop->cbks.lookup != NULL) { fop->cbks.lookup(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->inode, &cbk->iatt[0], cbk->xdata, &cbk->iatt[1]); @@ -859,8 +880,7 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); - if (fop->cbks.lookup != NULL) - { + if (fop->cbks.lookup != NULL) { fop->cbks.lookup(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL); } @@ -868,30 +888,30 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_lookup_cbk_t func, void * data, - loc_t * loc, dict_t * xdata) +void +ec_lookup(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_lookup_cbk_t func, void *data, loc_t *loc, + dict_t *xdata) { - ec_cbk_t callback = { .lookup = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.lookup = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(LOOKUP) %p", frame); + gf_msg_trace("ec", 0, "EC(LOOKUP) %p", frame); VALIDATE_OR_GOTO(this, out); 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_LOOKUP, EC_FLAG_LOCK_SHARED, - target, minimum, ec_wind_lookup, + target, fop_flags, ec_wind_lookup, ec_manager_lookup, callback, data); if (fop == NULL) { goto out; @@ -899,14 +919,14 @@ void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target, if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, + "Failed to copy a location."); goto out; } } if (xdata != NULL) { - fop->xdata = dict_copy_with_ref (xdata, NULL); + fop->xdata = dict_copy_with_ref(xdata, NULL); /* Do not log failures here as a memory problem would have already * been logged by the corresponding alloc functions */ if (fop->xdata == NULL) @@ -925,20 +945,20 @@ out: /* FOP: statfs */ -int32_t ec_combine_statfs(ec_fop_data_t * fop, ec_cbk_data_t * dst, - ec_cbk_data_t * src) +int32_t +ec_combine_statfs(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { ec_statvfs_combine(&dst->statvfs, &src->statvfs); return 1; } -int32_t ec_statfs_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, struct statvfs * buf, - dict_t * xdata) +int32_t +ec_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, struct statvfs *buf, dict_t *xdata) { - ec_fop_data_t * fop = NULL; - ec_cbk_data_t * cbk = NULL; + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); @@ -948,28 +968,23 @@ int32_t ec_statfs_cbk(call_frame_t * frame, void * cookie, xlator_t * this, fop = frame->local; - ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STATFS, idx, op_ret, op_errno); - if (cbk != NULL) - { - if (op_ret >= 0) - { - if (buf != NULL) - { + if (cbk != NULL) { + if (op_ret >= 0) { + if (buf != NULL) { cbk->statvfs = *buf; } } - if (xdata != NULL) - { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -979,15 +994,15 @@ int32_t ec_statfs_cbk(call_frame_t * frame, void * cookie, xlator_t * this, } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_statfs(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_statfs(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -996,14 +1011,14 @@ void ec_wind_statfs(ec_t * ec, ec_fop_data_t * fop, int32_t idx) &fop->loc[0], fop->xdata); } -int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) +int32_t +ec_manager_statfs(ec_fop_data_t *fop, int32_t state) { - ec_cbk_data_t *cbk = NULL; - gf_boolean_t deem_statfs_enabled = _gf_false; - int32_t err = 0; + ec_cbk_data_t *cbk = NULL; + gf_boolean_t deem_statfs_enabled = _gf_false; + int32_t err = 0; - switch (state) - { + switch (state) { case EC_STATE_INIT: case EC_STATE_DISPATCH: ec_dispatch_all(fop); @@ -1016,8 +1031,8 @@ int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) ec_t *ec = fop->xl->private; if (cbk->xdata) { - err = dict_get_int8 (cbk->xdata, "quota-deem-statfs", - (int8_t *)&deem_statfs_enabled); + err = dict_get_int8(cbk->xdata, "quota-deem-statfs", + (int8_t *)&deem_statfs_enabled); if (err != -ENOENT) { ec_cbk_set_error(cbk, -err, _gf_true); } @@ -1037,8 +1052,7 @@ int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.statfs != NULL) - { + if (fop->cbks.statfs != NULL) { fop->cbks.statfs(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->statvfs, cbk->xdata); } @@ -1051,8 +1065,7 @@ int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); - if (fop->cbks.statfs != NULL) - { + if (fop->cbks.statfs != NULL) { fop->cbks.statfs(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } @@ -1060,30 +1073,30 @@ int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_statfs_cbk_t func, void * data, - loc_t * loc, dict_t * xdata) +void +ec_statfs(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_statfs_cbk_t func, void *data, loc_t *loc, + dict_t *xdata) { - ec_cbk_t callback = { .statfs = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.statfs = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(STATFS) %p", frame); + gf_msg_trace("ec", 0, "EC(STATFS) %p", frame); VALIDATE_OR_GOTO(this, out); 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_STATFS, EC_FLAG_LOCK_SHARED, - target, minimum, ec_wind_statfs, + target, fop_flags, ec_wind_statfs, ec_manager_statfs, callback, data); if (fop == NULL) { goto out; @@ -1091,8 +1104,8 @@ void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target, if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, + "Failed to copy a location."); goto out; } @@ -1100,9 +1113,9 @@ void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1120,14 +1133,13 @@ out: /* FOP: xattrop */ -int32_t ec_combine_xattrop(ec_fop_data_t *fop, ec_cbk_data_t *dst, - ec_cbk_data_t *src) +int32_t +ec_combine_xattrop(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { - if (!ec_dict_compare(dst->dict, src->dict)) - { - gf_msg (fop->xl->name, GF_LOG_NOTICE, 0, - EC_MSG_DICT_MISMATCH, "Mismatching dictionary in " - "answers of 'GF_FOP_XATTROP'"); + if (!ec_dict_compare(dst->dict, src->dict)) { + gf_msg(fop->xl->name, GF_LOG_DEBUG, 0, EC_MSG_DICT_MISMATCH, + "Mismatching dictionary in " + "answers of 'GF_FOP_XATTROP'"); return 0; } @@ -1136,64 +1148,71 @@ int32_t ec_combine_xattrop(ec_fop_data_t *fop, ec_cbk_data_t *dst, } int32_t -ec_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xattr, - dict_t *xdata) +ec_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { - ec_fop_data_t *fop = NULL; - ec_cbk_data_t *cbk = NULL; - data_t *data; - uint64_t *version; - int32_t idx = (int32_t)(uintptr_t)cookie; + ec_fop_data_t *fop = NULL; + ec_lock_link_t *link = NULL; + ec_cbk_data_t *cbk = NULL; + uint64_t dirty[2] = {0}; + data_t *data; + uint64_t *version; + int32_t idx = (int32_t)(uintptr_t)cookie; - VALIDATE_OR_GOTO (this, out); - GF_VALIDATE_OR_GOTO (this->name, frame, out); - GF_VALIDATE_OR_GOTO (this->name, frame->local, out); - GF_VALIDATE_OR_GOTO (this->name, this->private, out); + VALIDATE_OR_GOTO(this, out); + GF_VALIDATE_OR_GOTO(this->name, frame, out); + GF_VALIDATE_OR_GOTO(this->name, frame->local, out); + GF_VALIDATE_OR_GOTO(this->name, this->private, out); - fop = frame->local; + fop = frame->local; - ec_trace ("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, - frame, op_ret, op_errno); + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); - cbk = ec_cbk_data_allocate (frame, this, fop, fop->id, idx, op_ret, - op_errno); - if (!cbk) - goto out; + cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, + op_errno); + if (!cbk) + goto out; - if (op_ret >= 0) { - cbk->dict = dict_ref (xattr); + if (op_ret >= 0) { + cbk->dict = dict_ref(xattr); - data = dict_get(cbk->dict, EC_XATTR_VERSION); - if ((data != NULL) && (data->len >= sizeof(uint64_t))) { - version = (uint64_t *)data->data; + data = dict_get(cbk->dict, EC_XATTR_VERSION); + if ((data != NULL) && (data->len >= sizeof(uint64_t))) { + version = (uint64_t *)data->data; - if (((ntoh64(version[0]) >> EC_SELFHEAL_BIT) & 1) != 0) { - LOCK(&fop->lock); + if (((ntoh64(version[0]) >> EC_SELFHEAL_BIT) & 1) != 0) { + LOCK(&fop->lock); - fop->healing |= 1ULL << idx; + fop->healing |= 1ULL << idx; - UNLOCK(&fop->lock); - } - } + UNLOCK(&fop->lock); + } + } - ec_dict_del_array (xattr, EC_XATTR_DIRTY, cbk->dirty, - EC_VERSION_SIZE); + ec_dict_del_array(xattr, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); + link = fop->data; + if (link) { + /*Keep a note of if the dirty is already set or not*/ + link->dirty[0] |= (dirty[0] != 0); + link->dirty[1] |= (dirty[1] != 0); } + } - if (xdata) - cbk->xdata = dict_ref(xdata); + if (xdata) + cbk->xdata = dict_ref(xdata); - ec_combine (cbk, ec_combine_xattrop); + ec_combine(cbk, ec_combine_xattrop); out: - if (fop) - ec_complete(fop); + if (fop) + ec_complete(fop); - return 0; + return 0; } -void ec_wind_xattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_xattrop(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -1202,18 +1221,20 @@ void ec_wind_xattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx) &fop->loc[0], fop->xattrop_flags, fop->dict, fop->xdata); } -int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_xattrop(ec_fop_data_t *fop, int32_t state) { - ec_cbk_data_t * cbk; + ec_cbk_data_t *cbk; - switch (state) - { + switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: if (fop->fd == NULL) { - ec_lock_prepare_inode(fop, &fop->loc[0], EC_UPDATE_META); + ec_lock_prepare_inode(fop, &fop->loc[0], EC_UPDATE_META, 0, + EC_RANGE_FULL); } else { - ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_META); + ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_META, 0, + EC_RANGE_FULL); } ec_lock(fop); @@ -1240,19 +1261,13 @@ int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->id == GF_FOP_XATTROP) - { - if (fop->cbks.xattrop != NULL) - { - fop->cbks.xattrop(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, cbk->dict, - cbk->xdata); + if (fop->id == GF_FOP_XATTROP) { + if (fop->cbks.xattrop != NULL) { + fop->cbks.xattrop(fop->req_frame, fop, fop->xl, cbk->op_ret, + cbk->op_errno, cbk->dict, cbk->xdata); } - } - else - { - if (fop->cbks.fxattrop != NULL) - { + } else { + if (fop->cbks.fxattrop != NULL) { fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->dict, cbk->xdata); @@ -1268,18 +1283,13 @@ int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state) case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); - if (fop->id == GF_FOP_XATTROP) - { - if (fop->cbks.xattrop != NULL) - { + if (fop->id == GF_FOP_XATTROP) { + if (fop->cbks.xattrop != NULL) { fop->cbks.xattrop(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } - } - else - { - if (fop->cbks.fxattrop != NULL) - { + } else { + if (fop->cbks.fxattrop != NULL) { fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } @@ -1300,32 +1310,31 @@ int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state) return EC_STATE_END; default: - gf_msg (fop->xl->name, GF_LOG_ERROR, EINVAL, - EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", - state, ec_fop_name(fop->id)); + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } -void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_xattrop_cbk_t func, void * data, - loc_t * loc, gf_xattrop_flags_t optype, dict_t * xattr, - dict_t * xdata) +void +ec_xattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_xattrop_cbk_t func, void *data, loc_t *loc, + gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { - ec_cbk_t callback = { .xattrop = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.xattrop = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(XATTROP) %p", frame); + gf_msg_trace("ec", 0, "EC(XATTROP) %p", frame); VALIDATE_OR_GOTO(this, out); 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_XATTROP, 0, target, minimum, - ec_wind_xattrop, ec_manager_xattrop, callback, - data); + fop = ec_fop_data_allocate(frame, this, GF_FOP_XATTROP, 0, target, + fop_flags, ec_wind_xattrop, ec_manager_xattrop, + callback, data); if (fop == NULL) { goto out; } @@ -1334,8 +1343,8 @@ void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, + "Failed to copy a location."); goto out; } @@ -1343,9 +1352,9 @@ void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xattr != NULL) { fop->dict = dict_ref(xattr); if (fop->dict == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1353,9 +1362,9 @@ void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1371,7 +1380,8 @@ out: } } -void ec_wind_fxattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_fxattrop(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -1380,23 +1390,23 @@ void ec_wind_fxattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->fd, fop->xattrop_flags, fop->dict, fop->xdata); } -void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_fxattrop_cbk_t func, void * data, - fd_t * fd, gf_xattrop_flags_t optype, dict_t * xattr, - dict_t * xdata) +void +ec_fxattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_fxattrop_cbk_t func, void *data, fd_t *fd, + gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { - ec_cbk_t callback = { .fxattrop = func }; - ec_fop_data_t * fop = NULL; + ec_cbk_t callback = {.fxattrop = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "EC(FXATTROP) %p", frame); + gf_msg_trace("ec", 0, "EC(FXATTROP) %p", frame); VALIDATE_OR_GOTO(this, out); 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_FXATTROP, 0, target, - minimum, ec_wind_fxattrop, ec_manager_xattrop, + fop_flags, ec_wind_fxattrop, ec_manager_xattrop, callback, data); if (fop == NULL) { goto out; @@ -1409,9 +1419,9 @@ void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " - "file descriptor."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } @@ -1419,9 +1429,9 @@ void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xattr != NULL) { fop->dict = dict_ref(xattr); if (fop->dict == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1429,9 +1439,9 @@ void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target, if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, - EC_MSG_DICT_REF_FAIL, "Failed to reference a " - "dictionary."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1446,3 +1456,136 @@ out: func(frame, NULL, this, -1, error, NULL, NULL); } } + +/* FOP: IPC */ + +int32_t +ec_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, dict_t *xdata) +{ + ec_fop_data_t *fop = NULL; + ec_cbk_data_t *cbk = NULL; + int32_t idx = (int32_t)(uintptr_t)cookie; + + VALIDATE_OR_GOTO(this, out); + GF_VALIDATE_OR_GOTO(this->name, frame, out); + GF_VALIDATE_OR_GOTO(this->name, frame->local, out); + GF_VALIDATE_OR_GOTO(this->name, this->private, out); + + fop = frame->local; + + ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, + op_ret, op_errno); + + cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_IPC, idx, op_ret, + op_errno); + + if (cbk != NULL) { + if (xdata != NULL) { + cbk->xdata = dict_ref(xdata); + } + + ec_combine(cbk, NULL); + } + +out: + if (fop != NULL) { + ec_complete(fop); + } + + return 0; +} + +void +ec_wind_ipc(ec_t *ec, ec_fop_data_t *fop, int32_t idx) +{ + ec_trace("WIND", fop, "idx=%d", idx); + + STACK_WIND_COOKIE(fop->frame, ec_ipc_cbk, (void *)(uintptr_t)idx, + ec->xl_list[idx], ec->xl_list[idx]->fops->ipc, fop->int32, + fop->xdata); +} + +int32_t +ec_manager_ipc(ec_fop_data_t *fop, int32_t state) +{ + ec_cbk_data_t *cbk; + + switch (state) { + case EC_STATE_INIT: + case EC_STATE_DISPATCH: + ec_dispatch_all(fop); + + return EC_STATE_PREPARE_ANSWER; + + case EC_STATE_PREPARE_ANSWER: + ec_fop_prepare_answer(fop, _gf_true); + + return EC_STATE_REPORT; + + case EC_STATE_REPORT: + cbk = fop->answer; + + GF_ASSERT(cbk != NULL); + if (fop->cbks.ipc != NULL) { + fop->cbks.ipc(fop->req_frame, fop, fop->xl, cbk->op_ret, + cbk->op_errno, cbk->xdata); + } + + return EC_STATE_END; + + case -EC_STATE_INIT: + case -EC_STATE_DISPATCH: + case -EC_STATE_PREPARE_ANSWER: + case -EC_STATE_REPORT: + GF_ASSERT(fop->error != 0); + + if (fop->cbks.ipc != NULL) { + fop->cbks.ipc(fop->req_frame, fop, fop->xl, -1, fop->error, + NULL); + } + + return EC_STATE_END; + + default: + gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, + "Unhandled state %d for %s", state, ec_fop_name(fop->id)); + + return EC_STATE_END; + } +} + +void +ec_ipc(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_ipc_cbk_t func, void *data, int32_t op, + dict_t *xdata) +{ + ec_cbk_t callback = {.ipc = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; + + gf_msg_trace("ec", 0, "EC(IPC) %p", frame); + + VALIDATE_OR_GOTO(this, out); + 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_IPC, 0, target, fop_flags, + ec_wind_ipc, ec_manager_ipc, callback, data); + if (fop == NULL) { + goto out; + } + if (xdata != NULL) { + fop->xdata = dict_ref(xdata); + } + fop->int32 = op; + + error = 0; + +out: + if (fop != NULL) { + ec_manager(fop, error); + } else { + func(frame, NULL, this, -1, error, NULL); + } +} |
