From 36236eecef55c710e1f11ba4a04fe01da67cab6a Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Tue, 11 Nov 2014 18:45:01 +0100 Subject: ec: Fix return errors when not enough bricks Changes introduced by this patch: * Fix an incorrect error propagation when the state of the life cycle of a fop returns an error. * Fix incorrect unlocking of failed locks. * Return ENOTCONN if there aren't enough bricks online. * In readdir(p) check that the fd has been successfully open by a previous opendir. Change-Id: Ib44f25a1297849ebcbab839332f3b6359f275ebe BUG: 1162805 Signed-off-by: Xavier Hernandez Reviewed-on: http://review.gluster.org/9098 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/cluster/ec/src/ec-common.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'xlators/cluster/ec/src/ec-common.c') diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c index fbdad86950a..89c78c69bae 100644 --- a/xlators/cluster/ec/src/ec-common.c +++ b/xlators/cluster/ec/src/ec-common.c @@ -313,6 +313,7 @@ void ec_resume_parent(ec_fop_data_t * fop, int32_t error) parent = fop->parent; if (parent != NULL) { + ec_trace("RESUME_PARENT", fop, "error=%u", error); fop->parent = NULL; ec_resume(parent, error); } @@ -1148,7 +1149,7 @@ int32_t ec_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, void ec_unlock_lock(ec_fop_data_t *fop, ec_lock_t *lock) { - if (lock->mask != 0) { + if ((lock->mask != 0) && lock->acquired) { ec_owner_set(fop->frame, lock); switch (lock->kind) { @@ -1327,7 +1328,10 @@ void ec_unlock_timer_add(ec_lock_link_t *link) lock->refs--; UNLOCK(&lock->loc.inode->lock); - } else { + } else if (lock->acquired) { + delay.tv_sec = 1; + delay.tv_nsec = 0; + LOCK(&fop->lock); fop->jobs++; @@ -1361,6 +1365,12 @@ void ec_unlock_timer_add(ec_lock_link_t *link) if (refs == 0) { ec_unlock_now(fop, lock); } + } else { + *lock->plock = NULL; + + UNLOCK(&lock->loc.inode->lock); + + ec_lock_destroy(lock); } } @@ -1461,23 +1471,25 @@ void ec_lock_reuse(ec_fop_data_t *fop) void __ec_manager(ec_fop_data_t * fop, int32_t error) { - do - { - ec_trace("MANAGER", fop, "error=%d", error); + ec_t *ec = fop->xl->private; - if (fop->state == EC_STATE_END) - { - ec_fop_data_release(fop); + do { + ec_trace("MANAGER", fop, "error=%d", error); - break; + if (ec->xl_up_count < ec->fragments) { + error = ENOTCONN; } - - if (error != 0) - { + if (error != 0) { fop->error = error; fop->state = -fop->state; } + if ((fop->state == EC_STATE_END) || (fop->state == -EC_STATE_END)) { + ec_fop_data_release(fop); + + break; + } + fop->state = fop->handler(fop, fop->state); error = ec_check_complete(fop, __ec_manager); -- cgit