diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 78 |
1 files changed, 30 insertions, 48 deletions
diff --git a/fs/namei.c b/fs/namei.c index 91ce1f24bbb6..043d587216b5 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); |
@@ -1314,10 +1316,8 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1314 | return error; | 1316 | return error; |
1315 | DQUOT_INIT(dir); | 1317 | DQUOT_INIT(dir); |
1316 | error = dir->i_op->create(dir, dentry, mode, nd); | 1318 | error = dir->i_op->create(dir, dentry, mode, nd); |
1317 | if (!error) { | 1319 | if (!error) |
1318 | fsnotify_create(dir, dentry->d_name.name); | 1320 | fsnotify_create(dir, dentry->d_name.name); |
1319 | security_inode_post_create(dir, dentry, mode); | ||
1320 | } | ||
1321 | return error; | 1321 | return error; |
1322 | } | 1322 | } |
1323 | 1323 | ||
@@ -1507,11 +1507,7 @@ do_last: | |||
1507 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1507 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
1508 | goto do_link; | 1508 | goto do_link; |
1509 | 1509 | ||
1510 | dput(nd->dentry); | 1510 | 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; | 1511 | error = -EISDIR; |
1516 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) | 1512 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
1517 | goto exit; | 1513 | goto exit; |
@@ -1522,9 +1518,7 @@ ok: | |||
1522 | return 0; | 1518 | return 0; |
1523 | 1519 | ||
1524 | exit_dput: | 1520 | exit_dput: |
1525 | dput(path.dentry); | 1521 | dput_path(&path, nd); |
1526 | if (nd->mnt != path.mnt) | ||
1527 | mntput(path.mnt); | ||
1528 | exit: | 1522 | exit: |
1529 | path_release(nd); | 1523 | path_release(nd); |
1530 | return error; | 1524 | return error; |
@@ -1639,10 +1633,8 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1639 | 1633 | ||
1640 | DQUOT_INIT(dir); | 1634 | DQUOT_INIT(dir); |
1641 | error = dir->i_op->mknod(dir, dentry, mode, dev); | 1635 | error = dir->i_op->mknod(dir, dentry, mode, dev); |
1642 | if (!error) { | 1636 | if (!error) |
1643 | fsnotify_create(dir, dentry->d_name.name); | 1637 | fsnotify_create(dir, dentry->d_name.name); |
1644 | security_inode_post_mknod(dir, dentry, mode, dev); | ||
1645 | } | ||
1646 | return error; | 1638 | return error; |
1647 | } | 1639 | } |
1648 | 1640 | ||
@@ -1712,10 +1704,8 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1712 | 1704 | ||
1713 | DQUOT_INIT(dir); | 1705 | DQUOT_INIT(dir); |
1714 | error = dir->i_op->mkdir(dir, dentry, mode); | 1706 | error = dir->i_op->mkdir(dir, dentry, mode); |
1715 | if (!error) { | 1707 | if (!error) |
1716 | fsnotify_mkdir(dir, dentry->d_name.name); | 1708 | fsnotify_mkdir(dir, dentry->d_name.name); |
1717 | security_inode_post_mkdir(dir,dentry, mode); | ||
1718 | } | ||
1719 | return error; | 1709 | return error; |
1720 | } | 1710 | } |
1721 | 1711 | ||
@@ -1951,10 +1941,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i | |||
1951 | 1941 | ||
1952 | DQUOT_INIT(dir); | 1942 | DQUOT_INIT(dir); |
1953 | error = dir->i_op->symlink(dir, dentry, oldname); | 1943 | error = dir->i_op->symlink(dir, dentry, oldname); |
1954 | if (!error) { | 1944 | if (!error) |
1955 | fsnotify_create(dir, dentry->d_name.name); | 1945 | fsnotify_create(dir, dentry->d_name.name); |
1956 | security_inode_post_symlink(dir, dentry, oldname); | ||
1957 | } | ||
1958 | return error; | 1946 | return error; |
1959 | } | 1947 | } |
1960 | 1948 | ||
@@ -2024,10 +2012,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2024 | DQUOT_INIT(dir); | 2012 | DQUOT_INIT(dir); |
2025 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2013 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2026 | up(&old_dentry->d_inode->i_sem); | 2014 | up(&old_dentry->d_inode->i_sem); |
2027 | if (!error) { | 2015 | if (!error) |
2028 | fsnotify_create(dir, new_dentry->d_name.name); | 2016 | fsnotify_create(dir, new_dentry->d_name.name); |
2029 | security_inode_post_link(old_dentry, dir, new_dentry); | ||
2030 | } | ||
2031 | return error; | 2017 | return error; |
2032 | } | 2018 | } |
2033 | 2019 | ||
@@ -2146,11 +2132,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2146 | d_rehash(new_dentry); | 2132 | d_rehash(new_dentry); |
2147 | dput(new_dentry); | 2133 | dput(new_dentry); |
2148 | } | 2134 | } |
2149 | if (!error) { | 2135 | if (!error) |
2150 | d_move(old_dentry,new_dentry); | 2136 | d_move(old_dentry,new_dentry); |
2151 | security_inode_post_rename(old_dir, old_dentry, | ||
2152 | new_dir, new_dentry); | ||
2153 | } | ||
2154 | return error; | 2137 | return error; |
2155 | } | 2138 | } |
2156 | 2139 | ||
@@ -2176,7 +2159,6 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
2176 | /* The following d_move() should become unconditional */ | 2159 | /* The following d_move() should become unconditional */ |
2177 | if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) | 2160 | if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) |
2178 | d_move(old_dentry, new_dentry); | 2161 | d_move(old_dentry, new_dentry); |
2179 | security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry); | ||
2180 | } | 2162 | } |
2181 | if (target) | 2163 | if (target) |
2182 | up(&target->i_sem); | 2164 | up(&target->i_sem); |