[Devel] [PATCH RH7] fs/nfs: break umount cycle if current task does not have enough stack.

Vasily Averin vvs at virtuozzo.com
Wed Jun 9 16:25:59 MSK 2021


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 9393d8364329..16a94d9ba877 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);
-- 
2.25.1



More information about the Devel mailing list