diff options
-rw-r--r-- | fs/btrfs/super.c | 9 | ||||
-rw-r--r-- | fs/ceph/super.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 69 | ||||
-rw-r--r-- | fs/nfs/getroot.c | 2 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 2 | ||||
-rw-r--r-- | include/linux/dcache.h | 1 |
6 files changed, 54 insertions, 31 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8e16bca69c56..67b48b9a03e0 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -851,7 +851,6 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
851 | struct btrfs_path *path; | 851 | struct btrfs_path *path; |
852 | struct btrfs_key location; | 852 | struct btrfs_key location; |
853 | struct inode *inode; | 853 | struct inode *inode; |
854 | struct dentry *dentry; | ||
855 | u64 dir_id; | 854 | u64 dir_id; |
856 | int new = 0; | 855 | int new = 0; |
857 | 856 | ||
@@ -922,13 +921,7 @@ setup_root: | |||
922 | return dget(sb->s_root); | 921 | return dget(sb->s_root); |
923 | } | 922 | } |
924 | 923 | ||
925 | dentry = d_obtain_alias(inode); | 924 | return d_obtain_root(inode); |
926 | if (!IS_ERR(dentry)) { | ||
927 | spin_lock(&dentry->d_lock); | ||
928 | dentry->d_flags &= ~DCACHE_DISCONNECTED; | ||
929 | spin_unlock(&dentry->d_lock); | ||
930 | } | ||
931 | return dentry; | ||
932 | } | 925 | } |
933 | 926 | ||
934 | static int btrfs_fill_super(struct super_block *sb, | 927 | static int btrfs_fill_super(struct super_block *sb, |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 06150fd745ac..f6e12377335c 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -755,7 +755,7 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, | |||
755 | goto out; | 755 | goto out; |
756 | } | 756 | } |
757 | } else { | 757 | } else { |
758 | root = d_obtain_alias(inode); | 758 | root = d_obtain_root(inode); |
759 | } | 759 | } |
760 | ceph_init_dentry(root); | 760 | ceph_init_dentry(root); |
761 | dout("open_root_inode success, root dentry is %p\n", root); | 761 | dout("open_root_inode success, root dentry is %p\n", root); |
diff --git a/fs/dcache.c b/fs/dcache.c index 3ed095363997..63d556c0e698 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1781,25 +1781,7 @@ struct dentry *d_find_any_alias(struct inode *inode) | |||
1781 | } | 1781 | } |
1782 | EXPORT_SYMBOL(d_find_any_alias); | 1782 | EXPORT_SYMBOL(d_find_any_alias); |
1783 | 1783 | ||
1784 | /** | 1784 | struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) |
1785 | * d_obtain_alias - find or allocate a dentry for a given inode | ||
1786 | * @inode: inode to allocate the dentry for | ||
1787 | * | ||
1788 | * Obtain a dentry for an inode resulting from NFS filehandle conversion or | ||
1789 | * similar open by handle operations. The returned dentry may be anonymous, | ||
1790 | * or may have a full name (if the inode was already in the cache). | ||
1791 | * | ||
1792 | * When called on a directory inode, we must ensure that the inode only ever | ||
1793 | * has one dentry. If a dentry is found, that is returned instead of | ||
1794 | * allocating a new one. | ||
1795 | * | ||
1796 | * On successful return, the reference to the inode has been transferred | ||
1797 | * to the dentry. In case of an error the reference on the inode is released. | ||
1798 | * To make it easier to use in export operations a %NULL or IS_ERR inode may | ||
1799 | * be passed in and will be the error will be propagate to the return value, | ||
1800 | * with a %NULL @inode replaced by ERR_PTR(-ESTALE). | ||
1801 | */ | ||
1802 | struct dentry *d_obtain_alias(struct inode *inode) | ||
1803 | { | 1785 | { |
1804 | static const struct qstr anonstring = QSTR_INIT("/", 1); | 1786 | static const struct qstr anonstring = QSTR_INIT("/", 1); |
1805 | struct dentry *tmp; | 1787 | struct dentry *tmp; |
@@ -1830,7 +1812,10 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1830 | } | 1812 | } |
1831 | 1813 | ||
1832 | /* attach a disconnected dentry */ | 1814 | /* attach a disconnected dentry */ |
1833 | add_flags = d_flags_for_inode(inode) | DCACHE_DISCONNECTED; | 1815 | add_flags = d_flags_for_inode(inode); |
1816 | |||
1817 | if (disconnected) | ||
1818 | add_flags |= DCACHE_DISCONNECTED; | ||
1834 | 1819 | ||
1835 | spin_lock(&tmp->d_lock); | 1820 | spin_lock(&tmp->d_lock); |
1836 | tmp->d_inode = inode; | 1821 | tmp->d_inode = inode; |
@@ -1851,9 +1836,53 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1851 | iput(inode); | 1836 | iput(inode); |
1852 | return res; | 1837 | return res; |
1853 | } | 1838 | } |
1839 | |||
1840 | /** | ||
1841 | * d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode | ||
1842 | * @inode: inode to allocate the dentry for | ||
1843 | * | ||
1844 | * Obtain a dentry for an inode resulting from NFS filehandle conversion or | ||
1845 | * similar open by handle operations. The returned dentry may be anonymous, | ||
1846 | * or may have a full name (if the inode was already in the cache). | ||
1847 | * | ||
1848 | * When called on a directory inode, we must ensure that the inode only ever | ||
1849 | * has one dentry. If a dentry is found, that is returned instead of | ||
1850 | * allocating a new one. | ||
1851 | * | ||
1852 | * On successful return, the reference to the inode has been transferred | ||
1853 | * to the dentry. In case of an error the reference on the inode is released. | ||
1854 | * To make it easier to use in export operations a %NULL or IS_ERR inode may | ||
1855 | * be passed in and the error will be propagated to the return value, | ||
1856 | * with a %NULL @inode replaced by ERR_PTR(-ESTALE). | ||
1857 | */ | ||
1858 | struct dentry *d_obtain_alias(struct inode *inode) | ||
1859 | { | ||
1860 | return __d_obtain_alias(inode, 1); | ||
1861 | } | ||
1854 | EXPORT_SYMBOL(d_obtain_alias); | 1862 | EXPORT_SYMBOL(d_obtain_alias); |
1855 | 1863 | ||
1856 | /** | 1864 | /** |
1865 | * d_obtain_root - find or allocate a dentry for a given inode | ||
1866 | * @inode: inode to allocate the dentry for | ||
1867 | * | ||
1868 | * Obtain an IS_ROOT dentry for the root of a filesystem. | ||
1869 | * | ||
1870 | * We must ensure that directory inodes only ever have one dentry. If a | ||
1871 | * dentry is found, that is returned instead of allocating a new one. | ||
1872 | * | ||
1873 | * On successful return, the reference to the inode has been transferred | ||
1874 | * to the dentry. In case of an error the reference on the inode is | ||
1875 | * released. A %NULL or IS_ERR inode may be passed in and will be the | ||
1876 | * error will be propagate to the return value, with a %NULL @inode | ||
1877 | * replaced by ERR_PTR(-ESTALE). | ||
1878 | */ | ||
1879 | struct dentry *d_obtain_root(struct inode *inode) | ||
1880 | { | ||
1881 | return __d_obtain_alias(inode, 0); | ||
1882 | } | ||
1883 | EXPORT_SYMBOL(d_obtain_root); | ||
1884 | |||
1885 | /** | ||
1857 | * d_add_ci - lookup or allocate new dentry with case-exact name | 1886 | * d_add_ci - lookup or allocate new dentry with case-exact name |
1858 | * @inode: the inode case-insensitive lookup has found | 1887 | * @inode: the inode case-insensitive lookup has found |
1859 | * @dentry: the negative dentry that was passed to the parent's lookup func | 1888 | * @dentry: the negative dentry that was passed to the parent's lookup func |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index b94f80420a58..880618a8b048 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -112,7 +112,7 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh, | |||
112 | * if the dentry tree reaches them; however if the dentry already | 112 | * if the dentry tree reaches them; however if the dentry already |
113 | * exists, we'll pick it up at this point and use it as the root | 113 | * exists, we'll pick it up at this point and use it as the root |
114 | */ | 114 | */ |
115 | ret = d_obtain_alias(inode); | 115 | ret = d_obtain_root(inode); |
116 | if (IS_ERR(ret)) { | 116 | if (IS_ERR(ret)) { |
117 | dprintk("nfs_get_root: get root dentry failed\n"); | 117 | dprintk("nfs_get_root: get root dentry failed\n"); |
118 | goto out; | 118 | goto out; |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 8c532b2ca3ab..ac914994dfed 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -942,7 +942,7 @@ static int nilfs_get_root_dentry(struct super_block *sb, | |||
942 | iput(inode); | 942 | iput(inode); |
943 | } | 943 | } |
944 | } else { | 944 | } else { |
945 | dentry = d_obtain_alias(inode); | 945 | dentry = d_obtain_root(inode); |
946 | if (IS_ERR(dentry)) { | 946 | if (IS_ERR(dentry)) { |
947 | ret = PTR_ERR(dentry); | 947 | ret = PTR_ERR(dentry); |
948 | goto failed_dentry; | 948 | goto failed_dentry; |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 3c7ec327ebd2..e4ae2ad48d07 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -249,6 +249,7 @@ extern struct dentry * d_splice_alias(struct inode *, struct dentry *); | |||
249 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); | 249 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); |
250 | extern struct dentry *d_find_any_alias(struct inode *inode); | 250 | extern struct dentry *d_find_any_alias(struct inode *inode); |
251 | extern struct dentry * d_obtain_alias(struct inode *); | 251 | extern struct dentry * d_obtain_alias(struct inode *); |
252 | extern struct dentry * d_obtain_root(struct inode *); | ||
252 | extern void shrink_dcache_sb(struct super_block *); | 253 | extern void shrink_dcache_sb(struct super_block *); |
253 | extern void shrink_dcache_parent(struct dentry *); | 254 | extern void shrink_dcache_parent(struct dentry *); |
254 | extern void shrink_dcache_for_umount(struct super_block *); | 255 | extern void shrink_dcache_for_umount(struct super_block *); |