summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht
diff options
context:
space:
mode:
authorSusant Palai <spalai@redhat.com>2020-04-24 13:32:51 +0530
committerMOHIT AGRAWAL <moagrawa@redhat.com>2020-04-28 16:57:26 +0000
commit5a3a9afa2352043a2172615c428989c3ebd80c27 (patch)
tree6fbca7446d7add61259339adc512e4fb4eb95f3d /xlators/cluster/dht
parent8536a9e66bd2b684f961b16ebe213cb63b060c20 (diff)
dht: Handle setxattr and rm race for directory in rebalance
Problem: Selfheal as part of directory does not return an error if the layout setxattr fails. This is because the actual lookup fop must have been successful to proceed for layout heal. Hence, we could not tell if fix-layout failed in rebalance. Solution: We can check this information in the layout structure that whether all the xlators have returned error. fixes: #1200 Change-Id: I3e5f2a36c0d934c21476a73a9a5473d8e490cde7 Signed-off-by: Susant Palai <spalai@redhat.com>
Diffstat (limited to 'xlators/cluster/dht')
-rw-r--r--xlators/cluster/dht/src/dht-common.c19
-rw-r--r--xlators/cluster/dht/src/dht-common.h3
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c11
3 files changed, 33 insertions, 0 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index e3aed576d75..749819680e6 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -11436,3 +11436,22 @@ dht_pt_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key,
FIRST_CHILD(this)->fops->fgetxattr, fd, key, xdata);
return 0;
}
+
+/* The job of this function is to check if all the xlators have updated
+ * error in the layout. */
+int
+dht_dir_layout_error_check(xlator_t *this, inode_t *inode)
+{
+ dht_layout_t *layout = NULL;
+ int i = 0;
+
+ layout = dht_layout_get(this, inode);
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].err == 0) {
+ return 0;
+ }
+ }
+
+ /* Returning the first xlator error as all xlators have errors */
+ return layout->list[0].err;
+}
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index 8a49eefe9b4..2c90dc9951e 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -1481,4 +1481,7 @@ dht_create_lock(call_frame_t *frame, xlator_t *subvol);
int
dht_set_parent_layout_in_dict(loc_t *loc, xlator_t *this, dht_local_t *local);
+int
+dht_dir_layout_error_check(xlator_t *this, inode_t *inode);
+
#endif /* _DHT_H */
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index 46c2f9a32a5..236cae9ea66 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -3905,6 +3905,17 @@ gf_defrag_fix_layout(xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
*/
ret = syncop_setxattr(this, loc, fix_layout, 0, NULL, NULL);
+
+ /* In case of a race where the directory is deleted just before
+ * layout setxattr, the errors are updated in the layout structure.
+ * We can use this information to make a decision whether the directory
+ * is deleted entirely.
+ */
+ if (ret == 0) {
+ ret = dht_dir_layout_error_check(this, loc->inode);
+ ret = -ret;
+ }
+
if (ret) {
if (-ret == ENOENT || -ret == ESTALE) {
gf_msg(this->name, GF_LOG_INFO, -ret, DHT_MSG_LAYOUT_FIX_FAILED,