diff --git a/fs/namespace.c b/fs/namespace.c index 2fd0bf91aa77..3441aa0edbef 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -42,6 +42,33 @@ static unsigned int m_hash_shift __read_mostly; static unsigned int mp_hash_mask __read_mostly; static unsigned int mp_hash_shift __read_mostly; +# UMOUNT Backport +static int can_umount(const struct path *path, int flags) +{ + struct mount *mnt = real_mount(path->mnt); + if (!may_mount()) + return -EPERM; + if (!path_mounted(path)) + return -EINVAL; + if (!check_mnt(mnt)) + return -EINVAL; + if (mnt->mnt.mnt_flags & MNT_LOCKED) + return -EINVAL; + 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); + return ret; +} + static __initdata unsigned long mhash_entries; static int __init set_mhash_entries(char *str) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 773492ba2e6e..a120d0c74f32 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -46,6 +46,9 @@ #include #include +// In fs/namespace.c +EXPORT_SYMBOL(path_umount); + struct backing_dev_info; struct bdi_writeback; struct bio;