diff options
| author | Christoph Hellwig <hch@lst.de> | 2008-02-15 17:37:28 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-19 00:25:32 -0400 |
| commit | a70e65df8812c52252fa07a2eb92a46451a4427f (patch) | |
| tree | b8154bebeb898743e89aeeea5971b410c7e49bf7 | |
| parent | d57999e1527f0b0c818846dcba5a23015beb4823 (diff) | |
[PATCH] merge open_namei() and do_filp_open()
open_namei() will, in the future, need to take mount write counts
over its creation and truncation (via may_open()) operations. It
needs to keep these write counts until any potential filp that is
created gets __fput()'d.
This gets complicated in the error handling and becomes very murky
as to how far open_namei() actually got, and whether or not that
mount write count was taken. That makes it a bad interface.
All that the current do_filp_open() really does is allocate the
nameidata on the stack, then call open_namei().
So, this merges those two functions and moves filp_open() over
to namei.c so it can be close to its buddy: do_filp_open(). It
also gets a kerneldoc comment in the process.
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/namei.c | 100 | ||||
| -rw-r--r-- | fs/open.c | 19 | ||||
| -rw-r--r-- | include/linux/fs.h | 3 |
3 files changed, 59 insertions, 63 deletions
diff --git a/fs/namei.c b/fs/namei.c index c70dbf720109..a1f8bbbd58e5 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1725,17 +1725,13 @@ static inline int open_to_namei_flags(int flag) | |||
| 1725 | } | 1725 | } |
| 1726 | 1726 | ||
| 1727 | /* | 1727 | /* |
| 1728 | * open_namei() | ||
| 1729 | * | ||
| 1730 | * namei for open - this is in fact almost the whole open-routine. | ||
| 1731 | * | ||
| 1732 | * Note that the low bits of "flag" aren't the same as in the open | 1728 | * Note that the low bits of "flag" aren't the same as in the open |
| 1733 | * system call. See open_to_namei_flags(). | 1729 | * system call. See open_to_namei_flags(). |
| 1734 | * SMP-safe | ||
| 1735 | */ | 1730 | */ |
| 1736 | int open_namei(int dfd, const char *pathname, int open_flag, | 1731 | struct file *do_filp_open(int dfd, const char *pathname, |
| 1737 | int mode, struct nameidata *nd) | 1732 | int open_flag, int mode) |
| 1738 | { | 1733 | { |
| 1734 | struct nameidata nd; | ||
| 1739 | int acc_mode, error; | 1735 | int acc_mode, error; |
| 1740 | struct path path; | 1736 | struct path path; |
| 1741 | struct dentry *dir; | 1737 | struct dentry *dir; |
| @@ -1758,18 +1754,19 @@ int open_namei(int dfd, const char *pathname, int open_flag, | |||
| 1758 | */ | 1754 | */ |
| 1759 | if (!(flag & O_CREAT)) { | 1755 | if (!(flag & O_CREAT)) { |
| 1760 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), | 1756 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), |
| 1761 | nd, flag); | 1757 | &nd, flag); |
| 1762 | if (error) | 1758 | if (error) |
| 1763 | return error; | 1759 | return ERR_PTR(error); |
| 1764 | goto ok; | 1760 | goto ok; |
| 1765 | } | 1761 | } |
| 1766 | 1762 | ||
| 1767 | /* | 1763 | /* |
| 1768 | * Create - we need to know the parent. | 1764 | * Create - we need to know the parent. |
| 1769 | */ | 1765 | */ |
| 1770 | error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode); | 1766 | error = path_lookup_create(dfd, pathname, LOOKUP_PARENT, |
| 1767 | &nd, flag, mode); | ||
| 1771 | if (error) | 1768 | if (error) |
| 1772 | return error; | 1769 | return ERR_PTR(error); |
| 1773 | 1770 | ||
| 1774 | /* | 1771 | /* |
| 1775 | * We have the parent and last component. First of all, check | 1772 | * We have the parent and last component. First of all, check |
| @@ -1777,14 +1774,14 @@ int open_namei(int dfd, const char *pathname, int open_flag, | |||
| 1777 | * will not do. | 1774 | * will not do. |
| 1778 | */ | 1775 | */ |
| 1779 | error = -EISDIR; | 1776 | error = -EISDIR; |
| 1780 | if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) | 1777 | if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len]) |
| 1781 | goto exit; | 1778 | goto exit; |
| 1782 | 1779 | ||
| 1783 | dir = nd->path.dentry; | 1780 | dir = nd.path.dentry; |
| 1784 | nd->flags &= ~LOOKUP_PARENT; | 1781 | nd.flags &= ~LOOKUP_PARENT; |
| 1785 | mutex_lock(&dir->d_inode->i_mutex); | 1782 | mutex_lock(&dir->d_inode->i_mutex); |
| 1786 | path.dentry = lookup_hash(nd); | 1783 | path.dentry = lookup_hash(&nd); |
| 1787 | path.mnt = nd->path.mnt; | 1784 | path.mnt = nd.path.mnt; |
| 1788 | 1785 | ||
| 1789 | do_last: | 1786 | do_last: |
| 1790 | error = PTR_ERR(path.dentry); | 1787 | error = PTR_ERR(path.dentry); |
| @@ -1793,18 +1790,18 @@ do_last: | |||
| 1793 | goto exit; | 1790 | goto exit; |
| 1794 | } | 1791 | } |
| 1795 | 1792 | ||
| 1796 | if (IS_ERR(nd->intent.open.file)) { | 1793 | if (IS_ERR(nd.intent.open.file)) { |
| 1797 | mutex_unlock(&dir->d_inode->i_mutex); | 1794 | mutex_unlock(&dir->d_inode->i_mutex); |
| 1798 | error = PTR_ERR(nd->intent.open.file); | 1795 | error = PTR_ERR(nd.intent.open.file); |
| 1799 | goto exit_dput; | 1796 | goto exit_dput; |
| 1800 | } | 1797 | } |
| 1801 | 1798 | ||
| 1802 | /* Negative dentry, just create the file */ | 1799 | /* Negative dentry, just create the file */ |
| 1803 | if (!path.dentry->d_inode) { | 1800 | if (!path.dentry->d_inode) { |
| 1804 | error = __open_namei_create(nd, &path, flag, mode); | 1801 | error = __open_namei_create(&nd, &path, flag, mode); |
| 1805 | if (error) | 1802 | if (error) |
| 1806 | goto exit; | 1803 | goto exit; |
| 1807 | return 0; | 1804 | return nameidata_to_filp(&nd, open_flag); |
| 1808 | } | 1805 | } |
| 1809 | 1806 | ||
| 1810 | /* | 1807 | /* |
| @@ -1829,23 +1826,23 @@ do_last: | |||
| 1829 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1826 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
| 1830 | goto do_link; | 1827 | goto do_link; |
| 1831 | 1828 | ||
| 1832 | path_to_nameidata(&path, nd); | 1829 | path_to_nameidata(&path, &nd); |
| 1833 | error = -EISDIR; | 1830 | error = -EISDIR; |
| 1834 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) | 1831 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
| 1835 | goto exit; | 1832 | goto exit; |
| 1836 | ok: | 1833 | ok: |
| 1837 | error = may_open(nd, acc_mode, flag); | 1834 | error = may_open(&nd, acc_mode, flag); |
| 1838 | if (error) | 1835 | if (error) |
| 1839 | goto exit; | 1836 | goto exit; |
| 1840 | return 0; | 1837 | return nameidata_to_filp(&nd, open_flag); |
| 1841 | 1838 | ||
| 1842 | exit_dput: | 1839 | exit_dput: |
| 1843 | path_put_conditional(&path, nd); | 1840 | path_put_conditional(&path, &nd); |
| 1844 | exit: | 1841 | exit: |
| 1845 | if (!IS_ERR(nd->intent.open.file)) | 1842 | if (!IS_ERR(nd.intent.open.file)) |
| 1846 | release_open_intent(nd); | 1843 | release_open_intent(&nd); |
| 1847 | path_put(&nd->path); | 1844 | path_put(&nd.path); |
| 1848 | return error; | 1845 | return ERR_PTR(error); |
| 1849 | 1846 | ||
| 1850 | do_link: | 1847 | do_link: |
| 1851 | error = -ELOOP; | 1848 | error = -ELOOP; |
| @@ -1861,43 +1858,60 @@ do_link: | |||
| 1861 | * stored in nd->last.name and we will have to putname() it when we | 1858 | * stored in nd->last.name and we will have to putname() it when we |
| 1862 | * are done. Procfs-like symlinks just set LAST_BIND. | 1859 | * are done. Procfs-like symlinks just set LAST_BIND. |
| 1863 | */ | 1860 | */ |
| 1864 | nd->flags |= LOOKUP_PARENT; | 1861 | nd.flags |= LOOKUP_PARENT; |
| 1865 | error = security_inode_follow_link(path.dentry, nd); | 1862 | error = security_inode_follow_link(path.dentry, &nd); |
| 1866 | if (error) | 1863 | if (error) |
| 1867 | goto exit_dput; | 1864 | goto exit_dput; |
| 1868 | error = __do_follow_link(&path, nd); | 1865 | error = __do_follow_link(&path, &nd); |
| 1869 | if (error) { | 1866 | if (error) { |
| 1870 | /* Does someone understand code flow here? Or it is only | 1867 | /* Does someone understand code flow here? Or it is only |
| 1871 | * me so stupid? Anathema to whoever designed this non-sense | 1868 | * me so stupid? Anathema to whoever designed this non-sense |
| 1872 | * with "intent.open". | 1869 | * with "intent.open". |
| 1873 | */ | 1870 | */ |
| 1874 | release_open_intent(nd); | 1871 | release_open_intent(&nd); |
| 1875 | return error; | 1872 | return ERR_PTR(error); |
| 1876 | } | 1873 | } |
| 1877 | nd->flags &= ~LOOKUP_PARENT; | 1874 | nd.flags &= ~LOOKUP_PARENT; |
| 1878 | if (nd->last_type == LAST_BIND) | 1875 | if (nd.last_type == LAST_BIND) |
| 1879 | goto ok; | 1876 | goto ok; |
| 1880 | error = -EISDIR; | 1877 | error = -EISDIR; |
| 1881 | if (nd->last_type != LAST_NORM) | 1878 | if (nd.last_type != LAST_NORM) |
| 1882 | goto exit; | 1879 | goto exit; |
| 1883 | if (nd->last.name[nd->last.len]) { | 1880 | if (nd.last.name[nd.last.len]) { |
| 1884 | __putname(nd->last.name); | 1881 | __putname(nd.last.name); |
| 1885 | goto exit; | 1882 | goto exit; |
| 1886 | } | 1883 | } |
| 1887 | error = -ELOOP; | 1884 | error = -ELOOP; |
| 1888 | if (count++==32) { | 1885 | if (count++==32) { |
| 1889 | __putname(nd->last.name); | 1886 | __putname(nd.last.name); |
| 1890 | goto exit; | 1887 | goto exit; |
| 1891 | } | 1888 | } |
| 1892 | dir = nd->path.dentry; | 1889 | dir = nd.path.dentry; |
| 1893 | mutex_lock(&dir->d_inode->i_mutex); | 1890 | mutex_lock(&dir->d_inode->i_mutex); |
| 1894 | path.dentry = lookup_hash(nd); | 1891 | path.dentry = lookup_hash(&nd); |
| 1895 | path.mnt = nd->path.mnt; | 1892 | path.mnt = nd.path.mnt; |
| 1896 | __putname(nd->last.name); | 1893 | __putname(nd.last.name); |
| 1897 | goto do_last; | 1894 | goto do_last; |
| 1898 | } | 1895 | } |
| 1899 | 1896 | ||
| 1900 | /** | 1897 | /** |
| 1898 | * filp_open - open file and return file pointer | ||
| 1899 | * | ||
| 1900 | * @filename: path to open | ||
| 1901 | * @flags: open flags as per the open(2) second argument | ||
| 1902 | * @mode: mode for the new file if O_CREAT is set, else ignored | ||
| 1903 | * | ||
| 1904 | * This is the helper to open a file from kernelspace if you really | ||
| 1905 | * have to. But in generally you should not do this, so please move | ||
| 1906 | * along, nothing to see here.. | ||
| 1907 | */ | ||
| 1908 | struct file *filp_open(const char *filename, int flags, int mode) | ||
| 1909 | { | ||
| 1910 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
| 1911 | } | ||
| 1912 | EXPORT_SYMBOL(filp_open); | ||
| 1913 | |||
| 1914 | /** | ||
| 1901 | * lookup_create - lookup a dentry, creating it if it doesn't exist | 1915 | * lookup_create - lookup a dentry, creating it if it doesn't exist |
| 1902 | * @nd: nameidata info | 1916 | * @nd: nameidata info |
| 1903 | * @is_dir: directory flag | 1917 | * @is_dir: directory flag |
| @@ -796,25 +796,6 @@ cleanup_file: | |||
| 796 | return ERR_PTR(error); | 796 | return ERR_PTR(error); |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | static struct file *do_filp_open(int dfd, const char *filename, int flags, | ||
| 800 | int mode) | ||
| 801 | { | ||
| 802 | int error; | ||
| 803 | struct nameidata nd; | ||
| 804 | |||
| 805 | error = open_namei(dfd, filename, flags, mode, &nd); | ||
| 806 | if (!error) | ||
| 807 | return nameidata_to_filp(&nd, flags); | ||
| 808 | |||
| 809 | return ERR_PTR(error); | ||
| 810 | } | ||
| 811 | |||
| 812 | struct file *filp_open(const char *filename, int flags, int mode) | ||
| 813 | { | ||
| 814 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
| 815 | } | ||
| 816 | EXPORT_SYMBOL(filp_open); | ||
| 817 | |||
| 818 | /** | 799 | /** |
| 819 | * lookup_instantiate_filp - instantiates the open intent filp | 800 | * lookup_instantiate_filp - instantiates the open intent filp |
| 820 | * @nd: pointer to nameidata | 801 | * @nd: pointer to nameidata |
diff --git a/include/linux/fs.h b/include/linux/fs.h index b84b848431f2..013b9c2b88e6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1735,7 +1735,8 @@ extern struct file *create_read_pipe(struct file *f); | |||
| 1735 | extern struct file *create_write_pipe(void); | 1735 | extern struct file *create_write_pipe(void); |
| 1736 | extern void free_write_pipe(struct file *); | 1736 | extern void free_write_pipe(struct file *); |
| 1737 | 1737 | ||
| 1738 | extern int open_namei(int dfd, const char *, int, int, struct nameidata *); | 1738 | extern struct file *do_filp_open(int dfd, const char *pathname, |
| 1739 | int open_flag, int mode); | ||
| 1739 | extern int may_open(struct nameidata *, int, int); | 1740 | extern int may_open(struct nameidata *, int, int); |
| 1740 | 1741 | ||
| 1741 | extern int kernel_read(struct file *, unsigned long, char *, unsigned long); | 1742 | extern int kernel_read(struct file *, unsigned long, char *, unsigned long); |
