diff options
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 55 |
2 files changed, 39 insertions, 18 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 040213359393..cecf29e03630 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1700,6 +1700,8 @@ struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, | |||
1700 | struct btrfs_root *root); | 1700 | struct btrfs_root *root); |
1701 | struct inode *btrfs_ilookup(struct super_block *s, u64 objectid, | 1701 | struct inode *btrfs_ilookup(struct super_block *s, u64 objectid, |
1702 | u64 root_objectid); | 1702 | u64 root_objectid); |
1703 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | ||
1704 | struct btrfs_root *root, int *is_new); | ||
1703 | int btrfs_commit_write(struct file *file, struct page *page, | 1705 | int btrfs_commit_write(struct file *file, struct page *page, |
1704 | unsigned from, unsigned to); | 1706 | unsigned from, unsigned to); |
1705 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | 1707 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 38d7a81763cd..266ca5514b33 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1840,6 +1840,33 @@ struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, | |||
1840 | return inode; | 1840 | return inode; |
1841 | } | 1841 | } |
1842 | 1842 | ||
1843 | /* Get an inode object given its location and corresponding root. | ||
1844 | * Returns in *is_new if the inode was read from disk | ||
1845 | */ | ||
1846 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | ||
1847 | struct btrfs_root *root, int *is_new) | ||
1848 | { | ||
1849 | struct inode *inode; | ||
1850 | |||
1851 | inode = btrfs_iget_locked(s, location->objectid, root); | ||
1852 | if (!inode) | ||
1853 | return ERR_PTR(-EACCES); | ||
1854 | |||
1855 | if (inode->i_state & I_NEW) { | ||
1856 | BTRFS_I(inode)->root = root; | ||
1857 | memcpy(&BTRFS_I(inode)->location, location, sizeof(*location)); | ||
1858 | btrfs_read_locked_inode(inode); | ||
1859 | unlock_new_inode(inode); | ||
1860 | if (is_new) | ||
1861 | *is_new = 1; | ||
1862 | } else { | ||
1863 | if (is_new) | ||
1864 | *is_new = 0; | ||
1865 | } | ||
1866 | |||
1867 | return inode; | ||
1868 | } | ||
1869 | |||
1843 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 1870 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
1844 | struct nameidata *nd) | 1871 | struct nameidata *nd) |
1845 | { | 1872 | { |
@@ -1848,7 +1875,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | |||
1848 | struct btrfs_root *root = bi->root; | 1875 | struct btrfs_root *root = bi->root; |
1849 | struct btrfs_root *sub_root = root; | 1876 | struct btrfs_root *sub_root = root; |
1850 | struct btrfs_key location; | 1877 | struct btrfs_key location; |
1851 | int ret, do_orphan = 0; | 1878 | int ret, new, do_orphan = 0; |
1852 | 1879 | ||
1853 | if (dentry->d_name.len > BTRFS_NAME_LEN) | 1880 | if (dentry->d_name.len > BTRFS_NAME_LEN) |
1854 | return ERR_PTR(-ENAMETOOLONG); | 1881 | return ERR_PTR(-ENAMETOOLONG); |
@@ -1866,23 +1893,15 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | |||
1866 | return ERR_PTR(ret); | 1893 | return ERR_PTR(ret); |
1867 | if (ret > 0) | 1894 | if (ret > 0) |
1868 | return ERR_PTR(-ENOENT); | 1895 | return ERR_PTR(-ENOENT); |
1869 | 1896 | inode = btrfs_iget(dir->i_sb, &location, sub_root, &new); | |
1870 | inode = btrfs_iget_locked(dir->i_sb, location.objectid, | 1897 | if (IS_ERR(inode)) |
1871 | sub_root); | 1898 | return ERR_CAST(inode); |
1872 | if (!inode) | 1899 | |
1873 | return ERR_PTR(-EACCES); | 1900 | /* the inode and parent dir are two different roots */ |
1874 | if (inode->i_state & I_NEW) { | 1901 | if (new && root != sub_root) { |
1875 | /* the inode and parent dir are two different roots */ | 1902 | igrab(inode); |
1876 | if (sub_root != root) { | 1903 | sub_root->inode = inode; |
1877 | igrab(inode); | 1904 | do_orphan = 1; |
1878 | sub_root->inode = inode; | ||
1879 | do_orphan = 1; | ||
1880 | } | ||
1881 | BTRFS_I(inode)->root = sub_root; | ||
1882 | memcpy(&BTRFS_I(inode)->location, &location, | ||
1883 | sizeof(location)); | ||
1884 | btrfs_read_locked_inode(inode); | ||
1885 | unlock_new_inode(inode); | ||
1886 | } | 1905 | } |
1887 | } | 1906 | } |
1888 | 1907 | ||