Commit a8104a9fcdeb82e22d7acd55fca20746581067d3
1 parent
8e4bfca1d1
Exists in
master
and in
20 other branches
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
fs/namei.c
... | ... | @@ -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: |
net/unix/af_unix.c
... | ... | @@ -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); |