aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-27 19:14:10 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-02 19:51:15 -0400
commit1643b43fbd0524e7da7259075032936c8fb68a05 (patch)
tree66547bd78ecd6c7dd922e1784c51ab352e1a1cba
parentb3d58eaffb98e1b5bbf2d6756c59398213caba57 (diff)
lookup_open(): lift the "fallback to !O_CREAT" logics from atomic_open()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c144
1 files changed, 55 insertions, 89 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 8d562a7a7e01..4359d22f43f4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2824,63 +2824,19 @@ static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode)
2824static int atomic_open(struct nameidata *nd, struct dentry *dentry, 2824static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2825 struct path *path, struct file *file, 2825 struct path *path, struct file *file,
2826 const struct open_flags *op, 2826 const struct open_flags *op,
2827 bool got_write, bool need_lookup, 2827 int open_flag, umode_t mode,
2828 int *opened) 2828 int *opened)
2829{ 2829{
2830 struct inode *dir = nd->path.dentry->d_inode; 2830 struct inode *dir = nd->path.dentry->d_inode;
2831 unsigned open_flag = op->open_flag;
2832 umode_t mode;
2833 int error; 2831 int error;
2834 int acc_mode; 2832 int acc_mode;
2835 int create_error = 0;
2836 struct dentry *const DENTRY_NOT_SET = (void *) -1UL; 2833 struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
2837 bool excl; 2834 bool excl;
2838 2835
2839 BUG_ON(dentry->d_inode);
2840
2841 mode = op->mode;
2842 if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
2843 mode &= ~current_umask();
2844
2845 excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); 2836 excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT);
2846 if (excl) 2837 if (excl)
2847 open_flag &= ~O_TRUNC; 2838 open_flag &= ~O_TRUNC;
2848 2839
2849 /*
2850 * Checking write permission is tricky, bacuse we don't know if we are
2851 * going to actually need it: O_CREAT opens should work as long as the
2852 * file exists. But checking existence breaks atomicity. The trick is
2853 * to check access and if not granted clear O_CREAT from the flags.
2854 *
2855 * Another problem is returing the "right" error value (e.g. for an
2856 * O_EXCL open we want to return EEXIST not EROFS).
2857 */
2858 if (open_flag & O_CREAT) {
2859 if (unlikely(!got_write)) {
2860 create_error = -EROFS;
2861 if (open_flag & (O_EXCL | O_TRUNC)) {
2862 /* Fall back and fail with the right error */
2863 goto no_open;
2864 }
2865 /* No side effects, safe to clear O_CREAT */
2866 open_flag &= ~O_CREAT;
2867 } else {
2868 create_error = may_o_create(&nd->path, dentry, mode);
2869 if (create_error) {
2870 if (open_flag & O_EXCL)
2871 goto no_open;
2872 open_flag &= ~O_CREAT;
2873 }
2874 }
2875 } else if ((open_flag & (O_TRUNC|O_WRONLY|O_RDWR)) &&
2876 unlikely(!got_write)) {
2877 /*
2878 * No O_CREATE -> atomicity not a requirement -> fall
2879 * back to lookup + open
2880 */
2881 goto no_open;
2882 }
2883
2884 if (nd->flags & LOOKUP_DIRECTORY) 2840 if (nd->flags & LOOKUP_DIRECTORY)
2885 open_flag |= O_DIRECTORY; 2841 open_flag |= O_DIRECTORY;
2886 2842
@@ -2889,11 +2845,8 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2889 error = dir->i_op->atomic_open(dir, dentry, file, 2845 error = dir->i_op->atomic_open(dir, dentry, file,
2890 open_to_namei_flags(open_flag), 2846 open_to_namei_flags(open_flag),
2891 mode, opened); 2847 mode, opened);
2892 if (error < 0) { 2848 if (error < 0)
2893 if (create_error && error == -ENOENT)
2894 error = create_error;
2895 goto out; 2849 goto out;
2896 }
2897 2850
2898 if (error) { /* returned 1, that is */ 2851 if (error) { /* returned 1, that is */
2899 if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { 2852 if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
@@ -2906,7 +2859,9 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2906 } 2859 }
2907 if (*opened & FILE_CREATED) 2860 if (*opened & FILE_CREATED)
2908 fsnotify_create(dir, dentry); 2861 fsnotify_create(dir, dentry);
2909 goto looked_up; 2862 path->dentry = dentry;
2863 path->mnt = nd->path.mnt;
2864 return 1;
2910 } 2865 }
2911 2866
2912 /* 2867 /*
@@ -2925,21 +2880,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2925out: 2880out:
2926 dput(dentry); 2881 dput(dentry);
2927 return error; 2882 return error;
2928
2929no_open:
2930 if (need_lookup) {
2931 dentry = lookup_real(dir, dentry, nd->flags);
2932 if (IS_ERR(dentry))
2933 return PTR_ERR(dentry);
2934 }
2935looked_up:
2936 if (create_error && !dentry->d_inode) {
2937 error = create_error;
2938 goto out;
2939 }
2940 path->dentry = dentry;
2941 path->mnt = nd->path.mnt;
2942 return 1;
2943} 2883}
2944 2884
2945/* 2885/*
@@ -2967,9 +2907,11 @@ static int lookup_open(struct nameidata *nd, struct path *path,
2967{ 2907{
2968 struct dentry *dir = nd->path.dentry; 2908 struct dentry *dir = nd->path.dentry;
2969 struct inode *dir_inode = dir->d_inode; 2909 struct inode *dir_inode = dir->d_inode;
2910 int open_flag = op->open_flag;
2970 struct dentry *dentry; 2911 struct dentry *dentry;
2971 int error; 2912 int error, create_error = 0;
2972 bool need_lookup = false; 2913 bool need_lookup = false;
2914 umode_t mode = op->mode;
2973 2915
2974 if (unlikely(IS_DEADDIR(dir_inode))) 2916 if (unlikely(IS_DEADDIR(dir_inode)))
2975 return -ENOENT; 2917 return -ENOENT;
@@ -2989,50 +2931,74 @@ static int lookup_open(struct nameidata *nd, struct path *path,
2989 goto out_no_open; 2931 goto out_no_open;
2990 } 2932 }
2991 2933
2934 /*
2935 * Checking write permission is tricky, bacuse we don't know if we are
2936 * going to actually need it: O_CREAT opens should work as long as the
2937 * file exists. But checking existence breaks atomicity. The trick is
2938 * to check access and if not granted clear O_CREAT from the flags.
2939 *
2940 * Another problem is returing the "right" error value (e.g. for an
2941 * O_EXCL open we want to return EEXIST not EROFS).
2942 */
2943 if (open_flag & O_CREAT) {
2944 if (!IS_POSIXACL(dir->d_inode))
2945 mode &= ~current_umask();
2946 if (unlikely(!got_write)) {
2947 create_error = -EROFS;
2948 open_flag &= ~O_CREAT;
2949 if (open_flag & (O_EXCL | O_TRUNC))
2950 goto no_open;
2951 /* No side effects, safe to clear O_CREAT */
2952 } else {
2953 create_error = may_o_create(&nd->path, dentry, mode);
2954 if (create_error) {
2955 open_flag &= ~O_CREAT;
2956 if (open_flag & O_EXCL)
2957 goto no_open;
2958 }
2959 }
2960 } else if ((open_flag & (O_TRUNC|O_WRONLY|O_RDWR)) &&
2961 unlikely(!got_write)) {
2962 /*
2963 * No O_CREATE -> atomicity not a requirement -> fall
2964 * back to lookup + open
2965 */
2966 goto no_open;
2967 }
2968
2992 if (dir_inode->i_op->atomic_open) { 2969 if (dir_inode->i_op->atomic_open) {
2993 return atomic_open(nd, dentry, path, file, op, got_write, 2970 error = atomic_open(nd, dentry, path, file, op, open_flag,
2994 need_lookup, opened); 2971 mode, opened);
2972 if (unlikely(error == -ENOENT) && create_error)
2973 error = create_error;
2974 return error;
2995 } 2975 }
2996 2976
2977no_open:
2997 if (need_lookup) { 2978 if (need_lookup) {
2998 BUG_ON(dentry->d_inode);
2999
3000 dentry = lookup_real(dir_inode, dentry, nd->flags); 2979 dentry = lookup_real(dir_inode, dentry, nd->flags);
3001 if (IS_ERR(dentry)) 2980 if (IS_ERR(dentry))
3002 return PTR_ERR(dentry); 2981 return PTR_ERR(dentry);
3003 } 2982 }
3004 2983
3005 /* Negative dentry, just create the file */ 2984 /* Negative dentry, just create the file */
3006 if (!dentry->d_inode && (op->open_flag & O_CREAT)) { 2985 if (!dentry->d_inode && (open_flag & O_CREAT)) {
3007 umode_t mode = op->mode;
3008 if (!IS_POSIXACL(dir->d_inode))
3009 mode &= ~current_umask();
3010 /*
3011 * This write is needed to ensure that a
3012 * rw->ro transition does not occur between
3013 * the time when the file is created and when
3014 * a permanent write count is taken through
3015 * the 'struct file' in finish_open().
3016 */
3017 if (!got_write) {
3018 error = -EROFS;
3019 goto out_dput;
3020 }
3021 *opened |= FILE_CREATED; 2986 *opened |= FILE_CREATED;
3022 audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); 2987 audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
3023 error = may_o_create(&nd->path, dentry, mode);
3024 if (error)
3025 goto out_dput;
3026 if (!dir_inode->i_op->create) { 2988 if (!dir_inode->i_op->create) {
3027 error = -EACCES; 2989 error = -EACCES;
3028 goto out_dput; 2990 goto out_dput;
3029 } 2991 }
3030 error = dir_inode->i_op->create(dir_inode, dentry, mode, 2992 error = dir_inode->i_op->create(dir_inode, dentry, mode,
3031 op->open_flag & O_EXCL); 2993 open_flag & O_EXCL);
3032 if (error) 2994 if (error)
3033 goto out_dput; 2995 goto out_dput;
3034 fsnotify_create(dir_inode, dentry); 2996 fsnotify_create(dir_inode, dentry);
3035 } 2997 }
2998 if (unlikely(create_error) && !dentry->d_inode) {
2999 error = create_error;
3000 goto out_dput;
3001 }
3036out_no_open: 3002out_no_open:
3037 path->dentry = dentry; 3003 path->dentry = dentry;
3038 path->mnt = nd->path.mnt; 3004 path->mnt = nd->path.mnt;