From d52f95864b9f58d14a9d48a1d73b086009491278 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Wed, 10 Jun 2015 10:30:03 +0530 Subject: cluster/ec: Wind unlock fops at all cost Backport of http://review.gluster.org/11152 Problem: While files are being created if more than redundancy number of bricks go down, then unlock for these fops do not go to the bricks. This will lead to stale locks leading to hangs. Fix: Wind unlock fops at all costs. BUG: 1230350 Change-Id: I3312b0fe1694ad02af5307bcbaf233ac63058846 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/11166 Tested-by: Gluster Build System --- xlators/cluster/ec/src/ec-common.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 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 c2c48c3c3f8..b833668c61a 100644 --- a/xlators/cluster/ec/src/ec-common.c +++ b/xlators/cluster/ec/src/ec-common.c @@ -1421,7 +1421,7 @@ void ec_unlock_lock(ec_lock_link_t *link) ec_trace("UNLOCK_INODELK", fop, "lock=%p, inode=%p", lock, lock->loc.inode); - ec_inodelk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ALL, + ec_inodelk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ONE, ec_unlocked, link, fop->xl->name, &lock->loc, F_SETLK, &lock->flock, NULL); } else { @@ -1833,6 +1833,24 @@ void ec_lock_reuse(ec_fop_data_t *fop) } } +/* There could be already granted locks sitting on the bricks, unlock for which + * must be wound at all costs*/ +static gf_boolean_t +ec_must_wind (ec_fop_data_t *fop) +{ + if ((fop->id == GF_FOP_INODELK) || (fop->id == GF_FOP_FINODELK) || + (fop->id == GF_FOP_LK)) { + if (fop->flock.l_type == F_UNLCK) + return _gf_true; + } else if ((fop->id == GF_FOP_ENTRYLK) || + (fop->id == GF_FOP_FENTRYLK)) { + if (fop->entrylk_cmd == ENTRYLK_UNLOCK) + return _gf_true; + } + + return _gf_false; +} + void __ec_manager(ec_fop_data_t * fop, int32_t error) { ec_t *ec = fop->xl->private; @@ -1840,9 +1858,12 @@ void __ec_manager(ec_fop_data_t * fop, int32_t error) do { ec_trace("MANAGER", fop, "error=%d", error); - if (ec->xl_up_count < ec->fragments) { - error = ENOTCONN; + if (!ec_must_wind (fop)) { + if (ec->xl_up_count < ec->fragments) { + error = ENOTCONN; + } } + if (error != 0) { fop->error = error; fop->state = -fop->state; -- cgit