diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2015-06-10 10:30:03 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-06-10 23:37:07 -0700 |
commit | 5c00a6c8163cc255e777823b99d516dfb5ef114e (patch) | |
tree | 1c94fd51506eeb341d7f2dfb79e2713461f16b4a /xlators/cluster/ec/src/ec-common.c | |
parent | ec7d0c3de11cbee1470308dcc10ec9f02e7fdfff (diff) |
cluster/ec: Wind unlock fops at all cost
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.
Change-Id: I50a87e8b4d6d2dde5bf7405b82e3aeecd95ad00e
BUG: 1220348
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/11152
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
Diffstat (limited to 'xlators/cluster/ec/src/ec-common.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-common.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c index f214e7e065f..6b7edfdecb1 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 { @@ -1834,6 +1834,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; @@ -1841,9 +1859,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; |