Repository navigation
Expand file tree
/
Copy pathpath_unmount.patch
More file actions
executable file
·66 lines (61 loc) · 1.9 KB
/
Copy pathpath_unmount.patch
File metadata and controls
executable file
·66 lines (61 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
From 2d514220cd262a772b35fae79358167ae1de9872 Mon Sep 17 00:00:00 2001
From: backslashxx <118538522+backslashxx@users.noreply.github.com>
Date: Sun, 24 Mar 2024 16:02:10 +0800
Subject: [PATCH] BACKPORT: fs/namespace.c path_umount [5.10.9]
---
fs/internal.h | 1 +
fs/namespace.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/fs/internal.h b/fs/internal.h
index 204e1e253283..dffebf7b32f3 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -68,6 +68,7 @@ extern int finish_automount(struct vfsmount *, struct path *);
extern int sb_prepare_remount_readonly(struct super_block *);
extern void __init mnt_init(void);
+int path_umount(struct path *path, int flags);
extern int __mnt_want_write(struct vfsmount *);
extern int __mnt_want_write_file(struct file *);
diff --git a/fs/namespace.c b/fs/namespace.c
index 6ca275c923c1..0001b8b3aa0a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1739,6 +1739,39 @@ static inline bool may_mandlock(void)
}
#endif
+static int can_umount(const struct path *path, int flags)
+{
+ struct mount *mnt = real_mount(path->mnt);
+
+ if (!may_mount())
+ return -EPERM;
+ if (path->dentry != path->mnt->mnt_root)
+ return -EINVAL;
+ if (!check_mnt(mnt))
+ return -EINVAL;
+ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
+ return -EINVAL;
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return 0;
+}
+
+// caller is responsible for flags being sane
+int path_umount(struct path *path, int flags)
+{
+ struct mount *mnt = real_mount(path->mnt);
+ int ret;
+
+ ret = can_umount(path, flags);
+ if (!ret)
+ ret = do_umount(mnt, flags);
+
+ /* we mustn't call path_put() as that would clear mnt_expiry_mark */
+ dput(path->dentry);
+ mntput_no_expire(mnt);
+ return ret;
+}
+
/*
* Now umount can handle mount points as well as block devices.
* This is important for filesystems which use unnamed block devices.