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