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; |
