aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 68921d9b5302..94a5e60779f9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -232,6 +232,7 @@ int generic_permission(struct inode *inode, int mask,
232 /* 232 /*
233 * Searching includes executable on directories, else just read. 233 * Searching includes executable on directories, else just read.
234 */ 234 */
235 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
235 if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) 236 if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
236 if (capable(CAP_DAC_READ_SEARCH)) 237 if (capable(CAP_DAC_READ_SEARCH))
237 return 0; 238 return 0;
@@ -560,6 +561,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
560 dget(dentry); 561 dget(dentry);
561 } 562 }
562 mntget(path->mnt); 563 mntget(path->mnt);
564 nd->last_type = LAST_BIND;
563 cookie = dentry->d_inode->i_op->follow_link(dentry, nd); 565 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
564 error = PTR_ERR(cookie); 566 error = PTR_ERR(cookie);
565 if (!IS_ERR(cookie)) { 567 if (!IS_ERR(cookie)) {
@@ -1602,11 +1604,12 @@ struct file *do_filp_open(int dfd, const char *pathname,
1602 struct file *filp; 1604 struct file *filp;
1603 struct nameidata nd; 1605 struct nameidata nd;
1604 int error; 1606 int error;
1605 struct path path, save; 1607 struct path path;
1606 struct dentry *dir; 1608 struct dentry *dir;
1607 int count = 0; 1609 int count = 0;
1608 int will_truncate; 1610 int will_truncate;
1609 int flag = open_to_namei_flags(open_flag); 1611 int flag = open_to_namei_flags(open_flag);
1612 int force_reval = 0;
1610 1613
1611 /* 1614 /*
1612 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only 1615 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
@@ -1618,7 +1621,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1618 open_flag |= O_DSYNC; 1621 open_flag |= O_DSYNC;
1619 1622
1620 if (!acc_mode) 1623 if (!acc_mode)
1621 acc_mode = MAY_OPEN | ACC_MODE(flag); 1624 acc_mode = MAY_OPEN | ACC_MODE(open_flag);
1622 1625
1623 /* O_TRUNC implies we need access checks for write permissions */ 1626 /* O_TRUNC implies we need access checks for write permissions */
1624 if (flag & O_TRUNC) 1627 if (flag & O_TRUNC)
@@ -1658,9 +1661,12 @@ struct file *do_filp_open(int dfd, const char *pathname,
1658 /* 1661 /*
1659 * Create - we need to know the parent. 1662 * Create - we need to know the parent.
1660 */ 1663 */
1664reval:
1661 error = path_init(dfd, pathname, LOOKUP_PARENT, &nd); 1665 error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
1662 if (error) 1666 if (error)
1663 return ERR_PTR(error); 1667 return ERR_PTR(error);
1668 if (force_reval)
1669 nd.flags |= LOOKUP_REVAL;
1664 error = path_walk(pathname, &nd); 1670 error = path_walk(pathname, &nd);
1665 if (error) { 1671 if (error) {
1666 if (nd.root.mnt) 1672 if (nd.root.mnt)
@@ -1852,17 +1858,7 @@ do_link:
1852 error = security_inode_follow_link(path.dentry, &nd); 1858 error = security_inode_follow_link(path.dentry, &nd);
1853 if (error) 1859 if (error)
1854 goto exit_dput; 1860 goto exit_dput;
1855 save = nd.path;
1856 path_get(&save);
1857 error = __do_follow_link(&path, &nd); 1861 error = __do_follow_link(&path, &nd);
1858 if (error == -ESTALE) {
1859 /* nd.path had been dropped */
1860 nd.path = save;
1861 path_get(&nd.path);
1862 nd.flags |= LOOKUP_REVAL;
1863 error = __do_follow_link(&path, &nd);
1864 }
1865 path_put(&save);
1866 path_put(&path); 1862 path_put(&path);
1867 if (error) { 1863 if (error) {
1868 /* Does someone understand code flow here? Or it is only 1864 /* Does someone understand code flow here? Or it is only
@@ -1872,6 +1868,10 @@ do_link:
1872 release_open_intent(&nd); 1868 release_open_intent(&nd);
1873 if (nd.root.mnt) 1869 if (nd.root.mnt)
1874 path_put(&nd.root); 1870 path_put(&nd.root);
1871 if (error == -ESTALE && !force_reval) {
1872 force_reval = 1;
1873 goto reval;
1874 }
1875 return ERR_PTR(error); 1875 return ERR_PTR(error);
1876 } 1876 }
1877 nd.flags &= ~LOOKUP_PARENT; 1877 nd.flags &= ~LOOKUP_PARENT;