diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/fs/namei.c b/fs/namei.c index c9b05a71c39..b0df7ea733d 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -362,11 +362,18 @@ int deny_write_access(struct file * file) | |||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | void path_release(struct nameidata *nd) | 365 | /** |
366 | * path_put - put a reference to a path | ||
367 | * @path: path to put the reference to | ||
368 | * | ||
369 | * Given a path decrement the reference count to the dentry and the vfsmount. | ||
370 | */ | ||
371 | void path_put(struct path *path) | ||
366 | { | 372 | { |
367 | dput(nd->path.dentry); | 373 | dput(path->dentry); |
368 | mntput(nd->path.mnt); | 374 | mntput(path->mnt); |
369 | } | 375 | } |
376 | EXPORT_SYMBOL(path_put); | ||
370 | 377 | ||
371 | /** | 378 | /** |
372 | * release_open_intent - free up open intent resources | 379 | * release_open_intent - free up open intent resources |
@@ -551,7 +558,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l | |||
551 | goto fail; | 558 | goto fail; |
552 | 559 | ||
553 | if (*link == '/') { | 560 | if (*link == '/') { |
554 | path_release(nd); | 561 | path_put(&nd->path); |
555 | if (!walk_init_root(link, nd)) | 562 | if (!walk_init_root(link, nd)) |
556 | /* weird __emul_prefix() stuff did it */ | 563 | /* weird __emul_prefix() stuff did it */ |
557 | goto out; | 564 | goto out; |
@@ -567,18 +574,18 @@ out: | |||
567 | */ | 574 | */ |
568 | name = __getname(); | 575 | name = __getname(); |
569 | if (unlikely(!name)) { | 576 | if (unlikely(!name)) { |
570 | path_release(nd); | 577 | path_put(&nd->path); |
571 | return -ENOMEM; | 578 | return -ENOMEM; |
572 | } | 579 | } |
573 | strcpy(name, nd->last.name); | 580 | strcpy(name, nd->last.name); |
574 | nd->last.name = name; | 581 | nd->last.name = name; |
575 | return 0; | 582 | return 0; |
576 | fail: | 583 | fail: |
577 | path_release(nd); | 584 | path_put(&nd->path); |
578 | return PTR_ERR(link); | 585 | return PTR_ERR(link); |
579 | } | 586 | } |
580 | 587 | ||
581 | static inline void dput_path(struct path *path, struct nameidata *nd) | 588 | static void path_put_conditional(struct path *path, struct nameidata *nd) |
582 | { | 589 | { |
583 | dput(path->dentry); | 590 | dput(path->dentry); |
584 | if (path->mnt != nd->path.mnt) | 591 | if (path->mnt != nd->path.mnt) |
@@ -651,8 +658,8 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) | |||
651 | nd->depth--; | 658 | nd->depth--; |
652 | return err; | 659 | return err; |
653 | loop: | 660 | loop: |
654 | dput_path(path, nd); | 661 | path_put_conditional(path, nd); |
655 | path_release(nd); | 662 | path_put(&nd->path); |
656 | return err; | 663 | return err; |
657 | } | 664 | } |
658 | 665 | ||
@@ -993,10 +1000,10 @@ return_reval: | |||
993 | return_base: | 1000 | return_base: |
994 | return 0; | 1001 | return 0; |
995 | out_dput: | 1002 | out_dput: |
996 | dput_path(&next, nd); | 1003 | path_put_conditional(&next, nd); |
997 | break; | 1004 | break; |
998 | } | 1005 | } |
999 | path_release(nd); | 1006 | path_put(&nd->path); |
1000 | return_err: | 1007 | return_err: |
1001 | return err; | 1008 | return err; |
1002 | } | 1009 | } |
@@ -1070,7 +1077,7 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1070 | mntput(old_mnt); | 1077 | mntput(old_mnt); |
1071 | return 1; | 1078 | return 1; |
1072 | } | 1079 | } |
1073 | path_release(nd); | 1080 | path_put(&nd->path); |
1074 | } | 1081 | } |
1075 | nd->path.dentry = old_dentry; | 1082 | nd->path.dentry = old_dentry; |
1076 | nd->path.mnt = old_mnt; | 1083 | nd->path.mnt = old_mnt; |
@@ -1230,7 +1237,7 @@ static int __path_lookup_intent_open(int dfd, const char *name, | |||
1230 | if (IS_ERR(nd->intent.open.file)) { | 1237 | if (IS_ERR(nd->intent.open.file)) { |
1231 | if (err == 0) { | 1238 | if (err == 0) { |
1232 | err = PTR_ERR(nd->intent.open.file); | 1239 | err = PTR_ERR(nd->intent.open.file); |
1233 | path_release(nd); | 1240 | path_put(&nd->path); |
1234 | } | 1241 | } |
1235 | } else if (err != 0) | 1242 | } else if (err != 0) |
1236 | release_open_intent(nd); | 1243 | release_open_intent(nd); |
@@ -1806,11 +1813,11 @@ ok: | |||
1806 | return 0; | 1813 | return 0; |
1807 | 1814 | ||
1808 | exit_dput: | 1815 | exit_dput: |
1809 | dput_path(&path, nd); | 1816 | path_put_conditional(&path, nd); |
1810 | exit: | 1817 | exit: |
1811 | if (!IS_ERR(nd->intent.open.file)) | 1818 | if (!IS_ERR(nd->intent.open.file)) |
1812 | release_open_intent(nd); | 1819 | release_open_intent(nd); |
1813 | path_release(nd); | 1820 | path_put(&nd->path); |
1814 | return error; | 1821 | return error; |
1815 | 1822 | ||
1816 | do_link: | 1823 | do_link: |
@@ -1979,7 +1986,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1979 | dput(dentry); | 1986 | dput(dentry); |
1980 | } | 1987 | } |
1981 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 1988 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
1982 | path_release(&nd); | 1989 | path_put(&nd.path); |
1983 | out: | 1990 | out: |
1984 | putname(tmp); | 1991 | putname(tmp); |
1985 | 1992 | ||
@@ -2039,7 +2046,7 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2039 | dput(dentry); | 2046 | dput(dentry); |
2040 | out_unlock: | 2047 | out_unlock: |
2041 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2048 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2042 | path_release(&nd); | 2049 | path_put(&nd.path); |
2043 | out: | 2050 | out: |
2044 | putname(tmp); | 2051 | putname(tmp); |
2045 | out_err: | 2052 | out_err: |
@@ -2147,7 +2154,7 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2147 | exit2: | 2154 | exit2: |
2148 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2155 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2149 | exit1: | 2156 | exit1: |
2150 | path_release(&nd); | 2157 | path_put(&nd.path); |
2151 | exit: | 2158 | exit: |
2152 | putname(name); | 2159 | putname(name); |
2153 | return error; | 2160 | return error; |
@@ -2231,7 +2238,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2231 | if (inode) | 2238 | if (inode) |
2232 | iput(inode); /* truncate the inode here */ | 2239 | iput(inode); /* truncate the inode here */ |
2233 | exit1: | 2240 | exit1: |
2234 | path_release(&nd); | 2241 | path_put(&nd.path); |
2235 | exit: | 2242 | exit: |
2236 | putname(name); | 2243 | putname(name); |
2237 | return error; | 2244 | return error; |
@@ -2308,7 +2315,7 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2308 | dput(dentry); | 2315 | dput(dentry); |
2309 | out_unlock: | 2316 | out_unlock: |
2310 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2317 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2311 | path_release(&nd); | 2318 | path_put(&nd.path); |
2312 | out: | 2319 | out: |
2313 | putname(to); | 2320 | putname(to); |
2314 | out_putname: | 2321 | out_putname: |
@@ -2404,9 +2411,9 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2404 | out_unlock: | 2411 | out_unlock: |
2405 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2412 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2406 | out_release: | 2413 | out_release: |
2407 | path_release(&nd); | 2414 | path_put(&nd.path); |
2408 | out: | 2415 | out: |
2409 | path_release(&old_nd); | 2416 | path_put(&old_nd.path); |
2410 | exit: | 2417 | exit: |
2411 | putname(to); | 2418 | putname(to); |
2412 | 2419 | ||
@@ -2634,9 +2641,9 @@ exit4: | |||
2634 | exit3: | 2641 | exit3: |
2635 | unlock_rename(new_dir, old_dir); | 2642 | unlock_rename(new_dir, old_dir); |
2636 | exit2: | 2643 | exit2: |
2637 | path_release(&newnd); | 2644 | path_put(&newnd.path); |
2638 | exit1: | 2645 | exit1: |
2639 | path_release(&oldnd); | 2646 | path_put(&oldnd.path); |
2640 | exit: | 2647 | exit: |
2641 | return error; | 2648 | return error; |
2642 | } | 2649 | } |
@@ -2810,7 +2817,6 @@ EXPORT_SYMBOL(page_symlink); | |||
2810 | EXPORT_SYMBOL(page_symlink_inode_operations); | 2817 | EXPORT_SYMBOL(page_symlink_inode_operations); |
2811 | EXPORT_SYMBOL(path_lookup); | 2818 | EXPORT_SYMBOL(path_lookup); |
2812 | EXPORT_SYMBOL(vfs_path_lookup); | 2819 | EXPORT_SYMBOL(vfs_path_lookup); |
2813 | EXPORT_SYMBOL(path_release); | ||
2814 | EXPORT_SYMBOL(permission); | 2820 | EXPORT_SYMBOL(permission); |
2815 | EXPORT_SYMBOL(vfs_permission); | 2821 | EXPORT_SYMBOL(vfs_permission); |
2816 | EXPORT_SYMBOL(file_permission); | 2822 | EXPORT_SYMBOL(file_permission); |