3604df
From fa1718110e33cbcd2591a668b7f8a22d817e4ef5 Mon Sep 17 00:00:00 2001
3604df
From: Jiffin Tony Thottan <jthottan@redhat.com>
3604df
Date: Mon, 21 Nov 2016 18:08:14 +0530
3604df
Subject: [PATCH 220/227] dht/rename : Incase of failure remove linkto file
3604df
 properly
3604df
3604df
Generally linkto file is created using root user. Consider following
3604df
case, a user is trying to rename a file which he is not permitted.
3604df
So the rename fails with EACESS and when rename tries to cleanup the
3604df
linkto file, it fails.
3604df
3604df
The above issue happens when rename/00.t test executed on nfs-ganesha
3604df
clients :
3604df
Steps executed in script
3604df
* create a file "abc" using root
3604df
* rename the file "abc" to "xyz" using a non root user, it fails with EACESS
3604df
* delete "abc"
3604df
* create directory "abc" using root
3604df
* again try ot rename "abc" to "xyz" using non root user, test hungs here
3604df
which slowly leds to OOM kill of ganesha process
3604df
3604df
RCA put forwarded by Du for OOM kill of ganesha
3604df
Note that when we hit this bug, we've a scenario of a dentry being
3604df
present as:
3604df
    * a linkto file on one subvol
3604df
    * a directory on rest of subvols
3604df
3604df
When a lookup happens on the dentry in such a scenario, the control flow
3604df
goes into an infinite loop of:
3604df
3604df
    dht_lookup_everywhere
3604df
    dht_lookup_everywhere_cbk
3604df
    dht_lookup_unlink_cbk
3604df
    dht_lookup_everywhere_done
3604df
    dht_lookup_directory (as local->dir_count > 0)
3604df
    dht_lookup_dir_cbk (sets to local->need_selfheal = 1 as the entry is a linkto file on one of the subvol)
3604df
    dht_lookup_everywhere (as need_selfheal = 1).
3604df
3604df
This infinite loop can cause increased consumption of memory due to:
3604df
1) dht_lookup_directory assigns a new layout to local->layout unconditionally
3604df
2)  Most of the functions in this loop do a stack_wind of various fops.
3604df
3604df
This results in growing of call stack (note that call-stack is destroyed only after lookup response is
3604df
received by fuse - which never happens in this case)
3604df
3604df
Thanks Du for root causing the oom kill and Sushant for suggesting the fix
3604df
3604df
Upstream reference :
3604df
>Change-Id: I1e16bc14aa685542afbd21188426ecb61fd2689d
3604df
>BUG: 1397052
3604df
>Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
3604df
>Reviewed-on: http://review.gluster.org/15894
3604df
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
>Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
>Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
3604df
3604df
Change-Id: I1e16bc14aa685542afbd21188426ecb61fd2689d
3604df
BUG: 1381452
3604df
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/92002
3604df
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
3604df
Tested-by: Atin Mukherjee <amukherj@redhat.com>
3604df
---
3604df
 xlators/cluster/dht/src/dht-common.c | 8 +++++++-
3604df
 xlators/cluster/dht/src/dht-rename.c | 8 +++++++-
3604df
 2 files changed, 14 insertions(+), 2 deletions(-)
3604df
3604df
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
3604df
index 0001d73..ca84826 100644
3604df
--- a/xlators/cluster/dht/src/dht-common.c
3604df
+++ b/xlators/cluster/dht/src/dht-common.c
3604df
@@ -1128,6 +1128,7 @@ dht_lookup_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
 
3604df
         local =  (dht_local_t*)frame->local;
3604df
         path = local->loc.path;
3604df
+        FRAME_SU_UNDO (frame, dht_local_t);
3604df
 
3604df
         gf_msg (this->name, GF_LOG_INFO, 0,
3604df
                 DHT_MSG_UNLINK_LOOKUP_INFO, "lookup_unlink returned with "
3604df
@@ -1821,7 +1822,12 @@ unlock:
3604df
                                         loc->path, subvol->name,
3604df
                                         (local->hashed_subvol?
3604df
                                         local->hashed_subvol->name : "<null>"));
3604df
-
3604df
+                                /* *
3604df
+                                 * These stale files may be created using root
3604df
+                                 * user. Hence deletion will work only with
3604df
+                                 * root.
3604df
+                                 */
3604df
+                                FRAME_SU_DO (frame, dht_local_t);
3604df
                                 STACK_WIND (frame, dht_lookup_unlink_cbk,
3604df
                                             subvol, subvol->fops->unlink, loc,
3604df
                                             0, dict_req);
3604df
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
3604df
index 777c63d..a9ffd1d 100644
3604df
--- a/xlators/cluster/dht/src/dht-rename.c
3604df
+++ b/xlators/cluster/dht/src/dht-rename.c
3604df
@@ -637,6 +637,7 @@ dht_rename_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
         local = frame->local;
3604df
         prev  = cookie;
3604df
 
3604df
+        FRAME_SU_UNDO (frame, dht_local_t);
3604df
         if (!local) {
3604df
                 gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
                         DHT_MSG_INVALID_VALUE,
3604df
@@ -745,7 +746,12 @@ dht_rename_cleanup (call_frame_t *frame)
3604df
                                   local->loc2.pargfid) == 0) {
3604df
                         DHT_MARKER_DONT_ACCOUNT(xattr_new);
3604df
                 }
3604df
-
3604df
+                /* *
3604df
+                 * The link to file is created using root permission.
3604df
+                 * Hence deletion should happen using root. Otherwise
3604df
+                 * it will fail.
3604df
+                 */
3604df
+                FRAME_SU_DO (frame, dht_local_t);
3604df
                 STACK_WIND (frame, dht_rename_unlink_cbk,
3604df
                             src_cached, src_cached->fops->unlink,
3604df
                             &local->loc2, 0, xattr_new);
3604df
-- 
3604df
2.9.3
3604df