diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-locks.c')
| -rw-r--r-- | xlators/cluster/ec/src/ec-locks.c | 1083 |
1 files changed, 457 insertions, 626 deletions
diff --git a/xlators/cluster/ec/src/ec-locks.c b/xlators/cluster/ec/src/ec-locks.c index 2e301631b3f..601960d6154 100644 --- a/xlators/cluster/ec/src/ec-locks.c +++ b/xlators/cluster/ec/src/ec-locks.c @@ -8,71 +8,110 @@ cases as published by the Free Software Foundation. */ -#include "xlator.h" -#include "defaults.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" #define EC_LOCK_MODE_NONE 0 -#define EC_LOCK_MODE_INC 1 -#define EC_LOCK_MODE_ALL 2 +#define EC_LOCK_MODE_INC 1 +#define EC_LOCK_MODE_ALL 2 -int32_t ec_lock_check(ec_fop_data_t * fop, ec_cbk_data_t ** cbk, - uintptr_t * mask) +int32_t +ec_lock_check(ec_fop_data_t *fop, uintptr_t *mask) { - ec_t * ec = fop->xl->private; - ec_cbk_data_t * ans = NULL; - uintptr_t locked = 0, notlocked = 0; + ec_t *ec = fop->xl->private; + ec_cbk_data_t *ans = NULL; + ec_cbk_data_t *cbk = NULL; + uintptr_t locked = 0; + int32_t good = 0; + int32_t eagain = 0; + int32_t estale = 0; int32_t error = -1; + /* There are some errors that we'll handle in an special way while trying + * to acquire a lock. + * + * EAGAIN: If it's found during a parallel non-blocking lock request, we + * consider that there's contention on the inode, so we consider + * the acquisition a failure and try again with a sequential + * blocking lock request. This will ensure that we get a lock on + * as many bricks as possible (ignoring EAGAIN here would cause + * unnecessary triggers of self-healing). + * + * If it's found during a sequential blocking lock request, it's + * considered an error. Lock will only succeed if there are + * enough other bricks locked. + * + * ESTALE: This can appear during parallel or sequential lock request if + * the inode has just been unlinked. We consider this error is + * not recoverable, but we also don't consider it as fatal. So, + * if it happens during parallel lock, we won't attempt a + * sequential one unless there are EAGAIN errors on other + * bricks (and are enough to form a quorum), but if we reach + * quorum counting the ESTALE bricks, we consider the whole + * result of the operation is ESTALE instead of EIO. + */ + list_for_each_entry(ans, &fop->cbk_list, list) { - if (ans->op_ret >= 0) - { - if (locked != 0) - { + if (ans->op_ret >= 0) { + if (locked != 0) { error = EIO; } locked |= ans->mask; - *cbk = ans; - } - else if (ans->op_errno == EAGAIN) - { - notlocked |= ans->mask; + good = ans->count; + cbk = ans; + } else if (ans->op_errno == ESTALE) { + estale += ans->count; + } else if ((ans->op_errno == EAGAIN) && + (fop->uint32 != EC_LOCK_MODE_INC)) { + eagain += ans->count; } } - if (error == -1) - { - if (ec_bits_count(locked | notlocked) >= ec->fragments) - { - if (notlocked == 0) - { - fop->answer = *cbk; + if (error == -1) { + /* If we have enough quorum with succeeded and EAGAIN answers, we + * ignore for now any ESTALE answer. If there are EAGAIN answers, + * we retry with a sequential blocking lock request if needed. + * Otherwise we succeed. */ + if ((good + eagain) >= ec->fragments) { + if (eagain == 0) { + if (fop->answer == NULL) { + fop->answer = cbk; + } - ec_update_bad(fop, locked); + ec_update_good(fop, locked); error = 0; - } - else - { - if (fop->uint32 == EC_LOCK_MODE_NONE) - { - error = EAGAIN; - } - else - { - fop->uint32 = EC_LOCK_MODE_INC; + } else { + switch (fop->uint32) { + case EC_LOCK_MODE_NONE: + error = EAGAIN; + break; + case EC_LOCK_MODE_ALL: + fop->uint32 = EC_LOCK_MODE_INC; + break; + default: + /* This shouldn't happen because eagain cannot be > 0 + * when fop->uint32 is EC_LOCK_MODE_INC. */ + error = EIO; + break; } } - } - else - { - error = EIO; + } else { + /* We have been unable to find enough candidates that will be able + * to take the lock. If we have quorum on some answer, we return + * it. Otherwise we check if ESTALE answers allow us to reach + * quorum. If so, we return ESTALE. */ + if (fop->answer && fop->answer->op_ret < 0) { + error = fop->answer->op_errno; + } else if ((good + eagain + estale) >= ec->fragments) { + error = ESTALE; + } else { + error = EIO; + } } } @@ -81,47 +120,26 @@ int32_t ec_lock_check(ec_fop_data_t * fop, ec_cbk_data_t ** cbk, return error; } -uintptr_t ec_lock_handler(ec_fop_data_t * fop, ec_cbk_data_t * cbk, - ec_combine_f combine) +int32_t +ec_lock_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - uintptr_t mask = 0; - - if (fop->uint32 == EC_LOCK_MODE_INC) - { - if (cbk->op_ret < 0) - { - if (cbk->op_errno != ENOTCONN) - { - mask = fop->mask & ~fop->remaining & ~cbk->mask; - fop->remaining = 0; - } - } - } - - ec_combine(cbk, combine); - - return mask; -} - -int32_t ec_lock_unlocked(call_frame_t * frame, void * cookie, - xlator_t * this, int32_t op_ret, int32_t op_errno, - dict_t * xdata) -{ - if (op_ret < 0) - { - gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an entry/inode"); + if (op_ret < 0) { + gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_UNLOCK_FAILED, + "Failed to unlock an entry/inode"); } return 0; } -int32_t ec_lock_lk_unlocked(call_frame_t * frame, void * cookie, - xlator_t * this, int32_t op_ret, int32_t op_errno, - struct gf_flock * flock, dict_t * xdata) +int32_t +ec_lock_lk_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct gf_flock *flock, + dict_t *xdata) { - if (op_ret < 0) - { - gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an lk"); + if (op_ret < 0) { + gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_LK_UNLOCK_FAILED, + "Failed to unlock an lk"); } return 0; @@ -129,11 +147,12 @@ int32_t ec_lock_lk_unlocked(call_frame_t * frame, void * cookie, /* FOP: entrylk */ -int32_t ec_entrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_entrylk_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); @@ -143,46 +162,36 @@ int32_t ec_entrylk_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_ENTRYLK, idx, op_ret, op_errno); - if (cbk != NULL) - { - uintptr_t mask; - - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "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; } } - mask = ec_lock_handler(fop, cbk, NULL); - if (mask != 0) - { - ec_entrylk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked, - NULL, fop->str[0], &fop->loc[0], fop->str[1], - ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); - } + ec_combine(cbk, NULL); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_entrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_entrylk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -192,20 +201,19 @@ void ec_wind_entrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->entrylk_type, fop->xdata); } -int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_entrylk(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: - if (fop->entrylk_cmd == ENTRYLK_LOCK) - { + if (fop->entrylk_cmd == ENTRYLK_LOCK) { fop->uint32 = EC_LOCK_MODE_ALL; fop->entrylk_cmd = ENTRYLK_LOCK_NB; } - /* Fall through */ + /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); @@ -213,46 +221,37 @@ int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: - cbk = fop->answer; - if ((cbk == NULL) || - ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN))) - { + case -EC_STATE_PREPARE_ANSWER: + if (fop->entrylk_cmd != ENTRYLK_UNLOCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &cbk, &mask); - if (fop->error != 0) - { - if (mask != 0) - { - if (fop->id == GF_FOP_ENTRYLK) - { - ec_entrylk(fop->req_frame, fop->xl, mask, 1, - ec_lock_unlocked, NULL, fop->str[0], - &fop->loc[0], fop->str[1], - ENTRYLK_UNLOCK, fop->entrylk_type, - fop->xdata); - } - else - { - ec_fentrylk(fop->req_frame, fop->xl, mask, 1, + ec_fop_set_error(fop, ec_lock_check(fop, &mask)); + if (fop->error != 0) { + if (mask != 0) { + if (fop->id == GF_FOP_ENTRYLK) { + ec_entrylk( + fop->frame, fop->xl, mask, 1, ec_lock_unlocked, + NULL, fop->str[0], &fop->loc[0], fop->str[1], + ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); + } else { + ec_fentrylk(fop->frame, fop->xl, mask, 1, ec_lock_unlocked, NULL, fop->str[0], fop->fd, fop->str[1], ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); } } - if (fop->error > 0) - { - return EC_STATE_REPORT; - } + if (fop->error < 0) { + fop->error = 0; - fop->error = 0; + fop->entrylk_cmd = ENTRYLK_LOCK; - fop->entrylk_cmd = ENTRYLK_LOCK; + ec_dispatch_inc(fop); - ec_dispatch_inc(fop); - - return EC_STATE_PREPARE_ANSWER; + return EC_STATE_PREPARE_ANSWER; + } } + } else { + ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; @@ -262,125 +261,104 @@ int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->id == GF_FOP_ENTRYLK) - { - if (fop->cbks.entrylk != NULL) - { - fop->cbks.entrylk(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, cbk->xdata); + if (fop->id == GF_FOP_ENTRYLK) { + if (fop->cbks.entrylk != NULL) { + fop->cbks.entrylk(fop->req_frame, fop, fop->xl, cbk->op_ret, + cbk->op_errno, cbk->xdata); } - } - else - { - if (fop->cbks.fentrylk != NULL) - { + } else { + if (fop->cbks.fentrylk != NULL) { fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } - ec_wait_winds(fop); - 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->id == GF_FOP_ENTRYLK) - { - if (fop->cbks.entrylk != NULL) - { + if (fop->id == GF_FOP_ENTRYLK) { + if (fop->cbks.entrylk != NULL) { fop->cbks.entrylk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } - } - else - { - if (fop->cbks.fentrylk != NULL) - { + } else { + if (fop->cbks.fentrylk != NULL) { fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } - ec_wait_winds(fop); - return EC_STATE_END; default: - gf_log(fop->xl->name, GF_LOG_ERROR, "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_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_entrylk_cbk_t func, void * data, - const char * volume, loc_t * loc, const char * basename, - entrylk_cmd cmd, entrylk_type type, dict_t * xdata) +void +ec_entrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_entrylk_cbk_t func, void *data, + const char *volume, loc_t *loc, const char *basename, + entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { - ec_cbk_t callback = { .entrylk = func }; - ec_fop_data_t * fop = NULL; - int32_t error = EIO; + ec_cbk_t callback = {.entrylk = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; - gf_log("ec", GF_LOG_TRACE, "EC(ENTRYLK) %p", frame); + gf_msg_trace("ec", 0, "EC(ENTRYLK) %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_ENTRYLK, - EC_FLAG_UPDATE_LOC_INODE, target, minimum, - ec_wind_entrylk, ec_manager_entrylk, callback, - data); - if (fop == NULL) - { + fop = ec_fop_data_allocate(frame, this, GF_FOP_ENTRYLK, 0, target, + fop_flags, ec_wind_entrylk, ec_manager_entrylk, + callback, data); + if (fop == NULL) { goto out; } fop->entrylk_cmd = cmd; fop->entrylk_type = type; - if (volume != NULL) - { + if (volume != NULL) { fop->str[0] = gf_strdup(volume); - if (fop->str[0] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[0] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (loc != NULL) - { - if (loc_copy(&fop->loc[0], loc) != 0) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location."); + 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."); goto out; } } - if (basename != NULL) - { + if (basename != NULL) { fop->str[1] = gf_strdup(basename); - if (fop->str[1] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[1] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (xdata != NULL) - { + if (xdata != NULL) { fop->xdata = dict_ref(xdata); - if (fop->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "dictionary."); + if (fop->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -389,23 +367,21 @@ void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, error = 0; out: - if (fop != NULL) - { + if (fop != NULL) { ec_manager(fop, error); - } - else - { - func(frame, NULL, this, -1, EIO, NULL); + } else { + func(frame, NULL, this, -1, error, NULL); } } /* FOP: fentrylk */ -int32_t ec_fentrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_fentrylk_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); @@ -415,46 +391,36 @@ int32_t ec_fentrylk_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_FENTRYLK, idx, op_ret, op_errno); - if (cbk != NULL) - { - uintptr_t mask; - - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "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; } } - mask = ec_lock_handler(fop, cbk, NULL); - if (mask != 0) - { - ec_fentrylk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked, - NULL, fop->str[0], fop->fd, fop->str[1], - ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); - } + ec_combine(cbk, NULL); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_fentrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_fentrylk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -464,27 +430,25 @@ void ec_wind_fentrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->entrylk_type, fop->xdata); } -void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_fentrylk_cbk_t func, void * data, - const char * volume, fd_t * fd, const char * basename, - entrylk_cmd cmd, entrylk_type type, dict_t * xdata) +void +ec_fentrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, + uint32_t fop_flags, fop_fentrylk_cbk_t func, void *data, + const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - ec_cbk_t callback = { .fentrylk = func }; - ec_fop_data_t * fop = NULL; - int32_t error = EIO; + ec_cbk_t callback = {.fentrylk = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; - gf_log("ec", GF_LOG_TRACE, "EC(FENTRYLK) %p", frame); + gf_msg_trace("ec", 0, "EC(FENTRYLK) %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_FENTRYLK, - EC_FLAG_UPDATE_FD_INODE, target, minimum, - ec_wind_fentrylk, ec_manager_entrylk, callback, - data); - if (fop == NULL) - { + fop = ec_fop_data_allocate(frame, this, GF_FOP_FENTRYLK, 0, target, + fop_flags, ec_wind_fentrylk, ec_manager_entrylk, + callback, data); + if (fop == NULL) { goto out; } @@ -493,44 +457,40 @@ void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, fop->entrylk_cmd = cmd; fop->entrylk_type = type; - if (volume != NULL) - { + if (volume != NULL) { fop->str[0] = gf_strdup(volume); - if (fop->str[0] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[0] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (fd != NULL) - { + if (fd != NULL) { fop->fd = fd_ref(fd); - if (fop->fd == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "file descriptor."); + if (fop->fd == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } } - if (basename != NULL) - { + if (basename != NULL) { fop->str[1] = gf_strdup(basename); - if (fop->str[1] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[1] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (xdata != NULL) - { + if (xdata != NULL) { fop->xdata = dict_ref(xdata); - if (fop->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "dictionary."); + if (fop->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -539,23 +499,21 @@ void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, error = 0; out: - if (fop != NULL) - { + if (fop != NULL) { ec_manager(fop, error); - } - else - { - func(frame, NULL, this, -1, EIO, NULL); + } else { + func(frame, NULL, this, -1, error, NULL); } } /* FOP: inodelk */ -int32_t ec_inodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_inodelk_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); @@ -565,56 +523,36 @@ int32_t ec_inodelk_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_INODELK, idx, op_ret, op_errno); - if (cbk != NULL) - { - uintptr_t mask; - - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "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; } } - mask = ec_lock_handler(fop, cbk, NULL); - if (mask != 0) - { - ec_t * ec = fop->xl->private; - struct gf_flock flock; - - flock.l_type = F_UNLCK; - flock.l_whence = fop->flock.l_whence; - flock.l_start = fop->flock.l_start * ec->fragments; - flock.l_len = fop->flock.l_len * ec->fragments; - flock.l_pid = 0; - flock.l_owner.len = 0; - - ec_inodelk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked, - NULL, fop->str[0], &fop->loc[0], F_SETLK, &flock, - fop->xdata); - } + ec_combine(cbk, NULL); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_inodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_inodelk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -624,24 +562,22 @@ void ec_wind_inodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->xdata); } -int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_inodelk(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: - fop->flock.l_len += ec_adjust_offset(fop->xl->private, - &fop->flock.l_start, 1); - fop->flock.l_len = ec_adjust_size(fop->xl->private, - fop->flock.l_len, 1); - if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) - { + fop->flock.l_len += ec_adjust_offset_down( + fop->xl->private, &fop->flock.l_start, _gf_true); + ec_adjust_offset_up(fop->xl->private, &fop->flock.l_len, _gf_true); + if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) { fop->uint32 = EC_LOCK_MODE_ALL; fop->int32 = F_SETLK; } - /* Fall through */ + /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); @@ -649,18 +585,14 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: - cbk = fop->answer; - if ((cbk == NULL) || - ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN))) - { + case -EC_STATE_PREPARE_ANSWER: + if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &cbk, &mask); - if (fop->error != 0) - { - if (mask != 0) - { - ec_t * ec = fop->xl->private; + ec_fop_set_error(fop, ec_lock_check(fop, &mask)); + if (fop->error != 0) { + if (mask != 0) { + ec_t *ec = fop->xl->private; struct gf_flock flock; flock.l_type = F_UNLCK; @@ -670,33 +602,31 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) flock.l_pid = 0; flock.l_owner.len = 0; - if (fop->id == GF_FOP_INODELK) - { - ec_inodelk(fop->req_frame, fop->xl, mask, 1, + if (fop->id == GF_FOP_INODELK) { + ec_inodelk(fop->frame, fop->xl, + &fop->frame->root->lk_owner, mask, 1, ec_lock_unlocked, NULL, fop->str[0], &fop->loc[0], F_SETLK, &flock, fop->xdata); - } - else - { - ec_finodelk(fop->req_frame, fop->xl, mask, 1, + } else { + ec_finodelk(fop->frame, fop->xl, + &fop->frame->root->lk_owner, mask, 1, ec_lock_unlocked, NULL, fop->str[0], fop->fd, F_SETLK, &flock, fop->xdata); } } - if (fop->error > 0) - { - return EC_STATE_REPORT; - } + if (fop->error < 0) { + fop->error = 0; - fop->error = 0; + fop->int32 = F_SETLKW; - fop->int32 = F_SETLKW; + ec_dispatch_inc(fop); - ec_dispatch_inc(fop); - - return EC_STATE_PREPARE_ANSWER; + return EC_STATE_PREPARE_ANSWER; + } } + } else { + ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; @@ -706,128 +636,108 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->id == GF_FOP_INODELK) - { - if (fop->cbks.inodelk != NULL) - { - fop->cbks.inodelk(fop->req_frame, fop, fop->xl, - cbk->op_ret, cbk->op_errno, cbk->xdata); + if (fop->id == GF_FOP_INODELK) { + if (fop->cbks.inodelk != NULL) { + fop->cbks.inodelk(fop->req_frame, fop, fop->xl, cbk->op_ret, + cbk->op_errno, cbk->xdata); } - } - else - { - if (fop->cbks.finodelk != NULL) - { + } else { + if (fop->cbks.finodelk != NULL) { fop->cbks.finodelk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } - ec_wait_winds(fop); - 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->id == GF_FOP_INODELK) - { - if (fop->cbks.inodelk != NULL) - { + if (fop->id == GF_FOP_INODELK) { + if (fop->cbks.inodelk != NULL) { fop->cbks.inodelk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } - } - else - { - if (fop->cbks.finodelk != NULL) - { + } else { + if (fop->cbks.finodelk != NULL) { fop->cbks.finodelk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } - ec_wait_winds(fop); - return EC_STATE_END; default: - gf_log(fop->xl->name, GF_LOG_ERROR, "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_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_inodelk_cbk_t func, void * data, - const char * volume, loc_t * loc, int32_t cmd, - struct gf_flock * flock, dict_t * xdata) +void +ec_inodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, + uintptr_t target, uint32_t fop_flags, fop_inodelk_cbk_t func, + void *data, const char *volume, loc_t *loc, int32_t cmd, + struct gf_flock *flock, dict_t *xdata) { - ec_cbk_t callback = { .inodelk = func }; - ec_fop_data_t * fop = NULL; - int32_t error = EIO; + ec_cbk_t callback = {.inodelk = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; - gf_log("ec", GF_LOG_TRACE, "EC(INODELK) %p", frame); + gf_msg_trace("ec", 0, "EC(INODELK) %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_INODELK, - EC_FLAG_UPDATE_LOC_INODE, target, minimum, - ec_wind_inodelk, ec_manager_inodelk, callback, - data); - if (fop == NULL) - { + fop = ec_fop_data_allocate(frame, this, GF_FOP_INODELK, 0, target, + fop_flags, ec_wind_inodelk, ec_manager_inodelk, + callback, data); + if (fop == NULL) { goto out; } fop->int32 = cmd; + ec_owner_copy(fop->frame, owner); - if (volume != NULL) - { + if (volume != NULL) { fop->str[0] = gf_strdup(volume); - if (fop->str[0] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[0] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (loc != NULL) - { - if (loc_copy(&fop->loc[0], loc) != 0) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location."); + 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."); goto out; } } - if (flock != NULL) - { + if (flock != NULL) { fop->flock.l_type = flock->l_type; fop->flock.l_whence = flock->l_whence; fop->flock.l_start = flock->l_start; fop->flock.l_len = flock->l_len; fop->flock.l_pid = flock->l_pid; fop->flock.l_owner.len = flock->l_owner.len; - if (flock->l_owner.len > 0) - { + if (flock->l_owner.len > 0) { memcpy(fop->flock.l_owner.data, flock->l_owner.data, flock->l_owner.len); } } - if (xdata != NULL) - { + if (xdata != NULL) { fop->xdata = dict_ref(xdata); - if (fop->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "dictionary."); + if (fop->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -836,23 +746,21 @@ void ec_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target, error = 0; out: - if (fop != NULL) - { + if (fop != NULL) { ec_manager(fop, error); - } - else - { - func(frame, NULL, this, -1, EIO, NULL); + } else { + func(frame, NULL, this, -1, error, NULL); } } /* FOP: finodelk */ -int32_t ec_finodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, dict_t * xdata) +int32_t +ec_finodelk_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); @@ -862,56 +770,36 @@ int32_t ec_finodelk_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_FINODELK, idx, op_ret, op_errno); - if (cbk != NULL) - { - uintptr_t mask; - - if (xdata != NULL) - { + if (cbk != NULL) { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "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; } } - mask = ec_lock_handler(fop, cbk, NULL); - if (mask != 0) - { - ec_t * ec = fop->xl->private; - struct gf_flock flock; - - flock.l_type = F_UNLCK; - flock.l_whence = fop->flock.l_whence; - flock.l_start = fop->flock.l_start * ec->fragments; - flock.l_len = fop->flock.l_len * ec->fragments; - flock.l_pid = 0; - flock.l_owner.len = 0; - - ec_finodelk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked, - NULL, fop->str[0], fop->fd, F_SETLK, &flock, - fop->xdata); - } + ec_combine(cbk, NULL); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_finodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_finodelk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -921,76 +809,71 @@ void ec_wind_finodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->xdata); } -void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_finodelk_cbk_t func, void * data, - const char * volume, fd_t * fd, int32_t cmd, - struct gf_flock * flock, dict_t * xdata) +void +ec_finodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, + uintptr_t target, uint32_t fop_flags, fop_finodelk_cbk_t func, + void *data, const char *volume, fd_t *fd, int32_t cmd, + struct gf_flock *flock, dict_t *xdata) { - ec_cbk_t callback = { .finodelk = func }; - ec_fop_data_t * fop = NULL; - int32_t error = EIO; + ec_cbk_t callback = {.finodelk = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; - gf_log("ec", GF_LOG_TRACE, "EC(FINODELK) %p", frame); + gf_msg_trace("ec", 0, "EC(FINODELK) %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_FINODELK, - EC_FLAG_UPDATE_FD_INODE, target, minimum, - ec_wind_finodelk, ec_manager_inodelk, callback, - data); - if (fop == NULL) - { + fop = ec_fop_data_allocate(frame, this, GF_FOP_FINODELK, 0, target, + fop_flags, ec_wind_finodelk, ec_manager_inodelk, + callback, data); + if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = cmd; + ec_owner_copy(fop->frame, owner); - if (volume != NULL) - { + if (volume != NULL) { fop->str[0] = gf_strdup(volume); - if (fop->str[0] == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string."); + if (fop->str[0] == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } } - if (fd != NULL) - { + if (fd != NULL) { fop->fd = fd_ref(fd); - if (fop->fd == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "file descriptor."); + if (fop->fd == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } } - if (flock != NULL) - { + if (flock != NULL) { fop->flock.l_type = flock->l_type; fop->flock.l_whence = flock->l_whence; fop->flock.l_start = flock->l_start; fop->flock.l_len = flock->l_len; fop->flock.l_pid = flock->l_pid; fop->flock.l_owner.len = flock->l_owner.len; - if (flock->l_owner.len > 0) - { + if (flock->l_owner.len > 0) { memcpy(fop->flock.l_owner.data, flock->l_owner.data, flock->l_owner.len); } } - if (xdata != NULL) - { + if (xdata != NULL) { fop->xdata = dict_ref(xdata); - if (fop->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "dictionary."); + if (fop->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -999,25 +882,22 @@ void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target, error = 0; out: - if (fop != NULL) - { + if (fop != NULL) { ec_manager(fop, error); - } - else - { - func(frame, NULL, this, -1, EIO, NULL); + } else { + func(frame, NULL, this, -1, error, NULL); } } /* FOP: lk */ -int32_t ec_combine_lk(ec_fop_data_t * fop, ec_cbk_data_t * dst, - ec_cbk_data_t * src) +int32_t +ec_combine_lk(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { - if (!ec_flock_compare(&dst->flock, &src->flock)) - { - gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching lock in " - "answers of 'GF_FOP_LK'"); + if (!ec_flock_compare(&dst->flock, &src->flock)) { + gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_LOCK_MISMATCH, + "Mismatching lock in " + "answers of 'GF_FOP_LK'"); return 0; } @@ -1025,12 +905,12 @@ int32_t ec_combine_lk(ec_fop_data_t * fop, ec_cbk_data_t * dst, return 1; } -int32_t ec_lk_cbk(call_frame_t * frame, void * cookie, xlator_t * this, - int32_t op_ret, int32_t op_errno, struct gf_flock * flock, - dict_t * xdata) +int32_t +ec_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, struct gf_flock *flock, 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); @@ -1040,72 +920,50 @@ int32_t ec_lk_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_LK, idx, op_ret, op_errno); - if (cbk != NULL) - { - uintptr_t mask; - - if (op_ret >= 0) - { - if (flock != NULL) - { + if (cbk != NULL) { + if (op_ret >= 0) { + if (flock != NULL) { cbk->flock.l_type = flock->l_type; cbk->flock.l_whence = flock->l_whence; cbk->flock.l_start = flock->l_start; cbk->flock.l_len = flock->l_len; cbk->flock.l_pid = flock->l_pid; cbk->flock.l_owner.len = flock->l_owner.len; - if (flock->l_owner.len > 0) - { + if (flock->l_owner.len > 0) { memcpy(cbk->flock.l_owner.data, flock->l_owner.data, flock->l_owner.len); } } } - if (xdata != NULL) - { + if (xdata != NULL) { cbk->xdata = dict_ref(xdata); - if (cbk->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "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; } } - mask = ec_lock_handler(fop, cbk, ec_combine_lk); - if (mask != 0) - { - ec_t * ec = fop->xl->private; - struct gf_flock flock; - - flock.l_type = F_UNLCK; - flock.l_whence = fop->flock.l_whence; - flock.l_start = fop->flock.l_start * ec->fragments; - flock.l_len = fop->flock.l_len * ec->fragments; - flock.l_pid = 0; - flock.l_owner.len = 0; - - ec_lk(fop->req_frame, fop->xl, mask, 1, ec_lock_lk_unlocked, NULL, - fop->fd, F_SETLK, &flock, fop->xdata); - } + ec_combine(cbk, ec_combine_lk); } out: - if (fop != NULL) - { + if (fop != NULL) { ec_complete(fop); } return 0; } -void ec_wind_lk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) +void +ec_wind_lk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); @@ -1114,24 +972,19 @@ void ec_wind_lk(ec_t * ec, ec_fop_data_t * fop, int32_t idx) fop->int32, &fop->flock, fop->xdata); } -int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_lk(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: - fop->flock.l_len += ec_adjust_offset(fop->xl->private, - &fop->flock.l_start, 1); - fop->flock.l_len = ec_adjust_size(fop->xl->private, - fop->flock.l_len, 1); - if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) - { + if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) { fop->uint32 = EC_LOCK_MODE_ALL; fop->int32 = F_SETLK; } - /* Fall through */ + /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); @@ -1139,44 +992,38 @@ int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: - cbk = fop->answer; - if ((cbk == NULL) || - ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN))) - { + case -EC_STATE_PREPARE_ANSWER: + if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &cbk, &mask); - if (fop->error != 0) - { - if (mask != 0) - { - ec_t * ec = fop->xl->private; - struct gf_flock flock; + ec_fop_set_error(fop, ec_lock_check(fop, &mask)); + if (fop->error != 0) { + if (mask != 0) { + struct gf_flock flock = {0}; flock.l_type = F_UNLCK; flock.l_whence = fop->flock.l_whence; - flock.l_start = fop->flock.l_start * ec->fragments; - flock.l_len = fop->flock.l_len * ec->fragments; - flock.l_pid = 0; - flock.l_owner.len = 0; + flock.l_start = fop->flock.l_start; + flock.l_len = fop->flock.l_len; + flock.l_pid = fop->flock.l_pid; + lk_owner_copy(&flock.l_owner, &fop->flock.l_owner); - ec_lk(fop->req_frame, fop->xl, mask, 1, - ec_lock_lk_unlocked, NULL, fop->fd, F_SETLK, - &flock, fop->xdata); - } - if (fop->error > 0) - { - return EC_STATE_REPORT; + ec_lk(fop->frame, fop->xl, mask, 1, ec_lock_lk_unlocked, + NULL, fop->fd, F_SETLK, &flock, fop->xdata); } - fop->error = 0; + if (fop->error < 0) { + fop->error = 0; - fop->int32 = F_SETLKW; + fop->int32 = F_SETLKW; - ec_dispatch_inc(fop); + ec_dispatch_inc(fop); - return EC_STATE_PREPARE_ANSWER; + return EC_STATE_PREPARE_ANSWER; + } } + } else { + ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; @@ -1186,59 +1033,50 @@ int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state) GF_ASSERT(cbk != NULL); - if (fop->cbks.lk != NULL) - { + if (fop->cbks.lk != NULL) { fop->cbks.lk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->flock, cbk->xdata); } - ec_wait_winds(fop); - 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.lk != NULL) - { - fop->cbks.lk(fop->req_frame, fop, fop->xl, -1, fop->error, - NULL, NULL); + if (fop->cbks.lk != NULL) { + fop->cbks.lk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, + NULL); } - ec_wait_winds(fop); - return EC_STATE_END; default: - gf_log(fop->xl->name, GF_LOG_ERROR, "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_lk(call_frame_t * frame, xlator_t * this, uintptr_t target, - int32_t minimum, fop_lk_cbk_t func, void * data, fd_t * fd, - int32_t cmd, struct gf_flock * flock, dict_t * xdata) +void +ec_lk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, + fop_lk_cbk_t func, void *data, fd_t *fd, int32_t cmd, + struct gf_flock *flock, dict_t *xdata) { - ec_cbk_t callback = { .lk = func }; - ec_fop_data_t * fop = NULL; - int32_t error = EIO; + ec_cbk_t callback = {.lk = func}; + ec_fop_data_t *fop = NULL; + int32_t error = ENOMEM; - gf_log("ec", GF_LOG_TRACE, "EC(LK) %p", frame); + gf_msg_trace("ec", 0, "EC(LK) %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_LK, EC_FLAG_UPDATE_FD_INODE, - target, minimum, ec_wind_lk, ec_manager_lk, - callback, data); - if (fop == NULL) - { + fop = ec_fop_data_allocate(frame, this, GF_FOP_LK, 0, target, fop_flags, + ec_wind_lk, ec_manager_lk, callback, data); + if (fop == NULL) { goto out; } @@ -1246,38 +1084,34 @@ void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target, fop->int32 = cmd; - if (fd != NULL) - { + if (fd != NULL) { fop->fd = fd_ref(fd); - if (fop->fd == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "file descriptor."); + if (fop->fd == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } } - if (flock != NULL) - { + if (flock != NULL) { fop->flock.l_type = flock->l_type; fop->flock.l_whence = flock->l_whence; fop->flock.l_start = flock->l_start; fop->flock.l_len = flock->l_len; fop->flock.l_pid = flock->l_pid; fop->flock.l_owner.len = flock->l_owner.len; - if (flock->l_owner.len > 0) - { + if (flock->l_owner.len > 0) { memcpy(fop->flock.l_owner.data, flock->l_owner.data, flock->l_owner.len); } } - if (xdata != NULL) - { + if (xdata != NULL) { fop->xdata = dict_ref(xdata); - if (fop->xdata == NULL) - { - gf_log(this->name, GF_LOG_ERROR, "Failed to reference a " - "dictionary."); + if (fop->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "dictionary."); goto out; } @@ -1286,12 +1120,9 @@ void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target, error = 0; out: - if (fop != NULL) - { + if (fop != NULL) { ec_manager(fop, error); - } - else - { - func(frame, NULL, this, -1, EIO, NULL, NULL); + } else { + func(frame, NULL, this, -1, error, NULL, NULL); } } |
