cb8e9e
From 17cb0e4782f47339dd1e4edc2e166ff2422da750 Mon Sep 17 00:00:00 2001
cb8e9e
From: Pranith Kumar K <pkarampu@redhat.com>
cb8e9e
Date: Thu, 4 Jun 2015 09:52:51 +0530
cb8e9e
Subject: [PATCH 14/18] cluster/ec: EC_XATTR_DIRTY doesn't come in response
cb8e9e
cb8e9e
        Backport of http://review.gluster.com/11084
cb8e9e
cb8e9e
Problem:
cb8e9e
ec_update_size_version expects all the keys it did xattrop with to come in
cb8e9e
response so that it can set the values again in ec_update_size_version_done.
cb8e9e
But EC_XATTR_DIRTY is not combined so the value won't be present in the
cb8e9e
response. So ctx->post/pre_dirty are not updated in
cb8e9e
ec_update_size_version_done. So these values are still non-zero. When
cb8e9e
ec_unlock_now is called as part of flush's unlock phase it again tries to
cb8e9e
perform same xattrop for EC_XATTR_DIRTY. But ec_update_size_version is not
cb8e9e
expected to be called in unlock phase of flush because ec_flush_size_version
cb8e9e
should have reset everything to zero and unlock is never invoked from
cb8e9e
ec_update_size_version_done for flush/fsync/fsyncdir. This leads to stale lock
cb8e9e
which leads to hang.
cb8e9e
cb8e9e
Fix:
cb8e9e
EC_XATTR_DIRTY is removed in ex_xattrop_cbk and is never combined with other
cb8e9e
answers. So remove handling of this in the response.
cb8e9e
cb8e9e
BUG: 1227649
cb8e9e
Change-Id: I657efca6e706e7acb541f98f526943f67562da9f
cb8e9e
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/49909
cb8e9e
---
cb8e9e
 xlators/cluster/ec/src/ec-common.c | 32 ++++++++------------------------
cb8e9e
 xlators/cluster/ec/src/ec-data.h   |  4 +---
cb8e9e
 2 files changed, 9 insertions(+), 27 deletions(-)
cb8e9e
cb8e9e
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
cb8e9e
index ba81fc7..062754b 100644
cb8e9e
--- a/xlators/cluster/ec/src/ec-common.c
cb8e9e
+++ b/xlators/cluster/ec/src/ec-common.c
cb8e9e
@@ -884,14 +884,6 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
cb8e9e
 
cb8e9e
     ctx->have_version = _gf_true;
cb8e9e
 
