From 30ae004100067f52fe156098ffb215417db5559e Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Wed, 3 Dec 2014 16:42:31 +0100 Subject: ec: Fix mutex related coverity scan issues This patch solves 3 issues detected by coverity scan: CID1241484 Data race condition CID1241486 Data race condition CID1256173 Thread deadlock With this patch, inode lock is never acquired inside a region locked with fop->lock. Change-Id: I35c4633efd1b68b9f72b42661fa7c728b1f52c6a BUG: 1170254 Signed-off-by: Xavier Hernandez Reviewed-on: http://review.gluster.org/9230 Tested-by: Gluster Build System Reviewed-by: Dan Lambright --- xlators/cluster/ec/src/ec-common.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'xlators/cluster') diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c index 894d2f552f3..fbdad86950a 100644 --- a/xlators/cluster/ec/src/ec-common.c +++ b/xlators/cluster/ec/src/ec-common.c @@ -321,7 +321,7 @@ void ec_resume_parent(ec_fop_data_t * fop, int32_t error) void ec_complete(ec_fop_data_t * fop) { ec_cbk_data_t * cbk = NULL; - int32_t resume = 0; + int32_t resume = 0, update = 0; LOCK(&fop->lock); @@ -335,7 +335,7 @@ void ec_complete(ec_fop_data_t * fop) ((cbk->op_ret >= 0) || (cbk->op_errno != ENOTCONN))) { fop->answer = cbk; - ec_update_bad(fop, cbk->mask); + update = 1; } } @@ -349,6 +349,14 @@ void ec_complete(ec_fop_data_t * fop) UNLOCK(&fop->lock); + /* ec_update_bad() locks inode->lock. This may cause deadlocks with + fop->lock when used in another order. Since ec_update_bad() will not + be called more than once for each fop, it can be called from outside + the fop->lock locked region. */ + if (update) { + ec_update_bad(fop, cbk->mask); + } + if (resume) { ec_resume(fop, 0); @@ -861,9 +869,13 @@ void ec_lock(ec_fop_data_t * fop) list_add_tail(&fop->locks[fop->locked].wait_list, &lock->waiting); + LOCK(&fop->lock); + fop->jobs++; fop->refs++; + UNLOCK(&fop->lock); + UNLOCK(&lock->loc.inode->lock); break; -- cgit