aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c118
1 files changed, 80 insertions, 38 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 5f4cdf3ad913..43a97ee1d4c8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1275,9 +1275,7 @@ static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir,
1275 *need_lookup = false; 1275 *need_lookup = false;
1276 dentry = d_lookup(dir, name); 1276 dentry = d_lookup(dir, name);
1277 if (dentry) { 1277 if (dentry) {
1278 if (d_need_lookup(dentry)) { 1278 if (dentry->d_flags & DCACHE_OP_REVALIDATE) {
1279 *need_lookup = true;
1280 } else if (dentry->d_flags & DCACHE_OP_REVALIDATE) {
1281 error = d_revalidate(dentry, flags); 1279 error = d_revalidate(dentry, flags);
1282 if (unlikely(error <= 0)) { 1280 if (unlikely(error <= 0)) {
1283 if (error < 0) { 1281 if (error < 0) {
@@ -1383,8 +1381,6 @@ static int lookup_fast(struct nameidata *nd, struct qstr *name,
1383 return -ECHILD; 1381 return -ECHILD;
1384 nd->seq = seq; 1382 nd->seq = seq;
1385 1383
1386 if (unlikely(d_need_lookup(dentry)))
1387 goto unlazy;
1388 if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { 1384 if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) {
1389 status = d_revalidate(dentry, nd->flags); 1385 status = d_revalidate(dentry, nd->flags);
1390 if (unlikely(status <= 0)) { 1386 if (unlikely(status <= 0)) {
@@ -1410,11 +1406,6 @@ unlazy:
1410 if (unlikely(!dentry)) 1406 if (unlikely(!dentry))
1411 goto need_lookup; 1407 goto need_lookup;
1412 1408
1413 if (unlikely(d_need_lookup(dentry))) {
1414 dput(dentry);
1415 goto need_lookup;
1416 }
1417
1418 if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) 1409 if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval)
1419 status = d_revalidate(dentry, nd->flags); 1410 status = d_revalidate(dentry, nd->flags);
1420 if (unlikely(status <= 0)) { 1411 if (unlikely(status <= 0)) {
@@ -1859,7 +1850,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1859 if (flags & LOOKUP_ROOT) { 1850 if (flags & LOOKUP_ROOT) {
1860 struct inode *inode = nd->root.dentry->d_inode; 1851 struct inode *inode = nd->root.dentry->d_inode;
1861 if (*name) { 1852 if (*name) {
1862 if (!inode->i_op->lookup) 1853 if (!can_lookup(inode))
1863 return -ENOTDIR; 1854 return -ENOTDIR;
1864 retval = inode_permission(inode, MAY_EXEC); 1855 retval = inode_permission(inode, MAY_EXEC);
1865 if (retval) 1856 if (retval)
@@ -1903,6 +1894,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1903 get_fs_pwd(current->fs, &nd->path); 1894 get_fs_pwd(current->fs, &nd->path);
1904 } 1895 }
1905 } else { 1896 } else {
1897 /* Caller must check execute permissions on the starting path component */
1906 struct fd f = fdget_raw(dfd); 1898 struct fd f = fdget_raw(dfd);
1907 struct dentry *dentry; 1899 struct dentry *dentry;
1908 1900
@@ -1912,16 +1904,10 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1912 dentry = f.file->f_path.dentry; 1904 dentry = f.file->f_path.dentry;
1913 1905
1914 if (*name) { 1906 if (*name) {
1915 if (!S_ISDIR(dentry->d_inode->i_mode)) { 1907 if (!can_lookup(dentry->d_inode)) {
1916 fdput(f); 1908 fdput(f);
1917 return -ENOTDIR; 1909 return -ENOTDIR;
1918 } 1910 }
1919
1920 retval = inode_permission(dentry->d_inode, MAY_EXEC);
1921 if (retval) {
1922 fdput(f);
1923 return retval;
1924 }
1925 } 1911 }
1926 1912
1927 nd->path = f.file->f_path; 1913 nd->path = f.file->f_path;
@@ -2189,15 +2175,19 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
2189 * path-walking is complete. 2175 * path-walking is complete.
2190 */ 2176 */
2191static struct filename * 2177static struct filename *
2192user_path_parent(int dfd, const char __user *path, struct nameidata *nd) 2178user_path_parent(int dfd, const char __user *path, struct nameidata *nd,
2179 unsigned int flags)
2193{ 2180{
2194 struct filename *s = getname(path); 2181 struct filename *s = getname(path);
2195 int error; 2182 int error;
2196 2183
2184 /* only LOOKUP_REVAL is allowed in extra flags */
2185 flags &= LOOKUP_REVAL;
2186
2197 if (IS_ERR(s)) 2187 if (IS_ERR(s))
2198 return s; 2188 return s;
2199 2189
2200 error = filename_lookup(dfd, s, LOOKUP_PARENT, nd); 2190 error = filename_lookup(dfd, s, flags | LOOKUP_PARENT, nd);
2201 if (error) { 2191 if (error) {
2202 putname(s); 2192 putname(s);
2203 return ERR_PTR(error); 2193 return ERR_PTR(error);
@@ -3044,12 +3034,22 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
3044 return file; 3034 return file;
3045} 3035}
3046 3036
3047struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir) 3037struct dentry *kern_path_create(int dfd, const char *pathname,
3038 struct path *path, unsigned int lookup_flags)
3048{ 3039{
3049 struct dentry *dentry = ERR_PTR(-EEXIST); 3040 struct dentry *dentry = ERR_PTR(-EEXIST);
3050 struct nameidata nd; 3041 struct nameidata nd;
3051 int err2; 3042 int err2;
3052 int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd); 3043 int error;
3044 bool is_dir = (lookup_flags & LOOKUP_DIRECTORY);
3045
3046 /*
3047 * Note that only LOOKUP_REVAL and LOOKUP_DIRECTORY matter here. Any
3048 * other flags passed in are ignored!
3049 */
3050 lookup_flags &= LOOKUP_REVAL;
3051
3052 error = do_path_lookup(dfd, pathname, LOOKUP_PARENT|lookup_flags, &nd);
3053 if (error) 3053 if (error)
3054 return ERR_PTR(error); 3054 return ERR_PTR(error);
3055 3055
@@ -3113,13 +3113,14 @@ void done_path_create(struct path *path, struct dentry *dentry)
3113} 3113}
3114EXPORT_SYMBOL(done_path_create); 3114EXPORT_SYMBOL(done_path_create);
3115 3115
3116struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) 3116struct dentry *user_path_create(int dfd, const char __user *pathname,
3117 struct path *path, unsigned int lookup_flags)
3117{ 3118{
3118 struct filename *tmp = getname(pathname); 3119 struct filename *tmp = getname(pathname);
3119 struct dentry *res; 3120 struct dentry *res;
3120 if (IS_ERR(tmp)) 3121 if (IS_ERR(tmp))
3121 return ERR_CAST(tmp); 3122 return ERR_CAST(tmp);
3122 res = kern_path_create(dfd, tmp->name, path, is_dir); 3123 res = kern_path_create(dfd, tmp->name, path, lookup_flags);
3123 putname(tmp); 3124 putname(tmp);
3124 return res; 3125 return res;
3125} 3126}
@@ -3175,12 +3176,13 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
3175 struct dentry *dentry; 3176 struct dentry *dentry;
3176 struct path path; 3177 struct path path;
3177 int error; 3178 int error;
3179 unsigned int lookup_flags = 0;
3178 3180
3179 error = may_mknod(mode); 3181 error = may_mknod(mode);
3180 if (error) 3182 if (error)
3181 return error; 3183 return error;
3182 3184retry:
3183 dentry = user_path_create(dfd, filename, &path, 0); 3185 dentry = user_path_create(dfd, filename, &path, lookup_flags);
3184 if (IS_ERR(dentry)) 3186 if (IS_ERR(dentry))
3185 return PTR_ERR(dentry); 3187 return PTR_ERR(dentry);
3186 3188
@@ -3203,6 +3205,10 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
3203 } 3205 }
3204out: 3206out:
3205 done_path_create(&path, dentry); 3207 done_path_create(&path, dentry);
3208 if (retry_estale(error, lookup_flags)) {
3209 lookup_flags |= LOOKUP_REVAL;
3210 goto retry;
3211 }
3206 return error; 3212 return error;
3207} 3213}
3208 3214
@@ -3241,8 +3247,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
3241 struct dentry *dentry; 3247 struct dentry *dentry;
3242 struct path path; 3248 struct path path;
3243 int error; 3249 int error;
3250 unsigned int lookup_flags = LOOKUP_DIRECTORY;
3244 3251
3245 dentry = user_path_create(dfd, pathname, &path, 1); 3252retry:
3253 dentry = user_path_create(dfd, pathname, &path, lookup_flags);
3246 if (IS_ERR(dentry)) 3254 if (IS_ERR(dentry))
3247 return PTR_ERR(dentry); 3255 return PTR_ERR(dentry);
3248 3256
@@ -3252,6 +3260,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
3252 if (!error) 3260 if (!error)
3253 error = vfs_mkdir(path.dentry->d_inode, dentry, mode); 3261 error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
3254 done_path_create(&path, dentry); 3262 done_path_create(&path, dentry);
3263 if (retry_estale(error, lookup_flags)) {
3264 lookup_flags |= LOOKUP_REVAL;
3265 goto retry;
3266 }
3255 return error; 3267 return error;
3256} 3268}
3257 3269
@@ -3327,8 +3339,9 @@ static long do_rmdir(int dfd, const char __user *pathname)
3327 struct filename *name; 3339 struct filename *name;
3328 struct dentry *dentry; 3340 struct dentry *dentry;
3329 struct nameidata nd; 3341 struct nameidata nd;
3330 3342 unsigned int lookup_flags = 0;
3331 name = user_path_parent(dfd, pathname, &nd); 3343retry:
3344 name = user_path_parent(dfd, pathname, &nd, lookup_flags);
3332 if (IS_ERR(name)) 3345 if (IS_ERR(name))
3333 return PTR_ERR(name); 3346 return PTR_ERR(name);
3334 3347
@@ -3370,6 +3383,10 @@ exit2:
3370exit1: 3383exit1:
3371 path_put(&nd.path); 3384 path_put(&nd.path);
3372 putname(name); 3385 putname(name);
3386 if (retry_estale(error, lookup_flags)) {
3387 lookup_flags |= LOOKUP_REVAL;
3388 goto retry;
3389 }
3373 return error; 3390 return error;
3374} 3391}
3375 3392
@@ -3423,8 +3440,9 @@ static long do_unlinkat(int dfd, const char __user *pathname)
3423 struct dentry *dentry; 3440 struct dentry *dentry;
3424 struct nameidata nd; 3441 struct nameidata nd;
3425 struct inode *inode = NULL; 3442 struct inode *inode = NULL;
3426 3443 unsigned int lookup_flags = 0;
3427 name = user_path_parent(dfd, pathname, &nd); 3444retry:
3445 name = user_path_parent(dfd, pathname, &nd, lookup_flags);
3428 if (IS_ERR(name)) 3446 if (IS_ERR(name))
3429 return PTR_ERR(name); 3447 return PTR_ERR(name);
3430 3448
@@ -3462,6 +3480,11 @@ exit2:
3462exit1: 3480exit1:
3463 path_put(&nd.path); 3481 path_put(&nd.path);
3464 putname(name); 3482 putname(name);
3483 if (retry_estale(error, lookup_flags)) {
3484 lookup_flags |= LOOKUP_REVAL;
3485 inode = NULL;
3486 goto retry;
3487 }
3465 return error; 3488 return error;
3466 3489
3467slashes: 3490slashes:
@@ -3513,12 +3536,13 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
3513 struct filename *from; 3536 struct filename *from;
3514 struct dentry *dentry; 3537 struct dentry *dentry;
3515 struct path path; 3538 struct path path;
3539 unsigned int lookup_flags = 0;
3516 3540
3517 from = getname(oldname); 3541 from = getname(oldname);
3518 if (IS_ERR(from)) 3542 if (IS_ERR(from))
3519 return PTR_ERR(from); 3543 return PTR_ERR(from);
3520 3544retry:
3521 dentry = user_path_create(newdfd, newname, &path, 0); 3545 dentry = user_path_create(newdfd, newname, &path, lookup_flags);
3522 error = PTR_ERR(dentry); 3546 error = PTR_ERR(dentry);
3523 if (IS_ERR(dentry)) 3547 if (IS_ERR(dentry))
3524 goto out_putname; 3548 goto out_putname;
@@ -3527,6 +3551,10 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
3527 if (!error) 3551 if (!error)
3528 error = vfs_symlink(path.dentry->d_inode, dentry, from->name); 3552 error = vfs_symlink(path.dentry->d_inode, dentry, from->name);
3529 done_path_create(&path, dentry); 3553 done_path_create(&path, dentry);
3554 if (retry_estale(error, lookup_flags)) {
3555 lookup_flags |= LOOKUP_REVAL;
3556 goto retry;
3557 }
3530out_putname: 3558out_putname:
3531 putname(from); 3559 putname(from);
3532 return error; 3560 return error;
@@ -3613,12 +3641,13 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
3613 3641
3614 if (flags & AT_SYMLINK_FOLLOW) 3642 if (flags & AT_SYMLINK_FOLLOW)
3615 how |= LOOKUP_FOLLOW; 3643 how |= LOOKUP_FOLLOW;
3616 3644retry:
3617 error = user_path_at(olddfd, oldname, how, &old_path); 3645 error = user_path_at(olddfd, oldname, how, &old_path);
3618 if (error) 3646 if (error)
3619 return error; 3647 return error;
3620 3648
3621 new_dentry = user_path_create(newdfd, newname, &new_path, 0); 3649 new_dentry = user_path_create(newdfd, newname, &new_path,
3650 (how & LOOKUP_REVAL));
3622 error = PTR_ERR(new_dentry); 3651 error = PTR_ERR(new_dentry);
3623 if (IS_ERR(new_dentry)) 3652 if (IS_ERR(new_dentry))
3624 goto out; 3653 goto out;
@@ -3635,6 +3664,10 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
3635 error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry); 3664 error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
3636out_dput: 3665out_dput:
3637 done_path_create(&new_path, new_dentry); 3666 done_path_create(&new_path, new_dentry);
3667 if (retry_estale(error, how)) {
3668 how |= LOOKUP_REVAL;
3669 goto retry;
3670 }
3638out: 3671out:
3639 path_put(&old_path); 3672 path_put(&old_path);
3640 3673
@@ -3807,15 +3840,17 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
3807 struct nameidata oldnd, newnd; 3840 struct nameidata oldnd, newnd;
3808 struct filename *from; 3841 struct filename *from;
3809 struct filename *to; 3842 struct filename *to;
3843 unsigned int lookup_flags = 0;
3844 bool should_retry = false;
3810 int error; 3845 int error;
3811 3846retry:
3812 from = user_path_parent(olddfd, oldname, &oldnd); 3847 from = user_path_parent(olddfd, oldname, &oldnd, lookup_flags);
3813 if (IS_ERR(from)) { 3848 if (IS_ERR(from)) {
3814 error = PTR_ERR(from); 3849 error = PTR_ERR(from);
3815 goto exit; 3850 goto exit;
3816 } 3851 }
3817 3852
3818 to = user_path_parent(newdfd, newname, &newnd); 3853 to = user_path_parent(newdfd, newname, &newnd, lookup_flags);
3819 if (IS_ERR(to)) { 3854 if (IS_ERR(to)) {
3820 error = PTR_ERR(to); 3855 error = PTR_ERR(to);
3821 goto exit1; 3856 goto exit1;
@@ -3887,11 +3922,18 @@ exit3:
3887 unlock_rename(new_dir, old_dir); 3922 unlock_rename(new_dir, old_dir);
3888 mnt_drop_write(oldnd.path.mnt); 3923 mnt_drop_write(oldnd.path.mnt);
3889exit2: 3924exit2:
3925 if (retry_estale(error, lookup_flags))
3926 should_retry = true;
3890 path_put(&newnd.path); 3927 path_put(&newnd.path);
3891 putname(to); 3928 putname(to);
3892exit1: 3929exit1:
3893 path_put(&oldnd.path); 3930 path_put(&oldnd.path);
3894 putname(from); 3931 putname(from);
3932 if (should_retry) {
3933 should_retry = false;
3934 lookup_flags |= LOOKUP_REVAL;
3935 goto retry;
3936 }
3895exit: 3937exit:
3896 return error; 3938 return error;
3897} 3939}