cb8e9e
-    if (ec_dict_del_array(dict, EC_XATTR_DIRTY, ctx->pre_dirty,
cb8e9e
-                          EC_VERSION_SIZE) == 0) {
cb8e9e
-        ctx->post_dirty[0] += ctx->pre_dirty[0];
cb8e9e
-        ctx->post_dirty[1] += ctx->pre_dirty[1];
cb8e9e
-
cb8e9e
-        ctx->have_dirty = _gf_true;
cb8e9e
-    }
cb8e9e
-
cb8e9e
     if (lock->loc.inode->ia_type == IA_IFREG) {
cb8e9e
         if (ec_dict_del_number(dict, EC_XATTR_SIZE, &ctx->pre_size) != 0) {
cb8e9e
             gf_log(this->name, GF_LOG_ERROR, "Unable to get size xattr");
cb8e9e
@@ -1107,14 +1099,12 @@ void ec_clear_inode_info(ec_fop_data_t *fop, inode_t *inode)
cb8e9e
     ctx->have_config = _gf_false;
cb8e9e
     ctx->have_version = _gf_false;
cb8e9e
     ctx->have_size = _gf_false;
cb8e9e
-    ctx->have_dirty = _gf_false;
cb8e9e
 
cb8e9e
     memset(&ctx->config, 0, sizeof(ctx->config));
cb8e9e
     memset(ctx->pre_version, 0, sizeof(ctx->pre_version));
cb8e9e
     memset(ctx->post_version, 0, sizeof(ctx->post_version));
cb8e9e
     ctx->pre_size = ctx->post_size = 0;
cb8e9e
-    memset(ctx->pre_dirty, 0, sizeof(ctx->pre_dirty));
cb8e9e
-    memset(ctx->post_dirty, 0, sizeof(ctx->post_dirty));
cb8e9e
+    memset(ctx->dirty, 0, sizeof(ctx->dirty));
cb8e9e
 
cb8e9e
 unlock:
cb8e9e
     UNLOCK(&inode->lock);
cb8e9e
@@ -1472,13 +1462,6 @@ int32_t ec_update_size_version_done(call_frame_t * frame, void * cookie,
cb8e9e
 
cb8e9e
             ctx->have_size = _gf_true;
cb8e9e
         }
cb8e9e
-        if (ec_dict_del_array(xattr, EC_XATTR_DIRTY, ctx->post_dirty,
cb8e9e
-                              EC_VERSION_SIZE) == 0) {
cb8e9e
-            ctx->pre_dirty[0] = ctx->post_dirty[0];
cb8e9e
-            ctx->pre_dirty[1] = ctx->post_dirty[1];
cb8e9e
-
cb8e9e
-            ctx->have_dirty = _gf_true;
cb8e9e
-        }
cb8e9e
         if ((ec_dict_del_config(xdata, EC_XATTR_CONFIG, &ctx->config) == 0) &&
cb8e9e
             ec_config_check(fop->parent, &ctx->config)) {
cb8e9e
             ctx->have_config = _gf_true;
cb8e9e
@@ -1541,7 +1524,7 @@ ec_update_size_version(ec_lock_link_t *link, uint64_t *version,
cb8e9e
 
cb8e9e
     /* If we don't have dirty information or it has been modified, we update
cb8e9e
      * it. */
cb8e9e
-    if (!ctx->have_dirty || (dirty[0] != 0) || (dirty[1] != 0)) {
cb8e9e
+    if ((dirty[0] != 0) || (dirty[1] != 0)) {
cb8e9e
         if (ec_dict_set_array(dict, EC_XATTR_DIRTY, dirty,
cb8e9e
                               EC_VERSION_SIZE) != 0) {
cb8e9e
             goto out;
cb8e9e
@@ -1606,9 +1589,10 @@ ec_update_info(ec_lock_link_t *link)
cb8e9e
 
cb8e9e
     size = ctx->post_size - ctx->pre_size;
cb8e9e
 
cb8e9e
-    /* pre_dirty[*] will be 0 if have_dirty is false */
cb8e9e
-    dirty[0] = ctx->post_dirty[0] - ctx->pre_dirty[0];
cb8e9e
-    dirty[1] = ctx->post_dirty[1] - ctx->pre_dirty[1];
cb8e9e
+    dirty[0] = ctx->dirty[0];
cb8e9e
+    dirty[1] = ctx->dirty[1];
cb8e9e
+    /*Dirty is not combined so just reset it right here*/
cb8e9e
+    memset(ctx->dirty, 0, sizeof(ctx->dirty));
cb8e9e
 
cb8e9e
     if ((version[0] != 0) || (version[1] != 0) ||
cb8e9e
         (dirty[0] != 0) || (dirty[1] != 0)) {
cb8e9e
@@ -1817,13 +1801,13 @@ void ec_lock_reuse(ec_fop_data_t *fop)
cb8e9e
             if (link->update[0]) {
cb8e9e
                 ctx->post_version[0]++;
cb8e9e
                 if (ec->node_mask & ~fop->mask) {
cb8e9e
-                    ctx->post_dirty[0]++;
cb8e9e
+                    ctx->dirty[0]++;
cb8e9e
                 }
cb8e9e
             }
cb8e9e
             if (link->update[1]) {
cb8e9e
                 ctx->post_version[1]++;
cb8e9e
                 if (ec->node_mask & ~fop->mask) {
cb8e9e
-                    ctx->post_dirty[1]++;
cb8e9e
+                    ctx->dirty[1]++;
cb8e9e
                 }
cb8e9e
             }
cb8e9e
         }
cb8e9e
diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h
cb8e9e
index 8204cf0..8f6d5de 100644
cb8e9e
--- a/xlators/cluster/ec/src/ec-data.h
cb8e9e
+++ b/xlators/cluster/ec/src/ec-data.h
cb8e9e
@@ -72,14 +72,12 @@ struct _ec_inode
cb8e9e
     gf_boolean_t      have_config;
cb8e9e
     gf_boolean_t      have_version;
cb8e9e
     gf_boolean_t      have_size;
cb8e9e
-    gf_boolean_t      have_dirty;
cb8e9e
     ec_config_t       config;
cb8e9e
     uint64_t          pre_version[2];
cb8e9e
     uint64_t          post_version[2];
cb8e9e
     uint64_t          pre_size;
cb8e9e
     uint64_t          post_size;
cb8e9e
-    uint64_t          pre_dirty[2];
cb8e9e
-    uint64_t          post_dirty[2];
cb8e9e
+    uint64_t          dirty[2];
cb8e9e
     struct list_head  heal;
cb8e9e
 };
cb8e9e
 
cb8e9e
-- 
cb8e9e
1.9.3
cb8e9e