diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-locks.c')
| -rw-r--r-- | xlators/cluster/ec/src/ec-locks.c | 701 |
1 files changed, 330 insertions, 371 deletions
diff --git a/xlators/cluster/ec/src/ec-locks.c b/xlators/cluster/ec/src/ec-locks.c index 7902a99ba84..601960d6154 100644 --- a/xlators/cluster/ec/src/ec-locks.c +++ b/xlators/cluster/ec/src/ec-locks.c @@ -8,52 +8,76 @@ 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, 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; ec_cbk_data_t *cbk = NULL; - uintptr_t locked = 0, notlocked = 0; + uintptr_t locked = 0; + int32_t good = 0; + int32_t eagain = 0; + int32_t estale = 0; int32_t error = -1; - list_for_each_entry(ans, &fop->cbk_list, list) { + /* 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) { error = EIO; } locked |= ans->mask; + good = ans->count; cbk = ans; - } else { - if (ans->op_errno == EAGAIN) { - switch (fop->uint32) { - case EC_LOCK_MODE_NONE: - case EC_LOCK_MODE_ALL: - /* Goal is to treat non-blocking lock as failure - * even if there is a signle EAGAIN*/ - notlocked |= ans->mask; - break; - } - } + } 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) { + /* 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; } @@ -63,24 +87,31 @@ int32_t ec_lock_check(ec_fop_data_t *fop, uintptr_t *mask) error = 0; } 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: - error = EIO; - break; + 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 { - if (fop->answer && fop->answer->op_ret < 0) - error = fop->answer->op_errno; - else - error = EIO; + /* 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; + } } } @@ -89,28 +120,25 @@ int32_t ec_lock_check(ec_fop_data_t *fop, uintptr_t *mask) return error; } -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) +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_msg (this->name, GF_LOG_WARNING, op_errno, - EC_MSG_UNLOCK_FAILED, - "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_msg(this->name, GF_LOG_WARNING, op_errno, - EC_MSG_LK_UNLOCK_FAILED, + if (op_ret < 0) { + gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_LK_UNLOCK_FAILED, "Failed to unlock an lk"); } @@ -119,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); @@ -133,20 +162,16 @@ 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) - { - 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, + if (cbk->xdata == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); @@ -158,15 +183,15 @@ int32_t ec_entrylk_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_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); @@ -176,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); @@ -197,18 +221,18 @@ int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: + case -EC_STATE_PREPARE_ANSWER: if (fop->entrylk_cmd != ENTRYLK_UNLOCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &mask); + 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); + 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], @@ -237,18 +261,13 @@ 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); } @@ -258,22 +277,16 @@ int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state) 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); } @@ -282,33 +295,31 @@ int32_t ec_manager_entrylk(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_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; + ec_cbk_t callback = {.entrylk = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "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, 0, target, minimum, - ec_wind_entrylk, ec_manager_entrylk, callback, - data); + 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; } @@ -319,18 +330,16 @@ void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + 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_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; } @@ -338,9 +347,8 @@ void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, if (basename != NULL) { fop->str[1] = gf_strdup(basename); if (fop->str[1] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } @@ -348,10 +356,9 @@ void ec_entrylk(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; } @@ -369,11 +376,12 @@ out: /* 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); @@ -383,22 +391,18 @@ 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) - { - 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; } @@ -408,15 +412,15 @@ int32_t ec_fentrylk_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_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); @@ -426,23 +430,23 @@ 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; + ec_cbk_t callback = {.fentrylk = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "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, 0, target, - minimum, ec_wind_fentrylk, ec_manager_entrylk, + fop_flags, ec_wind_fentrylk, ec_manager_entrylk, callback, data); if (fop == NULL) { goto out; @@ -456,9 +460,8 @@ void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } @@ -466,10 +469,9 @@ void ec_fentrylk(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; } @@ -477,9 +479,8 @@ void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target, if (basename != NULL) { fop->str[1] = gf_strdup(basename); if (fop->str[1] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } @@ -487,10 +488,9 @@ void ec_fentrylk(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; } @@ -508,11 +508,12 @@ out: /* 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); @@ -522,22 +523,18 @@ 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) - { - 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; } @@ -547,15 +544,15 @@ int32_t ec_inodelk_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_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); @@ -565,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); @@ -590,10 +585,11 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: + case -EC_STATE_PREPARE_ANSWER: if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &mask); + ec_fop_set_error(fop, ec_lock_check(fop, &mask)); if (fop->error != 0) { if (mask != 0) { ec_t *ec = fop->xl->private; @@ -607,12 +603,14 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) flock.l_owner.len = 0; if (fop->id == GF_FOP_INODELK) { - ec_inodelk(fop->frame, fop->xl, mask, 1, + 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->frame, fop->xl, mask, 1, + 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); } @@ -638,18 +636,13 @@ 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); } @@ -659,22 +652,16 @@ int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state) 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); } @@ -683,54 +670,52 @@ int32_t ec_manager_inodelk(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_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; + ec_cbk_t callback = {.inodelk = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "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, 0, target, minimum, - ec_wind_inodelk, ec_manager_inodelk, callback, - data); + 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) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + 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_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; } @@ -750,10 +735,9 @@ void ec_inodelk(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; } @@ -771,11 +755,12 @@ out: /* 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); @@ -785,22 +770,18 @@ 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) - { - 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; } @@ -810,15 +791,15 @@ int32_t ec_finodelk_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_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); @@ -828,23 +809,24 @@ 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; + ec_cbk_t callback = {.finodelk = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "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, 0, target, - minimum, ec_wind_finodelk, ec_manager_inodelk, + fop_flags, ec_wind_finodelk, ec_manager_inodelk, callback, data); if (fop == NULL) { goto out; @@ -853,13 +835,13 @@ void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target, fop->use_fd = 1; fop->int32 = cmd; + ec_owner_copy(fop->frame, owner); if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { - gf_msg (this->name, GF_LOG_ERROR, ENOMEM, - EC_MSG_NO_MEMORY, - "Failed to duplicate a string."); + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, + "Failed to duplicate a string."); goto out; } @@ -867,10 +849,9 @@ void ec_finodelk(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_DICT_REF_FAIL, - "Failed to reference a " - "file descriptor."); + gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, + "Failed to reference a " + "file descriptor."); goto out; } @@ -890,10 +871,9 @@ void ec_finodelk(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; } @@ -911,15 +891,13 @@ out: /* 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_msg (fop->xl->name, GF_LOG_NOTICE, 0, - EC_MSG_LOCK_MISMATCH, - "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; } @@ -927,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); @@ -942,39 +920,32 @@ 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) - { - 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_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; } @@ -984,15 +955,15 @@ int32_t ec_lk_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_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); @@ -1001,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); @@ -1026,26 +992,26 @@ int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: + case -EC_STATE_PREPARE_ANSWER: if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; - fop->error = ec_lock_check(fop, &mask); + 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; + 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->frame, fop->xl, mask, 1, - ec_lock_lk_unlocked, NULL, fop->fd, F_SETLK, - &flock, fop->xdata); + ec_lk(fop->frame, fop->xl, mask, 1, ec_lock_lk_unlocked, + NULL, fop->fd, F_SETLK, &flock, fop->xdata); } + if (fop->error < 0) { fop->error = 0; @@ -1067,8 +1033,7 @@ 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); } @@ -1077,43 +1042,39 @@ int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state) 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); } 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_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; + ec_cbk_t callback = {.lk = func}; + ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; - gf_msg_trace ("ec", 0, "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, 0, target, minimum, + 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; @@ -1126,10 +1087,9 @@ void ec_lk(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; } @@ -1149,10 +1109,9 @@ void ec_lk(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; } |
