aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-22 19:20:34 -0500
committerH. Peter Anvin <hpa@zytor.com>2010-02-22 19:20:34 -0500
commitd02e30c31c57683a66ed68a1bcff900ca78f6d56 (patch)
treec3ce99a00061bcc1199b50fa838147d876c56717 /fs/namei.c
parent0fdc7a8022c3eaff6b5ee27ffb9e913e5e58d8e9 (diff)
parentaef55d4922e62a0d887e60d87319f3718aec6ced (diff)
Merge branch 'x86/irq' into x86/apic
Merge reason: Conflicts in arch/x86/kernel/apic/io_apic.c Resolved Conflicts: arch/x86/kernel/apic/io_apic.c Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 68921d9b5302..d62fdc875f22 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)
@@ -1730,8 +1736,7 @@ do_last:
1730 if (nd.root.mnt) 1736 if (nd.root.mnt)
1731 path_put(&nd.root); 1737 path_put(&nd.root);
1732 if (!IS_ERR(filp)) { 1738 if (!IS_ERR(filp)) {
1733 error = ima_path_check(&filp->f_path, filp->f_mode & 1739 error = ima_file_check(filp, acc_mode);
1734 (MAY_READ | MAY_WRITE | MAY_EXEC));
1735 if (error) { 1740 if (error) {
1736 fput(filp); 1741 fput(filp);
1737 filp = ERR_PTR(error); 1742 filp = ERR_PTR(error);
@@ -1791,8 +1796,7 @@ ok:
1791 } 1796 }
1792 filp = nameidata_to_filp(&nd); 1797 filp = nameidata_to_filp(&nd);
1793 if (!IS_ERR(filp)) { 1798 if (!IS_ERR(filp)) {
1794 error = ima_path_check(&filp->f_path, filp->f_mode & 1799 error = ima_file_check(filp, acc_mode);
1795 (MAY_READ | MAY_WRITE | MAY_EXEC));
1796 if (error) { 1800 if (error) {
1797 fput(filp); 1801 fput(filp);
1798 filp = ERR_PTR(error); 1802 filp = ERR_PTR(error);
@@ -1852,17 +1856,7 @@ do_link:
1852 error = security_inode_follow_link(path.dentry, &nd); 1856 error = security_inode_follow_link(path.dentry, &nd);
1853 if (error) 1857 if (error)
1854 goto exit_dput; 1858 goto exit_dput;
1855 save = nd.path;
1856 path_get(&save);
1857 error = __do_follow_link(&path, &nd); 1859 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); 1860 path_put(&path);
1867 if (error) { 1861 if (error) {
1868 /* Does someone understand code flow here? Or it is only 1862 /* Does someone understand code flow here? Or it is only
@@ -1872,6 +1866,10 @@ do_link:
1872 release_open_intent(&nd); 1866 release_open_intent(&nd);
1873 if (nd.root.mnt) 1867 if (nd.root.mnt)
1874 path_put(&nd.root); 1868 path_put(&nd.root);
1869 if (error == -ESTALE && !force_reval) {
1870 force_reval = 1;
1871 goto reval;
1872 }
1875 return ERR_PTR(error); 1873 return ERR_PTR(error);
1876 } 1874 }
1877 nd.flags &= ~LOOKUP_PARENT; 1875 nd.flags &= ~LOOKUP_PARENT;