diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/fs/namei.c b/fs/namei.c index 6ec1f0fefc5b..145e852c4bd0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -525,6 +525,22 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) | |||
525 | return error; | 525 | return error; |
526 | } | 526 | } |
527 | 527 | ||
528 | static inline void dput_path(struct path *path, struct nameidata *nd) | ||
529 | { | ||
530 | dput(path->dentry); | ||
531 | if (path->mnt != nd->mnt) | ||
532 | mntput(path->mnt); | ||
533 | } | ||
534 | |||
535 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | ||
536 | { | ||
537 | dput(nd->dentry); | ||
538 | if (nd->mnt != path->mnt) | ||
539 | mntput(nd->mnt); | ||
540 | nd->mnt = path->mnt; | ||
541 | nd->dentry = path->dentry; | ||
542 | } | ||
543 | |||
528 | /* | 544 | /* |
529 | * This limits recursive symlink follows to 8, while | 545 | * This limits recursive symlink follows to 8, while |
530 | * limiting consecutive symlinks to 40. | 546 | * limiting consecutive symlinks to 40. |
@@ -552,9 +568,7 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) | |||
552 | nd->depth--; | 568 | nd->depth--; |
553 | return err; | 569 | return err; |
554 | loop: | 570 | loop: |
555 | dput(path->dentry); | 571 | dput_path(path, nd); |
556 | if (path->mnt != nd->mnt) | ||
557 | mntput(path->mnt); | ||
558 | path_release(nd); | 572 | path_release(nd); |
559 | return err; | 573 | return err; |
560 | } | 574 | } |
@@ -813,13 +827,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
813 | err = -ENOTDIR; | 827 | err = -ENOTDIR; |
814 | if (!inode->i_op) | 828 | if (!inode->i_op) |
815 | break; | 829 | break; |
816 | } else { | 830 | } else |
817 | dput(nd->dentry); | 831 | path_to_nameidata(&next, nd); |
818 | if (nd->mnt != next.mnt) | ||
819 | mntput(nd->mnt); | ||
820 | nd->mnt = next.mnt; | ||
821 | nd->dentry = next.dentry; | ||
822 | } | ||
823 | err = -ENOTDIR; | 832 | err = -ENOTDIR; |
824 | if (!inode->i_op->lookup) | 833 | if (!inode->i_op->lookup) |
825 | break; | 834 | break; |
@@ -859,13 +868,8 @@ last_component: | |||
859 | if (err) | 868 | if (err) |
860 | goto return_err; | 869 | goto return_err; |
861 | inode = nd->dentry->d_inode; | 870 | inode = nd->dentry->d_inode; |
862 | } else { | 871 | } else |
863 | dput(nd->dentry); | 872 | path_to_nameidata(&next, nd); |
864 | if (nd->mnt != next.mnt) | ||
865 | mntput(nd->mnt); | ||
866 | nd->mnt = next.mnt; | ||
867 | nd->dentry = next.dentry; | ||
868 | } | ||
869 | err = -ENOENT; | 873 | err = -ENOENT; |
870 | if (!inode) | 874 | if (!inode) |
871 | break; | 875 | break; |
@@ -901,9 +905,7 @@ return_reval: | |||
901 | return_base: | 905 | return_base: |
902 | return 0; | 906 | return 0; |
903 | out_dput: | 907 | out_dput: |
904 | dput(next.dentry); | 908 | dput_path(&next, nd); |
905 | if (nd->mnt != next.mnt) | ||
906 | mntput(next.mnt); | ||
907 | break; | 909 | break; |
908 | } | 910 | } |
909 | path_release(nd); | 911 | path_release(nd); |
@@ -1507,11 +1509,7 @@ do_last: | |||
1507 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1509 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
1508 | goto do_link; | 1510 | goto do_link; |
1509 | 1511 | ||
1510 | dput(nd->dentry); | 1512 | path_to_nameidata(&path, nd); |
1511 | nd->dentry = path.dentry; | ||
1512 | if (nd->mnt != path.mnt) | ||
1513 | mntput(nd->mnt); | ||
1514 | nd->mnt = path.mnt; | ||
1515 | error = -EISDIR; | 1513 | error = -EISDIR; |
1516 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) | 1514 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
1517 | goto exit; | 1515 | goto exit; |
@@ -1522,9 +1520,7 @@ ok: | |||
1522 | return 0; | 1520 | return 0; |
1523 | 1521 | ||
1524 | exit_dput: | 1522 | exit_dput: |
1525 | dput(path.dentry); | 1523 | dput_path(&path, nd); |
1526 | if (nd->mnt != path.mnt) | ||
1527 | mntput(path.mnt); | ||
1528 | exit: | 1524 | exit: |
1529 | path_release(nd); | 1525 | path_release(nd); |
1530 | return error; | 1526 | return error; |