diff options
| -rw-r--r-- | fs/namei.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c index 0b4d19d47e67..b0c74fe91fb0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1647,15 +1647,12 @@ exit: | |||
| 1647 | 1647 | ||
| 1648 | static struct file *do_last(struct nameidata *nd, struct path *path, | 1648 | static struct file *do_last(struct nameidata *nd, struct path *path, |
| 1649 | int open_flag, int acc_mode, | 1649 | int open_flag, int acc_mode, |
| 1650 | int mode, const char *pathname, | 1650 | int mode, const char *pathname) |
| 1651 | int *is_link) | ||
| 1652 | { | 1651 | { |
| 1653 | struct dentry *dir = nd->path.dentry; | 1652 | struct dentry *dir = nd->path.dentry; |
| 1654 | struct file *filp; | 1653 | struct file *filp; |
| 1655 | int error; | 1654 | int error; |
| 1656 | 1655 | ||
| 1657 | *is_link = 0; | ||
| 1658 | |||
| 1659 | if (nd->last_type == LAST_BIND) | 1656 | if (nd->last_type == LAST_BIND) |
| 1660 | goto ok; | 1657 | goto ok; |
| 1661 | 1658 | ||
| @@ -1727,10 +1724,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 1727 | error = -ENOENT; | 1724 | error = -ENOENT; |
| 1728 | if (!path->dentry->d_inode) | 1725 | if (!path->dentry->d_inode) |
| 1729 | goto exit_dput; | 1726 | goto exit_dput; |
| 1730 | if (path->dentry->d_inode->i_op->follow_link) { | 1727 | |
| 1731 | *is_link = 1; | 1728 | if (path->dentry->d_inode->i_op->follow_link) |
| 1732 | return NULL; | 1729 | return NULL; |
| 1733 | } | ||
| 1734 | 1730 | ||
| 1735 | path_to_nameidata(path, nd); | 1731 | path_to_nameidata(path, nd); |
| 1736 | error = -EISDIR; | 1732 | error = -EISDIR; |
| @@ -1766,7 +1762,6 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
| 1766 | int count = 0; | 1762 | int count = 0; |
| 1767 | int flag = open_to_namei_flags(open_flag); | 1763 | int flag = open_to_namei_flags(open_flag); |
| 1768 | int force_reval = 0; | 1764 | int force_reval = 0; |
| 1769 | int is_link; | ||
| 1770 | 1765 | ||
| 1771 | /* | 1766 | /* |
| 1772 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only | 1767 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only |
| @@ -1849,9 +1844,8 @@ reval: | |||
| 1849 | nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN; | 1844 | nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN; |
| 1850 | if (open_flag & O_EXCL) | 1845 | if (open_flag & O_EXCL) |
| 1851 | nd.flags |= LOOKUP_EXCL; | 1846 | nd.flags |= LOOKUP_EXCL; |
| 1852 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, | 1847 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); |
| 1853 | pathname, &is_link); | 1848 | if (!filp) |
| 1854 | if (is_link) | ||
| 1855 | goto do_link; | 1849 | goto do_link; |
| 1856 | if (nd.root.mnt) | 1850 | if (nd.root.mnt) |
| 1857 | path_put(&nd.root); | 1851 | path_put(&nd.root); |
| @@ -1902,11 +1896,10 @@ do_link: | |||
| 1902 | return ERR_PTR(error); | 1896 | return ERR_PTR(error); |
| 1903 | } | 1897 | } |
| 1904 | nd.flags &= ~LOOKUP_PARENT; | 1898 | nd.flags &= ~LOOKUP_PARENT; |
| 1905 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, | 1899 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); |
| 1906 | pathname, &is_link); | ||
| 1907 | if (nd.last_type == LAST_NORM) | 1900 | if (nd.last_type == LAST_NORM) |
| 1908 | __putname(nd.last.name); | 1901 | __putname(nd.last.name); |
| 1909 | if (is_link) | 1902 | if (!filp) |
| 1910 | goto do_link; | 1903 | goto do_link; |
| 1911 | if (nd.root.mnt) | 1904 | if (nd.root.mnt) |
| 1912 | path_put(&nd.root); | 1905 | path_put(&nd.root); |
