summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r--xlators/cluster/ec/src/ec-common.c27
-rw-r--r--xlators/cluster/ec/src/ec.c26
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;