summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2015-06-10 10:30:03 +0530
committerVijay Bellur <vbellur@redhat.com>2015-06-10 23:37:07 -0700
commit5c00a6c8163cc255e777823b99d516dfb5ef114e (patch)
tree1c94fd51506eeb341d7f2dfb79e2713461f16b4a
parentec7d0c3de11cbee1470308dcc10ec9f02e7fdfff (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>
-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;