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