14f8ab
From aef8e51b9974603d397cc8f5301b24451d012e46 Mon Sep 17 00:00:00 2001
14f8ab
From: Susant Palai <spalai@redhat.com>
14f8ab
Date: Fri, 24 Apr 2020 13:32:51 +0530
14f8ab
Subject: [PATCH 367/367] dht: Handle setxattr and rm race for directory in
14f8ab
 rebalance
14f8ab
14f8ab
Problem: Selfheal as part of directory does not return an error if
14f8ab
the layout setxattr fails. This is because the actual lookup fop
14f8ab
must have been successful to proceed for layout heal. Hence, we could
14f8ab
not tell if fix-layout failed in rebalance.
14f8ab
14f8ab
Solution: We can check this information in the layout structure that
14f8ab
whether all the xlators have returned error.
14f8ab
14f8ab
> fixes: #1200
14f8ab
> hange-Id: I3e5f2a36c0d934c21476a73a9a5473d8e490cde7
14f8ab
> Signed-off-by: Susant Palai <spalai@redhat.com>
14f8ab
(backport of https://review.gluster.org/#/c/glusterfs/+/24375/)
14f8ab
14f8ab
BUG: 1812789
14f8ab
Change-Id: I897826c4c2e883b3085c9314deff32d649b4588e
14f8ab
Signed-off-by: Susant Palai <spalai@redhat.com>
14f8ab
Reviewed-on: https://code.engineering.redhat.com/gerrit/198726
14f8ab
Reviewed-by: Mohit Agrawal <moagrawa@redhat.com>
14f8ab
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
14f8ab
---
14f8ab
 xlators/cluster/dht/src/dht-common.c    | 19 +++++++++++++++++++
14f8ab
 xlators/cluster/dht/src/dht-common.h    |  3 +++
14f8ab
 xlators/cluster/dht/src/dht-rebalance.c | 11 +++++++++++
14f8ab
 3 files changed, 33 insertions(+)
14f8ab
14f8ab
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
14f8ab
index d0b5287..7890e7a 100644
14f8ab
--- a/xlators/cluster/dht/src/dht-common.c
14f8ab
+++ b/xlators/cluster/dht/src/dht-common.c
14f8ab
@@ -11286,3 +11286,22 @@ dht_pt_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key,
14f8ab
                FIRST_CHILD(this)->fops->fgetxattr, fd, key, xdata);
14f8ab
     return 0;
14f8ab
 }
14f8ab
+
14f8ab
+/* The job of this function is to check if all the xlators have updated
14f8ab
+ * error in the layout. */
14f8ab
+int
14f8ab
+dht_dir_layout_error_check(xlator_t *this, inode_t *inode)
14f8ab
+{
14f8ab
+    dht_layout_t *layout = NULL;
14f8ab
+    int i = 0;
14f8ab
+
14f8ab
+    layout = dht_layout_get(this, inode);
14f8ab
+    for (i = 0; i < layout->cnt; i++) {
14f8ab
+        if (layout->list[i].err == 0) {
14f8ab
+            return 0;
14f8ab
+        }
14f8ab
+    }
14f8ab
+
14f8ab
+    /* Returning the first xlator error as all xlators have errors */
14f8ab
+    return layout->list[0].err;
14f8ab
+}
14f8ab
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
14f8ab
index ce11f02..4d2aae6 100644
14f8ab
--- a/xlators/cluster/dht/src/dht-common.h
14f8ab
+++ b/xlators/cluster/dht/src/dht-common.h
14f8ab
@@ -1544,4 +1544,7 @@ dht_pt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
14f8ab
 int32_t
14f8ab
 dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno);
14f8ab
 
14f8ab
+int
14f8ab
+dht_dir_layout_error_check(xlator_t *this, inode_t *inode);
14f8ab
+
14f8ab
 #endif /* _DHT_H */
14f8ab
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
14f8ab
index 7d9df02..33cacfe 100644
14f8ab
--- a/xlators/cluster/dht/src/dht-rebalance.c
14f8ab
+++ b/xlators/cluster/dht/src/dht-rebalance.c
14f8ab
@@ -3928,6 +3928,17 @@ gf_defrag_fix_layout(xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
14f8ab
     }
14f8ab
 
14f8ab
     ret = syncop_setxattr(this, loc, fix_layout, 0, NULL, NULL);
14f8ab
+
14f8ab
+    /* In case of a race where the directory is deleted just before
14f8ab
+     * layout setxattr, the errors are updated in the layout structure.
14f8ab
+     * We can use this information to make a decision whether the directory
14f8ab
+     * is deleted entirely.
14f8ab
+     */
14f8ab
+    if (ret == 0) {
14f8ab
+        ret = dht_dir_layout_error_check(this, loc->inode);
14f8ab
+        ret = -ret;
14f8ab
+    }
14f8ab
+
14f8ab
     if (ret) {
14f8ab
         if (-ret == ENOENT || -ret == ESTALE) {
14f8ab
             gf_msg(this->name, GF_LOG_INFO, -ret, DHT_MSG_LAYOUT_FIX_FAILED,
14f8ab
-- 
14f8ab
1.8.3.1
14f8ab