diff options
| -rw-r--r-- | fs/exec.c | 5 | ||||
| -rw-r--r-- | fs/internal.h | 4 | ||||
| -rw-r--r-- | fs/namei.c | 18 | ||||
| -rw-r--r-- | fs/open.c | 25 | ||||
| -rw-r--r-- | include/linux/fs.h | 1 | ||||
| -rw-r--r-- | kernel/acct.c | 6 | ||||
| -rw-r--r-- | mm/swapfile.c | 4 |
7 files changed, 42 insertions, 21 deletions
| @@ -116,7 +116,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) | |||
| 116 | if (IS_ERR(tmp)) | 116 | if (IS_ERR(tmp)) |
| 117 | goto out; | 117 | goto out; |
| 118 | 118 | ||
| 119 | file = do_filp_open(AT_FDCWD, tmp->name, &uselib_flags, LOOKUP_FOLLOW); | 119 | file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW); |
| 120 | putname(tmp); | 120 | putname(tmp); |
| 121 | error = PTR_ERR(file); | 121 | error = PTR_ERR(file); |
| 122 | if (IS_ERR(file)) | 122 | if (IS_ERR(file)) |
| @@ -751,13 +751,14 @@ struct file *open_exec(const char *name) | |||
| 751 | { | 751 | { |
| 752 | struct file *file; | 752 | struct file *file; |
| 753 | int err; | 753 | int err; |
| 754 | struct filename tmp = { .name = name }; | ||
| 754 | static const struct open_flags open_exec_flags = { | 755 | static const struct open_flags open_exec_flags = { |
| 755 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 756 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
| 756 | .acc_mode = MAY_EXEC | MAY_OPEN, | 757 | .acc_mode = MAY_EXEC | MAY_OPEN, |
| 757 | .intent = LOOKUP_OPEN | 758 | .intent = LOOKUP_OPEN |
| 758 | }; | 759 | }; |
| 759 | 760 | ||
| 760 | file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW); | 761 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW); |
| 761 | if (IS_ERR(file)) | 762 | if (IS_ERR(file)) |
| 762 | goto out; | 763 | goto out; |
| 763 | 764 | ||
diff --git a/fs/internal.h b/fs/internal.h index 371bcc4b1697..916b7cbf3e3e 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -97,8 +97,8 @@ struct open_flags { | |||
| 97 | int acc_mode; | 97 | int acc_mode; |
| 98 | int intent; | 98 | int intent; |
| 99 | }; | 99 | }; |
| 100 | extern struct file *do_filp_open(int dfd, const char *pathname, | 100 | extern struct file *do_filp_open(int dfd, struct filename *pathname, |
| 101 | const struct open_flags *op, int lookup_flags); | 101 | const struct open_flags *op, int flags); |
| 102 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, | 102 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, |
| 103 | const char *, const struct open_flags *, int lookup_flags); | 103 | const char *, const struct open_flags *, int lookup_flags); |
| 104 | 104 | ||
diff --git a/fs/namei.c b/fs/namei.c index 8c14353fb750..6bbd8fdfb1f5 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -2662,7 +2662,7 @@ out_dput: | |||
| 2662 | */ | 2662 | */ |
| 2663 | static int do_last(struct nameidata *nd, struct path *path, | 2663 | static int do_last(struct nameidata *nd, struct path *path, |
| 2664 | struct file *file, const struct open_flags *op, | 2664 | struct file *file, const struct open_flags *op, |
| 2665 | int *opened, const char *pathname) | 2665 | int *opened, struct filename *name) |
| 2666 | { | 2666 | { |
| 2667 | struct dentry *dir = nd->path.dentry; | 2667 | struct dentry *dir = nd->path.dentry; |
| 2668 | int open_flag = op->open_flag; | 2668 | int open_flag = op->open_flag; |
| @@ -2674,6 +2674,7 @@ static int do_last(struct nameidata *nd, struct path *path, | |||
| 2674 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; | 2674 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; |
| 2675 | bool retried = false; | 2675 | bool retried = false; |
| 2676 | int error; | 2676 | int error; |
| 2677 | const char *pathname = name->name; | ||
| 2677 | 2678 | ||
| 2678 | nd->flags &= ~LOOKUP_PARENT; | 2679 | nd->flags &= ~LOOKUP_PARENT; |
| 2679 | nd->flags |= op->intent; | 2680 | nd->flags |= op->intent; |
| @@ -2908,7 +2909,7 @@ stale_open: | |||
| 2908 | goto retry_lookup; | 2909 | goto retry_lookup; |
| 2909 | } | 2910 | } |
| 2910 | 2911 | ||
| 2911 | static struct file *path_openat(int dfd, const char *pathname, | 2912 | static struct file *path_openat(int dfd, struct filename *pathname, |
| 2912 | struct nameidata *nd, const struct open_flags *op, int flags) | 2913 | struct nameidata *nd, const struct open_flags *op, int flags) |
| 2913 | { | 2914 | { |
| 2914 | struct file *base = NULL; | 2915 | struct file *base = NULL; |
| @@ -2923,12 +2924,12 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
| 2923 | 2924 | ||
| 2924 | file->f_flags = op->open_flag; | 2925 | file->f_flags = op->open_flag; |
| 2925 | 2926 | ||
| 2926 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); | 2927 | error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); |
| 2927 | if (unlikely(error)) | 2928 | if (unlikely(error)) |
| 2928 | goto out; | 2929 | goto out; |
| 2929 | 2930 | ||
| 2930 | current->total_link_count = 0; | 2931 | current->total_link_count = 0; |
| 2931 | error = link_path_walk(pathname, nd); | 2932 | error = link_path_walk(pathname->name, nd); |
| 2932 | if (unlikely(error)) | 2933 | if (unlikely(error)) |
| 2933 | goto out; | 2934 | goto out; |
| 2934 | 2935 | ||
| @@ -2974,7 +2975,7 @@ out: | |||
| 2974 | return file; | 2975 | return file; |
| 2975 | } | 2976 | } |
| 2976 | 2977 | ||
| 2977 | struct file *do_filp_open(int dfd, const char *pathname, | 2978 | struct file *do_filp_open(int dfd, struct filename *pathname, |
| 2978 | const struct open_flags *op, int flags) | 2979 | const struct open_flags *op, int flags) |
| 2979 | { | 2980 | { |
| 2980 | struct nameidata nd; | 2981 | struct nameidata nd; |
| @@ -2993,6 +2994,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
| 2993 | { | 2994 | { |
| 2994 | struct nameidata nd; | 2995 | struct nameidata nd; |
| 2995 | struct file *file; | 2996 | struct file *file; |
| 2997 | struct filename filename = { .name = name }; | ||
| 2996 | 2998 | ||
| 2997 | nd.root.mnt = mnt; | 2999 | nd.root.mnt = mnt; |
| 2998 | nd.root.dentry = dentry; | 3000 | nd.root.dentry = dentry; |
| @@ -3002,11 +3004,11 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
| 3002 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) | 3004 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) |
| 3003 | return ERR_PTR(-ELOOP); | 3005 | return ERR_PTR(-ELOOP); |
| 3004 | 3006 | ||
| 3005 | file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU); | 3007 | file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU); |
| 3006 | if (unlikely(file == ERR_PTR(-ECHILD))) | 3008 | if (unlikely(file == ERR_PTR(-ECHILD))) |
| 3007 | file = path_openat(-1, name, &nd, op, flags); | 3009 | file = path_openat(-1, &filename, &nd, op, flags); |
| 3008 | if (unlikely(file == ERR_PTR(-ESTALE))) | 3010 | if (unlikely(file == ERR_PTR(-ESTALE))) |
| 3009 | file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL); | 3011 | file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL); |
| 3010 | return file; | 3012 | return file; |
| 3011 | } | 3013 | } |
| 3012 | 3014 | ||
| @@ -859,6 +859,24 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | /** | 861 | /** |
| 862 | * file_open_name - open file and return file pointer | ||
| 863 | * | ||
| 864 | * @name: struct filename containing path to open | ||
| 865 | * @flags: open flags as per the open(2) second argument | ||
| 866 | * @mode: mode for the new file if O_CREAT is set, else ignored | ||
| 867 | * | ||
| 868 | * This is the helper to open a file from kernelspace if you really | ||
| 869 | * have to. But in generally you should not do this, so please move | ||
| 870 | * along, nothing to see here.. | ||
| 871 | */ | ||
| 872 | struct file *file_open_name(struct filename *name, int flags, umode_t mode) | ||
| 873 | { | ||
| 874 | struct open_flags op; | ||
| 875 | int lookup = build_open_flags(flags, mode, &op); | ||
| 876 | return do_filp_open(AT_FDCWD, name, &op, lookup); | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 862 | * filp_open - open file and return file pointer | 880 | * filp_open - open file and return file pointer |
| 863 | * | 881 | * |
| 864 | * @filename: path to open | 882 | * @filename: path to open |
| @@ -871,9 +889,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
| 871 | */ | 889 | */ |
| 872 | struct file *filp_open(const char *filename, int flags, umode_t mode) | 890 | struct file *filp_open(const char *filename, int flags, umode_t mode) |
| 873 | { | 891 | { |
| 874 | struct open_flags op; | 892 | struct filename name = {.name = filename}; |
| 875 | int lookup = build_open_flags(flags, mode, &op); | 893 | return file_open_name(&name, flags, mode); |
| 876 | return do_filp_open(AT_FDCWD, filename, &op, lookup); | ||
| 877 | } | 894 | } |
| 878 | EXPORT_SYMBOL(filp_open); | 895 | EXPORT_SYMBOL(filp_open); |
| 879 | 896 | ||
| @@ -901,7 +918,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | |||
| 901 | if (!IS_ERR(tmp)) { | 918 | if (!IS_ERR(tmp)) { |
| 902 | fd = get_unused_fd_flags(flags); | 919 | fd = get_unused_fd_flags(flags); |
| 903 | if (fd >= 0) { | 920 | if (fd >= 0) { |
| 904 | struct file *f = do_filp_open(dfd, tmp->name, &op, lookup); | 921 | struct file *f = do_filp_open(dfd, tmp, &op, lookup); |
| 905 | if (IS_ERR(f)) { | 922 | if (IS_ERR(f)) { |
| 906 | put_unused_fd(fd); | 923 | put_unused_fd(fd); |
| 907 | fd = PTR_ERR(f); | 924 | fd = PTR_ERR(f); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6c93b46f46dc..b6b10e7f0ac0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -2207,6 +2207,7 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2207 | loff_t len); | 2207 | loff_t len); |
| 2208 | extern long do_sys_open(int dfd, const char __user *filename, int flags, | 2208 | extern long do_sys_open(int dfd, const char __user *filename, int flags, |
| 2209 | umode_t mode); | 2209 | umode_t mode); |
| 2210 | extern struct file *file_open_name(struct filename *, int, umode_t); | ||
| 2210 | extern struct file *filp_open(const char *, int, umode_t); | 2211 | extern struct file *filp_open(const char *, int, umode_t); |
| 2211 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, | 2212 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, |
| 2212 | const char *, int); | 2213 | const char *, int); |
diff --git a/kernel/acct.c b/kernel/acct.c index 08354195eecc..051e071a06e7 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
| @@ -193,7 +193,7 @@ static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file, | |||
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static int acct_on(const char *name) | 196 | static int acct_on(struct filename *pathname) |
| 197 | { | 197 | { |
| 198 | struct file *file; | 198 | struct file *file; |
| 199 | struct vfsmount *mnt; | 199 | struct vfsmount *mnt; |
| @@ -201,7 +201,7 @@ static int acct_on(const char *name) | |||
| 201 | struct bsd_acct_struct *acct = NULL; | 201 | struct bsd_acct_struct *acct = NULL; |
| 202 | 202 | ||
| 203 | /* Difference from BSD - they don't do O_APPEND */ | 203 | /* Difference from BSD - they don't do O_APPEND */ |
| 204 | file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0); | 204 | file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0); |
| 205 | if (IS_ERR(file)) | 205 | if (IS_ERR(file)) |
| 206 | return PTR_ERR(file); | 206 | return PTR_ERR(file); |
| 207 | 207 | ||
| @@ -263,7 +263,7 @@ SYSCALL_DEFINE1(acct, const char __user *, name) | |||
| 263 | struct filename *tmp = getname(name); | 263 | struct filename *tmp = getname(name); |
| 264 | if (IS_ERR(tmp)) | 264 | if (IS_ERR(tmp)) |
| 265 | return (PTR_ERR(tmp)); | 265 | return (PTR_ERR(tmp)); |
| 266 | error = acct_on(tmp->name); | 266 | error = acct_on(tmp); |
| 267 | putname(tmp); | 267 | putname(tmp); |
| 268 | } else { | 268 | } else { |
| 269 | struct bsd_acct_struct *acct; | 269 | struct bsd_acct_struct *acct; |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 90d2ed591de9..71cd288b2001 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -1498,7 +1498,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
| 1498 | if (IS_ERR(pathname)) | 1498 | if (IS_ERR(pathname)) |
| 1499 | goto out; | 1499 | goto out; |
| 1500 | 1500 | ||
| 1501 | victim = filp_open(pathname->name, O_RDWR|O_LARGEFILE, 0); | 1501 | victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0); |
| 1502 | err = PTR_ERR(victim); | 1502 | err = PTR_ERR(victim); |
| 1503 | if (IS_ERR(victim)) | 1503 | if (IS_ERR(victim)) |
| 1504 | goto out; | 1504 | goto out; |
| @@ -1966,7 +1966,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
| 1966 | name = NULL; | 1966 | name = NULL; |
| 1967 | goto bad_swap; | 1967 | goto bad_swap; |
| 1968 | } | 1968 | } |
| 1969 | swap_file = filp_open(name->name, O_RDWR|O_LARGEFILE, 0); | 1969 | swap_file = file_open_name(name, O_RDWR|O_LARGEFILE, 0); |
| 1970 | if (IS_ERR(swap_file)) { | 1970 | if (IS_ERR(swap_file)) { |
| 1971 | error = PTR_ERR(swap_file); | 1971 | error = PTR_ERR(swap_file); |
| 1972 | swap_file = NULL; | 1972 | swap_file = NULL; |
