diff options
Diffstat (limited to 'fs/namei.c')
-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); |