diff options
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r-- | xlators/cluster/ec/src/ec-common.c | 27 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec.c | 26 |
2 files changed, 45 insertions, 8 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; diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index 4028aa4d2bb..797c390e383 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -625,7 +625,10 @@ int32_t ec_gf_entrylk(call_frame_t * frame, xlator_t * this, const char * volume, loc_t * loc, const char * basename, entrylk_cmd cmd, entrylk_type type, dict_t * xdata) { - ec_entrylk(frame, this, -1, EC_MINIMUM_ALL, default_entrylk_cbk, NULL, + int32_t minimum = EC_MINIMUM_ALL; + if (cmd == ENTRYLK_UNLOCK) + minimum = EC_MINIMUM_ONE; + ec_entrylk(frame, this, -1, minimum, default_entrylk_cbk, NULL, volume, loc, basename, cmd, type, xdata); return 0; @@ -635,7 +638,10 @@ int32_t ec_gf_fentrylk(call_frame_t * frame, xlator_t * this, const char * volume, fd_t * fd, const char * basename, entrylk_cmd cmd, entrylk_type type, dict_t * xdata) { - ec_fentrylk(frame, this, -1, EC_MINIMUM_ALL, default_fentrylk_cbk, NULL, + int32_t minimum = EC_MINIMUM_ALL; + if (cmd == ENTRYLK_UNLOCK) + minimum = EC_MINIMUM_ONE; + ec_fentrylk(frame, this, -1, minimum, default_fentrylk_cbk, NULL, volume, fd, basename, cmd, type, xdata); return 0; @@ -772,7 +778,11 @@ int32_t ec_gf_inodelk(call_frame_t * frame, xlator_t * this, const char * volume, loc_t * loc, int32_t cmd, struct gf_flock * flock, dict_t * xdata) { - ec_inodelk(frame, this, -1, EC_MINIMUM_ALL, default_inodelk_cbk, NULL, + int32_t minimum = EC_MINIMUM_ALL; + if (flock->l_type == F_UNLCK) + minimum = EC_MINIMUM_ONE; + + ec_inodelk(frame, this, -1, minimum, default_inodelk_cbk, NULL, volume, loc, cmd, flock, xdata); return 0; @@ -782,7 +792,10 @@ int32_t ec_gf_finodelk(call_frame_t * frame, xlator_t * this, const char * volume, fd_t * fd, int32_t cmd, struct gf_flock * flock, dict_t * xdata) { - ec_finodelk(frame, this, -1, EC_MINIMUM_ALL, default_finodelk_cbk, NULL, + int32_t minimum = EC_MINIMUM_ALL; + if (flock->l_type == F_UNLCK) + minimum = EC_MINIMUM_ONE; + ec_finodelk(frame, this, -1, minimum, default_finodelk_cbk, NULL, volume, fd, cmd, flock, xdata); return 0; @@ -800,7 +813,10 @@ int32_t ec_gf_link(call_frame_t * frame, xlator_t * this, loc_t * oldloc, int32_t ec_gf_lk(call_frame_t * frame, xlator_t * this, fd_t * fd, int32_t cmd, struct gf_flock * flock, dict_t * xdata) { - ec_lk(frame, this, -1, EC_MINIMUM_ALL, default_lk_cbk, NULL, fd, cmd, + int32_t minimum = EC_MINIMUM_ALL; + if (flock->l_type == F_UNLCK) + minimum = EC_MINIMUM_ONE; + ec_lk(frame, this, -1, minimum, default_lk_cbk, NULL, fd, cmd, flock, xdata); return 0; |