Like ksys_umount, but takes a kernel pointer for the destination path. Switch over the umount in the init code, which just happen to work due to the implicit set_fs(KERNEL_DS) during early init right now.
Unified · Split
| @@ -23,3 +23,17 @@ int __init init_mount(const char *dev_name, const char *dir_name, · 22 unmodified lines | |||
| 23 | path_put(&path); | 23 | path_put(&path); |
| 24 | return ret; | 24 | return ret; |
| 25 | } | 25 | } |
| 26 | |||
| 27 | int __init init_umount(const char *name, int flags) | ||
| 28 | { | ||
| 29 | int lookup_flags = LOOKUP_MOUNTPOINT; | ||
| 30 | struct path path; | ||
| 31 | int ret; | ||
| 32 | |||
| 33 | if (!(flags & UMOUNT_NOFOLLOW)) | ||
| 34 | lookup_flags |= LOOKUP_FOLLOW; | ||
| 35 | ret = kern_path(name, lookup_flags, &path); | ||
| 36 | if (ret) | ||
| 37 | return ret; | ||
| 38 | return path_umount(&path, flags); | ||
| 39 | } | ||
| @@ -92,6 +92,7 @@ extern void dissolve_on_fput(struct vfsmount *); · 91 unmodified lines | |||
| 92 | 92 | ||
| 93 | int path_mount(const char *dev_name, struct path *path, | 93 | int path_mount(const char *dev_name, struct path *path, |
| 94 | const char *type_page, unsigned long flags, void *data_page); | 94 | const char *type_page, unsigned long flags, void *data_page); |
| 95 | int path_umount(struct path *path, int flags); | ||
| 95 | 96 | ||
| 96 | /* | 97 | /* |
| 97 | * fs_struct.c | 98 | * fs_struct.c |
| @@ -1706,7 +1706,7 @@ static inline bool may_mandlock(void) · 1705 unmodified lines | |||
| 1706 | } | 1706 | } |
| 1707 | #endif | 1707 | #endif |
| 1708 | 1708 | ||
| 1709 | static int path_umount(struct path *path, int flags) | 1709 | int path_umount(struct path *path, int flags) |
| 1710 | { | 1710 | { |
| 1711 | struct mount *mnt; | 1711 | struct mount *mnt; |
| 1712 | int retval; | 1712 | int retval; |
| @@ -1736,7 +1736,7 @@ dput_and_out: · 23 unmodified lines | |||
| 1736 | return retval; | 1736 | return retval; |
| 1737 | } | 1737 | } |
| 1738 | 1738 | ||
| 1739 | int ksys_umount(char __user *name, int flags) | 1739 | static int ksys_umount(char __user *name, int flags) |
| 1740 | { | 1740 | { |
| 1741 | int lookup_flags = LOOKUP_MOUNTPOINT; | 1741 | int lookup_flags = LOOKUP_MOUNTPOINT; |
| 1742 | struct path path; | 1742 | struct path path; |
| @@ -2,3 +2,4 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | int __init init_mount(const char *dev_name, const char *dir_name, | 3 | int __init init_mount(const char *dev_name, const char *dir_name, |
| 4 | const char *type_page, unsigned long flags, void *data_page); | 4 | const char *type_page, unsigned long flags, void *data_page); |
| 5 | int __init init_umount(const char *name, int flags); | ||
| @@ -1236,7 +1236,6 @@ asmlinkage long sys_ni_syscall(void); · 1235 unmodified lines | |||
| 1236 | * the ksys_xyzyyz() functions prototyped below. | 1236 | * the ksys_xyzyyz() functions prototyped below. |
| 1237 | */ | 1237 | */ |
| 1238 | 1238 | ||
| 1239 | int ksys_umount(char __user *name, int flags); | ||
| 1240 | int ksys_chroot(const char __user *filename); | 1239 | int ksys_chroot(const char __user *filename); |
| 1241 | ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); | 1240 | ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); |
| 1242 | int ksys_chdir(const char __user *filename); | 1241 | int ksys_chdir(const char __user *filename); |
| @@ -122,7 +122,7 @@ static void __init handle_initrd(void) · 121 unmodified lines | |||
| 122 | else | 122 | else |
| 123 | printk("failed\n"); | 123 | printk("failed\n"); |
| 124 | printk(KERN_NOTICE "Unmounting old root\n"); | 124 | printk(KERN_NOTICE "Unmounting old root\n"); |
| 125 | ksys_umount("/old", MNT_DETACH); | 125 | init_umount("/old", MNT_DETACH); |
| 126 | } | 126 | } |
| 127 | } | 127 | } |
| 128 | 128 | ||