aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-02-15 17:37:28 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2008-04-19 00:25:32 -0400
commita70e65df8812c52252fa07a2eb92a46451a4427f (patch)
treeb8154bebeb898743e89aeeea5971b410c7e49bf7
parentd57999e1527f0b0c818846dcba5a23015beb4823 (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.c100
-rw-r--r--fs/open.c19
-rw-r--r--include/linux/fs.h3
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 */
1736int open_namei(int dfd, const char *pathname, int open_flag, 1731struct 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
1789do_last: 1786do_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;
1836ok: 1833ok:
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
1842exit_dput: 1839exit_dput:
1843 path_put_conditional(&path, nd); 1840 path_put_conditional(&path, &nd);
1844exit: 1841exit:
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
1850do_link: 1847do_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 */
1908struct file *filp_open(const char *filename, int flags, int mode)
1909{
1910 return do_filp_open(AT_FDCWD, filename, flags, mode);
1911}
1912EXPORT_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
diff --git a/fs/open.c b/fs/open.c
index 5ab3f3f079c0..8111947905d8 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -796,25 +796,6 @@ cleanup_file:
796 return ERR_PTR(error); 796 return ERR_PTR(error);
797} 797}
798 798
799static 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
812struct file *filp_open(const char *filename, int flags, int mode)
813{
814 return do_filp_open(AT_FDCWD, filename, flags, mode);
815}
816EXPORT_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);
1735extern struct file *create_write_pipe(void); 1735extern struct file *create_write_pipe(void);
1736extern void free_write_pipe(struct file *); 1736extern void free_write_pipe(struct file *);
1737 1737
1738extern int open_namei(int dfd, const char *, int, int, struct nameidata *); 1738extern struct file *do_filp_open(int dfd, const char *pathname,
1739 int open_flag, int mode);
1739extern int may_open(struct nameidata *, int, int); 1740extern int may_open(struct nameidata *, int, int);
1740 1741
1741extern int kernel_read(struct file *, unsigned long, char *, unsigned long); 1742extern int kernel_read(struct file *, unsigned long, char *, unsigned long);