Skip to content

Instantly share code, notes, and snippets.

@devnoname120
Created May 24, 2025 06:12
Show Gist options
  • Save devnoname120/8aa52912674e9dfe769011f6f480927f to your computer and use it in GitHub Desktop.
Save devnoname120/8aa52912674e9dfe769011f6f480927f to your computer and use it in GitHub Desktop.
umount.cocci for Linux < 3.12
@has_can_umount@
identifier path, flags;
@@
can_umount(const struct path *path, int flags) { ... }
// Backport for Linux < 5.9
// File: fs/namespace.c
@path_umount depends on file in "namespace.c" && never has_can_umount@
@@
do_umount(...) { ... }
+static int can_umount(const struct path *path, int flags)
+{
+struct mount *mnt = real_mount(path->mnt);
+
+if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
+ return -EINVAL;
+if (!may_mount())
+ return -EPERM;
+if (path->dentry != path->mnt->mnt_root)
+ return -EINVAL;
+if (!check_mnt(mnt))
+ return -EINVAL;
+#ifdef MNT_LOCKED /* Only available on Linux 3.12+ https://github.com/torvalds/linux/commit/5ff9d8a65ce80efb509ce4e8051394e9ed2cd942 */
+if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
+ return -EINVAL;
+#endif
+if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+return 0;
+}
+
+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;
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment