aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-12-24 01:58:28 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-03-05 09:01:13 -0500
commitfb1cc555d533869910e20de4b8d5147570afdfad (patch)
tree99ee86c8370e28df0991a4ecd03677cb65704f01 /fs/namei.c
parent648fa8611de3d4d43bbd64af3226679d2d0eb609 (diff)
gut do_filp_open() a bit more (do_last separation)
Brute-force separation of stuff reachable from do_last: with the exception of do_link:; just take all that crap to a helper function as-is and have it tell the caller if it has to go to do_link. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c171
1 files changed, 103 insertions, 68 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 60b74b3946a1..3c39fa1608c5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1645,6 +1645,104 @@ exit:
1645 return ERR_PTR(error); 1645 return ERR_PTR(error);
1646} 1646}
1647 1647
1648static struct file *do_last(struct nameidata *nd, struct path *path,
1649 int open_flag, int flag, int acc_mode,
1650 int mode, const char *pathname,
1651 struct dentry *dir, int *is_link)
1652{
1653 struct file *filp;
1654 int error;
1655
1656 *is_link = 0;
1657
1658 error = PTR_ERR(path->dentry);
1659 if (IS_ERR(path->dentry)) {
1660 mutex_unlock(&dir->d_inode->i_mutex);
1661 goto exit;
1662 }
1663
1664 if (IS_ERR(nd->intent.open.file)) {
1665 error = PTR_ERR(nd->intent.open.file);
1666 goto exit_mutex_unlock;
1667 }
1668
1669 /* Negative dentry, just create the file */
1670 if (!path->dentry->d_inode) {
1671 /*
1672 * This write is needed to ensure that a
1673 * ro->rw transition does not occur between
1674 * the time when the file is created and when
1675 * a permanent write count is taken through
1676 * the 'struct file' in nameidata_to_filp().
1677 */
1678 error = mnt_want_write(nd->path.mnt);
1679 if (error)
1680 goto exit_mutex_unlock;
1681 error = __open_namei_create(nd, path, open_flag, mode);
1682 if (error) {
1683 mnt_drop_write(nd->path.mnt);
1684 goto exit;
1685 }
1686 filp = nameidata_to_filp(nd);
1687 mnt_drop_write(nd->path.mnt);
1688 if (nd->root.mnt)
1689 path_put(&nd->root);
1690 if (!IS_ERR(filp)) {
1691 error = ima_file_check(filp, acc_mode);
1692 if (error) {
1693 fput(filp);
1694 filp = ERR_PTR(error);
1695 }
1696 }
1697 return filp;
1698 }
1699
1700 /*
1701 * It already exists.
1702 */
1703 mutex_unlock(&dir->d_inode->i_mutex);
1704 audit_inode(pathname, path->dentry);
1705
1706 error = -EEXIST;
1707 if (flag & O_EXCL)
1708 goto exit_dput;
1709
1710 if (__follow_mount(path)) {
1711 error = -ELOOP;
1712 if (flag & O_NOFOLLOW)
1713 goto exit_dput;
1714 }
1715
1716 error = -ENOENT;
1717 if (!path->dentry->d_inode)
1718 goto exit_dput;
1719 if (path->dentry->d_inode->i_op->follow_link) {
1720 *is_link = 1;
1721 return NULL;
1722 }
1723
1724 path_to_nameidata(path, nd);
1725 error = -EISDIR;
1726 if (S_ISDIR(path->dentry->d_inode->i_mode))
1727 goto exit;
1728 filp = finish_open(nd, open_flag, flag, acc_mode);
1729 if (nd->root.mnt)
1730 path_put(&nd->root);
1731 return filp;
1732
1733exit_mutex_unlock:
1734 mutex_unlock(&dir->d_inode->i_mutex);
1735exit_dput:
1736 path_put_conditional(path, nd);
1737exit:
1738 if (!IS_ERR(nd->intent.open.file))
1739 release_open_intent(nd);
1740 if (nd->root.mnt)
1741 path_put(&nd->root);
1742 path_put(&nd->path);
1743 return ERR_PTR(error);
1744}
1745
1648/* 1746/*
1649 * Note that the low bits of the passed in "open_flag" 1747 * Note that the low bits of the passed in "open_flag"
1650 * are not the same as in the local variable "flag". See 1748 * are not the same as in the local variable "flag". See
@@ -1661,6 +1759,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1661 int count = 0; 1759 int count = 0;
1662 int flag = open_to_namei_flags(open_flag); 1760 int flag = open_to_namei_flags(open_flag);
1663 int force_reval = 0; 1761 int force_reval = 0;
1762 int is_link;
1664 1763
1665 /* 1764 /*
1666 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only 1765 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
@@ -1754,82 +1853,18 @@ reval:
1754 path.mnt = nd.path.mnt; 1853 path.mnt = nd.path.mnt;
1755 1854
1756do_last: 1855do_last:
1757 error = PTR_ERR(path.dentry); 1856 filp = do_last(&nd, &path, open_flag, flag, acc_mode, mode,
1758 if (IS_ERR(path.dentry)) { 1857 pathname, dir, &is_link);
1759 mutex_unlock(&dir->d_inode->i_mutex); 1858 if (is_link)
1760 goto exit;
1761 }
1762
1763 if (IS_ERR(nd.intent.open.file)) {
1764 error = PTR_ERR(nd.intent.open.file);
1765 goto exit_mutex_unlock;
1766 }
1767
1768 /* Negative dentry, just create the file */
1769 if (!path.dentry->d_inode) {
1770 /*
1771 * This write is needed to ensure that a
1772 * ro->rw transition does not occur between
1773 * the time when the file is created and when
1774 * a permanent write count is taken through
1775 * the 'struct file' in nameidata_to_filp().
1776 */
1777 error = mnt_want_write(nd.path.mnt);
1778 if (error)
1779 goto exit_mutex_unlock;
1780 error = __open_namei_create(&nd, &path, open_flag, mode);
1781 if (error) {
1782 mnt_drop_write(nd.path.mnt);
1783 goto exit;
1784 }
1785 filp = nameidata_to_filp(&nd);
1786 mnt_drop_write(nd.path.mnt);
1787 if (nd.root.mnt)
1788 path_put(&nd.root);
1789 if (!IS_ERR(filp)) {
1790 error = ima_file_check(filp, acc_mode);
1791 if (error) {
1792 fput(filp);
1793 filp = ERR_PTR(error);
1794 }
1795 }
1796 return filp;
1797 }
1798
1799 /*
1800 * It already exists.
1801 */
1802 mutex_unlock(&dir->d_inode->i_mutex);
1803 audit_inode(pathname, path.dentry);
1804
1805 error = -EEXIST;
1806 if (flag & O_EXCL)
1807 goto exit_dput;
1808
1809 if (__follow_mount(&path)) {
1810 error = -ELOOP;
1811 if (flag & O_NOFOLLOW)
1812 goto exit_dput;
1813 }
1814
1815 error = -ENOENT;
1816 if (!path.dentry->d_inode)
1817 goto exit_dput;
1818 if (path.dentry->d_inode->i_op->follow_link)
1819 goto do_link; 1859 goto do_link;
1860 return filp;
1820 1861
1821 path_to_nameidata(&path, &nd);
1822 error = -EISDIR;
1823 if (S_ISDIR(path.dentry->d_inode->i_mode))
1824 goto exit;
1825ok: 1862ok:
1826 filp = finish_open(&nd, open_flag, flag, acc_mode); 1863 filp = finish_open(&nd, open_flag, flag, acc_mode);
1827 if (nd.root.mnt) 1864 if (nd.root.mnt)
1828 path_put(&nd.root); 1865 path_put(&nd.root);
1829 return filp; 1866 return filp;
1830 1867
1831exit_mutex_unlock:
1832 mutex_unlock(&dir->d_inode->i_mutex);
1833exit_dput: 1868exit_dput:
1834 path_put_conditional(&path, &nd); 1869 path_put_conditional(&path, &nd);
1835exit: 1870exit: