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 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; 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;  | 
