Commit a8104a9fcdeb82e22d7acd55fca20746581067d3

Authored by Al Viro
1 parent 8e4bfca1d1

pull mnt_want_write()/mnt_drop_write() into kern_path_create()/done_path_create() resp.

One side effect - attempt to create a cross-device link on a read-only fs fails
with EROFS instead of EXDEV now.  Makes more sense, POSIX allows, etc.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 3 changed files with 18 additions and 50 deletions Side-by-side Diff

... ... @@ -2865,10 +2865,11 @@
2865 2865 mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
2866 2866 dentry = lookup_hash(&nd);
2867 2867 if (IS_ERR(dentry))
2868   - goto fail;
  2868 + goto unlock;
2869 2869  
  2870 + error = -EEXIST;
2870 2871 if (dentry->d_inode)
2871   - goto eexist;
  2872 + goto fail;
2872 2873 /*
2873 2874 * Special case - lookup gave negative, but... we had foo/bar/
2874 2875 * From the vfs_mknod() POV we just have a negative dentry -
2875 2876  
2876 2877  
2877 2878  
... ... @@ -2876,16 +2877,18 @@
2876 2877 * been asking for (non-existent) directory. -ENOENT for you.
2877 2878 */
2878 2879 if (unlikely(!is_dir && nd.last.name[nd.last.len])) {
2879   - dput(dentry);
2880   - dentry = ERR_PTR(-ENOENT);
  2880 + error = -ENOENT;
2881 2881 goto fail;
2882 2882 }
  2883 + error = mnt_want_write(nd.path.mnt);
  2884 + if (error)
  2885 + goto fail;
2883 2886 *path = nd.path;
2884 2887 return dentry;
2885   -eexist:
2886   - dput(dentry);
2887   - dentry = ERR_PTR(-EEXIST);
2888 2888 fail:
  2889 + dput(dentry);
  2890 + dentry = ERR_PTR(error);
  2891 +unlock:
2889 2892 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2890 2893 out:
2891 2894 path_put(&nd.path);
... ... @@ -2897,6 +2900,7 @@
2897 2900 {
2898 2901 dput(dentry);
2899 2902 mutex_unlock(&path->dentry->d_inode->i_mutex);
  2903 + mnt_drop_write(path->mnt);
2900 2904 path_put(path);
2901 2905 }
2902 2906 EXPORT_SYMBOL(done_path_create);
2903 2907  
... ... @@ -2974,12 +2978,9 @@
2974 2978  
2975 2979 if (!IS_POSIXACL(path.dentry->d_inode))
2976 2980 mode &= ~current_umask();
2977   - error = mnt_want_write(path.mnt);
2978   - if (error)
2979   - goto out_dput;
2980 2981 error = security_path_mknod(&path, dentry, mode, dev);
2981 2982 if (error)
2982   - goto out_drop_write;
  2983 + goto out;
2983 2984 switch (mode & S_IFMT) {
2984 2985 case 0: case S_IFREG:
2985 2986 error = vfs_create(path.dentry->d_inode,dentry,mode,true);
2986 2987  
... ... @@ -2992,11 +2993,8 @@
2992 2993 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
2993 2994 break;
2994 2995 }
2995   -out_drop_write:
2996   - mnt_drop_write(path.mnt);
2997   -out_dput:
  2996 +out:
2998 2997 done_path_create(&path, dentry);
2999   -
3000 2998 return error;
3001 2999 }
3002 3000  
3003 3001  
... ... @@ -3042,16 +3040,9 @@
3042 3040  
3043 3041 if (!IS_POSIXACL(path.dentry->d_inode))
3044 3042 mode &= ~current_umask();
3045   - error = mnt_want_write(path.mnt);
3046   - if (error)
3047   - goto out_dput;
3048 3043 error = security_path_mkdir(&path, dentry, mode);
3049   - if (error)
3050   - goto out_drop_write;
3051   - error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
3052   -out_drop_write:
3053   - mnt_drop_write(path.mnt);
3054   -out_dput:
  3044 + if (!error)
  3045 + error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
3055 3046 done_path_create(&path, dentry);
3056 3047 return error;
3057 3048 }
3058 3049  
... ... @@ -3326,16 +3317,9 @@
3326 3317 if (IS_ERR(dentry))
3327 3318 goto out_putname;
3328 3319  
3329   - error = mnt_want_write(path.mnt);
3330   - if (error)
3331   - goto out_dput;
3332 3320 error = security_path_symlink(&path, dentry, from);
3333   - if (error)
3334   - goto out_drop_write;
3335   - error = vfs_symlink(path.dentry->d_inode, dentry, from);
3336   -out_drop_write:
3337   - mnt_drop_write(path.mnt);
3338   -out_dput:
  3321 + if (!error)
  3322 + error = vfs_symlink(path.dentry->d_inode, dentry, from);
3339 3323 done_path_create(&path, dentry);
3340 3324 out_putname:
3341 3325 putname(from);
3342 3326  
3343 3327  
... ... @@ -3436,15 +3420,10 @@
3436 3420 error = -EXDEV;
3437 3421 if (old_path.mnt != new_path.mnt)
3438 3422 goto out_dput;
3439   - error = mnt_want_write(new_path.mnt);
3440   - if (error)
3441   - goto out_dput;
3442 3423 error = security_path_link(old_path.dentry, &new_path, new_dentry);
3443 3424 if (error)
3444   - goto out_drop_write;
  3425 + goto out_dput;
3445 3426 error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
3446   -out_drop_write:
3447   - mnt_drop_write(new_path.mnt);
3448 3427 out_dput:
3449 3428 done_path_create(&new_path, new_dentry);
3450 3429 out:
fs/ocfs2/refcounttree.c
... ... @@ -4466,16 +4466,9 @@
4466 4466 goto out_dput;
4467 4467 }
4468 4468  
4469   - error = mnt_want_write(new_path.mnt);
4470   - if (error) {
4471   - mlog_errno(error);
4472   - goto out_dput;
4473   - }
4474   -
4475 4469 error = ocfs2_vfs_reflink(old_path.dentry,
4476 4470 new_path.dentry->d_inode,
4477 4471 new_dentry, preserve);
4478   - mnt_drop_write(new_path.mnt);
4479 4472 out_dput:
4480 4473 done_path_create(&new_path, new_dentry);
4481 4474 out:
... ... @@ -876,15 +876,11 @@
876 876 */
877 877 mode = S_IFSOCK |
878 878 (SOCK_INODE(sock)->i_mode & ~current_umask());
879   - err = mnt_want_write(path.mnt);
880   - if (err)
881   - goto out_mknod_dput;
882 879 err = security_path_mknod(&path, dentry, mode, 0);
883 880 if (err)
884 881 goto out_mknod_drop_write;
885 882 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
886 883 out_mknod_drop_write:
887   - mnt_drop_write(path.mnt);
888 884 if (err)
889 885 goto out_mknod_dput;
890 886 mntget(path.mnt);