d1681e
From b3c216d77ae7a054d4f5f28a93239afe00771cd8 Mon Sep 17 00:00:00 2001
d1681e
From: N Balachandran <nbalacha@redhat.com>
d1681e
Date: Thu, 29 Mar 2018 18:23:13 +0530
d1681e
Subject: [PATCH 209/212] cluster/dht: Update layout in inode only on success
d1681e
d1681e
With lookup-optimize enabled, gf_defrag_settle_hash in rebalance
d1681e
sometimes flips the on-disk layout on volume root post the
d1681e
migration of all files in the directory.
d1681e
d1681e
This is sometimes seen when attempting to fix the layout of a
d1681e
directory multiple times before calling gf_defrag_settle_hash.
d1681e
dht_fix_layout_of_directory generates a new layout in memory but
d1681e
updates it in the inode ctx before it is set on disk. The layout
d1681e
may be different the second time around due to
d1681e
dht_selfheal_layout_maximize_overlap. If the layout is then not
d1681e
written to the disk, the inode now contains the wrong layout.
d1681e
gf_defrag_settle_hash does not check the correctness of the layout
d1681e
in the inode before updating the commit-hash and writing it to the
d1681e
disk thus changing the layout of the directory.
d1681e
d1681e
upstream master:https://review.gluster.org/#/c/19797/
d1681e
d1681e
> Change-Id: Ie1407d92982518f2a0c40ec70ad370b34a87b4d4
d1681e
> updates: bz#1557435
d1681e
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
d1681e
d1681e
Change-Id: I4222b7c985226ca175e0581c103bad62084339a2
d1681e
BUG: 1557365
d1681e
Signed-off-by: N Balachandran <nbalacha@redhat.com>
d1681e
Reviewed-on: https://code.engineering.redhat.com/gerrit/134451
d1681e
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d1681e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
d1681e
---
d1681e
 xlators/cluster/dht/src/dht-common.c   | 25 ++++++++++++++++++++++++-
d1681e
 xlators/cluster/dht/src/dht-selfheal.c |  3 ---
d1681e
 2 files changed, 24 insertions(+), 4 deletions(-)
d1681e
d1681e
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
d1681e
index f1e6a92..6319a87 100644
d1681e
--- a/xlators/cluster/dht/src/dht-common.c
d1681e
+++ b/xlators/cluster/dht/src/dht-common.c
d1681e
@@ -3545,6 +3545,28 @@ dht_common_setxattr_cbk (call_frame_t *frame, void *cookie,
d1681e
 
d1681e
 
d1681e
 
d1681e
+static int
d1681e
+dht_fix_layout_setxattr_cbk (call_frame_t *frame, void *cookie,
d1681e
+                             xlator_t *this, int32_t op_ret, int32_t op_errno,
d1681e
+                             dict_t *xdata)
d1681e
+{
d1681e
+        dht_local_t   *local   = NULL;
d1681e
+        dht_layout_t  *layout  = NULL;
d1681e
+
d1681e
+        if (op_ret == 0) {
d1681e
+
d1681e
+                /* update the layout in the inode ctx */
d1681e
+                local = frame->local;
d1681e
+                layout = local->selfheal.layout;
d1681e
+
d1681e
+                dht_layout_set (this, local->loc.inode, layout);
d1681e
+        }
d1681e
+
d1681e
+         DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
d1681e
+         return 0;
d1681e
+}
d1681e
+
d1681e
+
d1681e
 int
d1681e
 dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
d1681e
              int op_ret, int op_errno, dict_t *xdata)
d1681e
@@ -5531,7 +5553,8 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
d1681e
                         DHT_MSG_FIX_LAYOUT_INFO,
d1681e
                         "fixing the layout of %s", loc->path);
d1681e
 
d1681e
-                ret = dht_fix_directory_layout (frame, dht_common_setxattr_cbk,
d1681e
+                ret = dht_fix_directory_layout (frame,
d1681e
+                                                dht_fix_layout_setxattr_cbk,
d1681e
                                                 layout);
d1681e
                 if (ret) {
d1681e
                         op_errno = ENOTCONN;
d1681e
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
d1681e
index 328251d..1707e08 100644
d1681e
--- a/xlators/cluster/dht/src/dht-selfheal.c
d1681e
+++ b/xlators/cluster/dht/src/dht-selfheal.c
d1681e
@@ -2112,9 +2112,6 @@ dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc,
d1681e
         }
d1681e
 done:
d1681e
         if (new_layout) {
d1681e
-                /* Now that the new layout has all the proper layout, change the
d1681e
-                   inode context */
d1681e
-                dht_layout_set (this, loc->inode, new_layout);
d1681e
 
d1681e
                 /* Make sure the extra 'ref' for existing layout is removed */
d1681e
                 dht_layout_unref (this, local->layout);
d1681e
-- 
d1681e
1.8.3.1
d1681e