[Devel] [PATCH RHEL7 COMMIT] fs/nfs: break umount cycle if current task does not have enough stack.
Vasily Averin
vvs at virtuozzo.com
Wed Jun 9 17:36:49 MSK 2021
The commit is pushed to "branch-rh7-3.10.0-1160.31.1.vz7.181.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.31.1.vz7.181.1
------>
commit 37353ee65d1bf51741004ba1a844dca58f085ad6
Author: Vasily Averin <vvs at virtuozzo.com>
Date: Wed Jun 9 17:36:49 2021 +0300
fs/nfs: break umount cycle if current task does not have enough stack.
vz7 commit d7ab92b772a5 ("fs/nfs: don't use delayed unmount for nfs")
forced synchronious NFS unmount, but it enabled cycle lead to stack
overflow. This patch break described cycle if stack of current task
is too low (i.e. according stack frame is locakted on lowest stack page).
https://jira.sw.ru/browse/PSBM-130309
Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
---
fs/namespace.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 9393d83..16a94d9 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1252,6 +1252,15 @@ static void delayed_mntput(struct work_struct *unused)
}
static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
+static inline bool stack_is_low(void)
+{
+ u64 curbase = (u64)task_stack_page(current);
+ u64 fp = (u64)__builtin_frame_address(0);
+ if ((fp < curbase + THREAD_SIZE) && (fp > curbase + PAGE_SIZE))
+ return false;
+ return true;
+}
+
static void mntput_no_expire(struct mount *mnt)
{
rcu_read_lock();
@@ -1295,7 +1304,8 @@ static void mntput_no_expire(struct mount *mnt)
unlock_mount_hash();
if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))
- && !(mnt->mnt.mnt_sb->s_iflags & SB_I_UMOUNT_SYNC)) {
+ && ((!(mnt->mnt.mnt_sb->s_iflags & SB_I_UMOUNT_SYNC)) ||
+ stack_is_low())) {
struct task_struct *task = current;
if (likely(!(task->flags & PF_KTHREAD))) {
init_task_work(&mnt->mnt_rcu, __cleanup_mnt);
More information about the Devel
mailing list