... and provide file_open_root_mnt(), using the root of given mount.
Unified · Split
| @@ -890,3 +890,12 @@ been called or returned with non -EIOCBQUEUED code. · 889 unmodified lines | |||
| 890 | 890 | ||
| 891 | mnt_want_write_file() can now only be paired with mnt_drop_write_file(), | 891 | mnt_want_write_file() can now only be paired with mnt_drop_write_file(), |
| 892 | whereas previously it could be paired with mnt_drop_write() as well. | 892 | whereas previously it could be paired with mnt_drop_write() as well. |
| 893 | |||
| 894 | --- | ||
| 895 | |||
| 896 | **mandatory** | ||
| 897 | |||
| 898 | Calling conventions for file_open_root() changed; now it takes struct path * | ||
| 899 | instead of passing mount and dentry separately. For callers that used to | ||
| 900 | pass <mnt, mnt->mnt_root> pair (i.e. the root of given mount), a new helper | ||
| 901 | is provided - file_open_root_mnt(). In-tree users adjusted. | ||
| @@ -140,7 +140,7 @@ void mconsole_proc(struct mc_request *req) · 139 unmodified lines | |||
| 140 | mconsole_reply(req, "Proc not available", 1, 0); | 140 | mconsole_reply(req, "Proc not available", 1, 0); |
| 141 | goto out; | 141 | goto out; |
| 142 | } | 142 | } |
| 143 | file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0); | 143 | file = file_open_root_mnt(mnt, ptr, O_RDONLY, 0); |
| 144 | if (IS_ERR(file)) { | 144 | if (IS_ERR(file)) { |
| 145 | mconsole_reply(req, "Failed to open file", 1, 0); | 145 | mconsole_reply(req, "Failed to open file", 1, 0); |
| 146 | printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file)); | 146 | printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file)); |
| @@ -755,8 +755,8 @@ void do_coredump(const kernel_siginfo_t *siginfo) · 754 unmodified lines | |||
| 755 | task_lock(&init_task); | 755 | task_lock(&init_task); |
| 756 | get_fs_root(init_task.fs, &root); | 756 | get_fs_root(init_task.fs, &root); |
| 757 | task_unlock(&init_task); | 757 | task_unlock(&init_task); |
| 758 | cprm.file = file_open_root(root.dentry, root.mnt, | 758 | cprm.file = file_open_root(&root, cn.corename, |
| 759 | cn.corename, open_flags, 0600); | 759 | open_flags, 0600); |
| 760 | path_put(&root); | 760 | path_put(&root); |
| 761 | } else { | 761 | } else { |
| 762 | cprm.file = filp_open(cn.corename, open_flags, 0600); | 762 | cprm.file = filp_open(cn.corename, open_flags, 0600); |
| @@ -229,7 +229,7 @@ static long do_handle_open(int mountdirfd, struct file_handle __user *ufh, · 228 unmodified lines | |||
| 229 | path_put(&path); | 229 | path_put(&path); |
| 230 | return fd; | 230 | return fd; |
| 231 | } | 231 | } |
| 232 | file = file_open_root(path.dentry, path.mnt, "", open_flag, 0); | 232 | file = file_open_root(&path, "", open_flag, 0); |
| 233 | if (IS_ERR(file)) { | 233 | if (IS_ERR(file)) { |
| 234 | put_unused_fd(fd); | 234 | put_unused_fd(fd); |
| 235 | retval = PTR_ERR(file); | 235 | retval = PTR_ERR(file); |
| @@ -129,7 +129,7 @@ struct open_flags { · 128 unmodified lines | |||
| 129 | }; | 129 | }; |
| 130 | extern struct file *do_filp_open(int dfd, struct filename *pathname, | 130 | extern struct file *do_filp_open(int dfd, struct filename *pathname, |
| 131 | const struct open_flags *op); | 131 | const struct open_flags *op); |
| 132 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, | 132 | extern struct file *do_file_open_root(const struct path *, |
| 133 | const char *, const struct open_flags *); | 133 | const char *, const struct open_flags *); |
| 134 | extern struct open_how build_open_how(int flags, umode_t mode); | 134 | extern struct open_how build_open_how(int flags, umode_t mode); |
| 135 | extern int build_open_flags(const struct open_how *how, struct open_flags *op); | 135 | extern int build_open_flags(const struct open_how *how, struct open_flags *op); |
| @@ -160,7 +160,7 @@ int kernel_read_file_from_path_initns(const char *path, loff_t offset, · 159 unmodified lines | |||
| 160 | get_fs_root(init_task.fs, &root); | 160 | get_fs_root(init_task.fs, &root); |
| 161 | task_unlock(&init_task); | 161 | task_unlock(&init_task); |
| 162 | 162 | ||
| 163 | file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0); | 163 | file = file_open_root(&root, path, O_RDONLY, 0); |
| 164 | path_put(&root); | 164 | path_put(&root); |
| 165 | if (IS_ERR(file)) | 165 | if (IS_ERR(file)) |
| 166 | return PTR_ERR(file); | 166 | return PTR_ERR(file); |
| @@ -3533,7 +3533,7 @@ struct file *do_filp_open(int dfd, struct filename *pathname, · 3532 unmodified lines | |||
| 3533 | return filp; | 3533 | return filp; |
| 3534 | } | 3534 | } |
| 3535 | 3535 | ||
| 3536 | struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | 3536 | struct file *do_file_open_root(const struct path *root, |
| 3537 | const char *name, const struct open_flags *op) | 3537 | const char *name, const struct open_flags *op) |
| 3538 | { | 3538 | { |
| 3539 | struct nameidata nd; | 3539 | struct nameidata nd; |
| @@ -3541,16 +3541,14 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, · 1 unmodified line | |||
| 3541 | struct filename *filename; | 3541 | struct filename *filename; |
| 3542 | int flags = op->lookup_flags | LOOKUP_ROOT; | 3542 | int flags = op->lookup_flags | LOOKUP_ROOT; |
| 3543 | 3543 | ||
| 3544 | nd.root.mnt = mnt; | 3544 | if (d_is_symlink(root->dentry) && op->intent & LOOKUP_OPEN) |
| 3545 | nd.root.dentry = dentry; | ||
| 3546 | |||
| 3547 | if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN) | ||
| 3548 | return ERR_PTR(-ELOOP); | 3545 | return ERR_PTR(-ELOOP); |
| 3549 | 3546 | ||
| 3550 | filename = getname_kernel(name); | 3547 | filename = getname_kernel(name); |
| 3551 | if (IS_ERR(filename)) | 3548 | if (IS_ERR(filename)) |
| 3552 | return ERR_CAST(filename); | 3549 | return ERR_CAST(filename); |
| 3553 | 3550 | ||
| 3551 | nd.root = *root; | ||
| 3554 | set_nameidata(&nd, -1, filename); | 3552 | set_nameidata(&nd, -1, filename); |
| 3555 | file = path_openat(&nd, op, flags | LOOKUP_RCU); | 3553 | file = path_openat(&nd, op, flags | LOOKUP_RCU); |
| 3556 | if (unlikely(file == ERR_PTR(-ECHILD))) | 3554 | if (unlikely(file == ERR_PTR(-ECHILD))) |
| @@ -1156,7 +1156,7 @@ struct file *filp_open(const char *filename, int flags, umode_t mode) · 1155 unmodified lines | |||
| 1156 | } | 1156 | } |
| 1157 | EXPORT_SYMBOL(filp_open); | 1157 | EXPORT_SYMBOL(filp_open); |
| 1158 | 1158 | ||
| 1159 | struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, | 1159 | struct file *file_open_root(const struct path *root, |
| 1160 | const char *filename, int flags, umode_t mode) | 1160 | const char *filename, int flags, umode_t mode) |
| 1161 | { | 1161 | { |
| 1162 | struct open_flags op; | 1162 | struct open_flags op; |
| @@ -1164,7 +1164,7 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, · 1 unmodified line | |||
| 1164 | int err = build_open_flags(&how, &op); | 1164 | int err = build_open_flags(&how, &op); |
| 1165 | if (err) | 1165 | if (err) |
| 1166 | return ERR_PTR(err); | 1166 | return ERR_PTR(err); |
| 1167 | return do_file_open_root(dentry, mnt, filename, &op); | 1167 | return do_file_open_root(root, filename, &op); |
| 1168 | } | 1168 | } |
| 1169 | EXPORT_SYMBOL(file_open_root); | 1169 | EXPORT_SYMBOL(file_open_root); |
| 1170 | 1170 | ||
| @@ -1806,7 +1806,7 @@ static int process_sysctl_arg(char *param, char *val, · 1805 unmodified lines | |||
| 1806 | panic("%s: Failed to allocate path for %s\n", __func__, param); | 1806 | panic("%s: Failed to allocate path for %s\n", __func__, param); |
| 1807 | strreplace(path, '.', '/'); | 1807 | strreplace(path, '.', '/'); |
| 1808 | 1808 | ||
| 1809 | file = file_open_root((*proc_mnt)->mnt_root, *proc_mnt, path, O_WRONLY, 0); | 1809 | file = file_open_root_mnt(*proc_mnt, path, O_WRONLY, 0); |
| 1810 | if (IS_ERR(file)) { | 1810 | if (IS_ERR(file)) { |
| 1811 | err = PTR_ERR(file); | 1811 | err = PTR_ERR(file); |
| 1812 | if (err == -ENOENT) | 1812 | if (err == -ENOENT) |
| @@ -2632,8 +2632,14 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags, · 2631 unmodified lines | |||
| 2632 | umode_t mode); | 2632 | umode_t mode); |
| 2633 | extern struct file *file_open_name(struct filename *, int, umode_t); | 2633 | extern struct file *file_open_name(struct filename *, int, umode_t); |
| 2634 | extern struct file *filp_open(const char *, int, umode_t); | 2634 | extern struct file *filp_open(const char *, int, umode_t); |
| 2635 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, | 2635 | extern struct file *file_open_root(const struct path *, |
| 2636 | const char *, int, umode_t); | 2636 | const char *, int, umode_t); |
| 2637 | static inline struct file *file_open_root_mnt(struct vfsmount *mnt, | ||
| 2638 | const char *name, int flags, umode_t mode) | ||
| 2639 | { | ||
| 2640 | return file_open_root(&(struct path){.mnt = mnt, .dentry = mnt->mnt_root}, | ||
| 2641 | name, flags, mode); | ||
| 2642 | } | ||
| 2637 | extern struct file * dentry_open(const struct path *, int, const struct cred *); | 2643 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
| 2638 | extern struct file * open_with_fake_path(const struct path *, int, | 2644 | extern struct file * open_with_fake_path(const struct path *, int, |
| 2639 | struct inode*, const struct cred *); | 2645 | struct inode*, const struct cred *); |
| @@ -26,7 +26,7 @@ static struct vfsmount *blob_to_mnt(const void *data, size_t len, const char *na · 25 unmodified lines | |||
| 26 | if (IS_ERR(mnt)) | 26 | if (IS_ERR(mnt)) |
| 27 | return mnt; | 27 | return mnt; |
| 28 | 28 | ||
| 29 | file = file_open_root(mnt->mnt_root, mnt, name, O_CREAT | O_WRONLY, 0700); | 29 | file = file_open_root_mnt(mnt, name, O_CREAT | O_WRONLY, 0700); |
| 30 | if (IS_ERR(file)) { | 30 | if (IS_ERR(file)) { |
| 31 | mntput(mnt); | 31 | mntput(mnt); |
| 32 | return ERR_CAST(file); | 32 | return ERR_CAST(file); |