diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-24 16:13:08 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:59 -0400 |
commit | d1310b2e0cd98eb1348553e69b73827b436dca7b (patch) | |
tree | f55e9c380df0f3a7e9fb792b2308b52b632b90aa /fs/btrfs/inode.c | |
parent | 5f56406aabdf5444d040c5955effc665b1d0dbaf (diff) |
Btrfs: Split the extent_map code into two parts
There is now extent_map for mapping offsets in the file to disk and
extent_io for state tracking, IO submission and extent_bufers.
The new extent_map code shifts from [start,end] pairs to [start,len], and
pushes the locking out into the caller. This allows a few performance
optimizations and is easier to use.
A number of extent_map usage bugs were fixed, mostly with failing
to remove extent_map entries when changing the file.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 175 |
1 files changed, 92 insertions, 83 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 67005480e139..16d3aef45d18 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -53,7 +53,7 @@ static struct inode_operations btrfs_file_inode_operations; | |||
53 | static struct address_space_operations btrfs_aops; | 53 | static struct address_space_operations btrfs_aops; |
54 | static struct address_space_operations btrfs_symlink_aops; | 54 | static struct address_space_operations btrfs_symlink_aops; |
55 | static struct file_operations btrfs_dir_file_operations; | 55 | static struct file_operations btrfs_dir_file_operations; |
56 | static struct extent_map_ops btrfs_extent_map_ops; | 56 | static struct extent_io_ops btrfs_extent_io_ops; |
57 | 57 | ||
58 | static struct kmem_cache *btrfs_inode_cachep; | 58 | static struct kmem_cache *btrfs_inode_cachep; |
59 | struct kmem_cache *btrfs_trans_handle_cachep; | 59 | struct kmem_cache *btrfs_trans_handle_cachep; |
@@ -104,6 +104,8 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) | |||
104 | u64 num_bytes; | 104 | u64 num_bytes; |
105 | u64 cur_alloc_size; | 105 | u64 cur_alloc_size; |
106 | u64 blocksize = root->sectorsize; | 106 | u64 blocksize = root->sectorsize; |
107 | u64 orig_start = start; | ||
108 | u64 orig_num_bytes; | ||
107 | struct btrfs_key ins; | 109 | struct btrfs_key ins; |
108 | int ret; | 110 | int ret; |
109 | 111 | ||
@@ -115,6 +117,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) | |||
115 | num_bytes = max(blocksize, num_bytes); | 117 | num_bytes = max(blocksize, num_bytes); |
116 | ret = btrfs_drop_extents(trans, root, inode, | 118 | ret = btrfs_drop_extents(trans, root, inode, |
117 | start, start + num_bytes, start, &alloc_hint); | 119 | start, start + num_bytes, start, &alloc_hint); |
120 | orig_num_bytes = num_bytes; | ||
118 | 121 | ||
119 | if (alloc_hint == EXTENT_MAP_INLINE) | 122 | if (alloc_hint == EXTENT_MAP_INLINE) |
120 | goto out; | 123 | goto out; |
@@ -138,6 +141,8 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) | |||
138 | alloc_hint = ins.objectid + ins.offset; | 141 | alloc_hint = ins.objectid + ins.offset; |
139 | start += cur_alloc_size; | 142 | start += cur_alloc_size; |
140 | } | 143 | } |
144 | btrfs_drop_extent_cache(inode, orig_start, | ||
145 | orig_start + orig_num_bytes - 1); | ||
141 | btrfs_add_ordered_inode(inode); | 146 | btrfs_add_ordered_inode(inode); |
142 | out: | 147 | out: |
143 | btrfs_end_transaction(trans, root); | 148 | btrfs_end_transaction(trans, root); |
@@ -297,7 +302,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) | |||
297 | int ret = 0; | 302 | int ret = 0; |
298 | struct inode *inode = page->mapping->host; | 303 | struct inode *inode = page->mapping->host; |
299 | struct btrfs_root *root = BTRFS_I(inode)->root; | 304 | struct btrfs_root *root = BTRFS_I(inode)->root; |
300 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 305 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
301 | struct btrfs_csum_item *item; | 306 | struct btrfs_csum_item *item; |
302 | struct btrfs_path *path = NULL; | 307 | struct btrfs_path *path = NULL; |
303 | u32 csum; | 308 | u32 csum; |
@@ -317,7 +322,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) | |||
317 | } | 322 | } |
318 | read_extent_buffer(path->nodes[0], &csum, (unsigned long)item, | 323 | read_extent_buffer(path->nodes[0], &csum, (unsigned long)item, |
319 | BTRFS_CRC32_SIZE); | 324 | BTRFS_CRC32_SIZE); |
320 | set_state_private(em_tree, start, csum); | 325 | set_state_private(io_tree, start, csum); |
321 | out: | 326 | out: |
322 | if (path) | 327 | if (path) |
323 | btrfs_free_path(path); | 328 | btrfs_free_path(path); |
@@ -329,17 +334,19 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) | |||
329 | { | 334 | { |
330 | size_t offset = start - ((u64)page->index << PAGE_CACHE_SHIFT); | 335 | size_t offset = start - ((u64)page->index << PAGE_CACHE_SHIFT); |
331 | struct inode *inode = page->mapping->host; | 336 | struct inode *inode = page->mapping->host; |
332 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 337 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
333 | char *kaddr; | 338 | char *kaddr; |
334 | u64 private; | 339 | u64 private; |
335 | int ret; | 340 | int ret; |
336 | struct btrfs_root *root = BTRFS_I(inode)->root; | 341 | struct btrfs_root *root = BTRFS_I(inode)->root; |
337 | u32 csum = ~(u32)0; | 342 | u32 csum = ~(u32)0; |
338 | unsigned long flags; | 343 | unsigned long flags; |
344 | |||
339 | if (btrfs_test_opt(root, NODATASUM) || | 345 | if (btrfs_test_opt(root, NODATASUM) || |
340 | btrfs_test_flag(inode, NODATASUM)) | 346 | btrfs_test_flag(inode, NODATASUM)) |
341 | return 0; | 347 | return 0; |
342 | ret = get_state_private(em_tree, start, &private); | 348 | |
349 | ret = get_state_private(io_tree, start, &private); | ||
343 | local_irq_save(flags); | 350 | local_irq_save(flags); |
344 | kaddr = kmap_atomic(page, KM_IRQ0); | 351 | kaddr = kmap_atomic(page, KM_IRQ0); |
345 | if (ret) { | 352 | if (ret) { |
@@ -428,7 +435,7 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
428 | switch (inode->i_mode & S_IFMT) { | 435 | switch (inode->i_mode & S_IFMT) { |
429 | case S_IFREG: | 436 | case S_IFREG: |
430 | inode->i_mapping->a_ops = &btrfs_aops; | 437 | inode->i_mapping->a_ops = &btrfs_aops; |
431 | BTRFS_I(inode)->extent_tree.ops = &btrfs_extent_map_ops; | 438 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
432 | inode->i_fop = &btrfs_file_operations; | 439 | inode->i_fop = &btrfs_file_operations; |
433 | inode->i_op = &btrfs_file_inode_operations; | 440 | inode->i_op = &btrfs_file_inode_operations; |
434 | break; | 441 | break; |
@@ -873,7 +880,7 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page, | |||
873 | size_t zero_start) | 880 | size_t zero_start) |
874 | { | 881 | { |
875 | char *kaddr; | 882 | char *kaddr; |
876 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 883 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
877 | struct btrfs_root *root = BTRFS_I(inode)->root; | 884 | struct btrfs_root *root = BTRFS_I(inode)->root; |
878 | u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; | 885 | u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; |
879 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; | 886 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; |
@@ -884,12 +891,12 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page, | |||
884 | WARN_ON(!PageLocked(page)); | 891 | WARN_ON(!PageLocked(page)); |
885 | set_page_extent_mapped(page); | 892 | set_page_extent_mapped(page); |
886 | 893 | ||
887 | lock_extent(em_tree, page_start, page_end, GFP_NOFS); | 894 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
888 | delalloc_start = page_start; | 895 | delalloc_start = page_start; |
889 | existing_delalloc = count_range_bits(&BTRFS_I(inode)->extent_tree, | 896 | existing_delalloc = count_range_bits(&BTRFS_I(inode)->io_tree, |
890 | &delalloc_start, page_end, | 897 | &delalloc_start, page_end, |
891 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); | 898 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); |
892 | set_extent_delalloc(&BTRFS_I(inode)->extent_tree, page_start, | 899 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, |
893 | page_end, GFP_NOFS); | 900 | page_end, GFP_NOFS); |
894 | 901 | ||
895 | spin_lock(&root->fs_info->delalloc_lock); | 902 | spin_lock(&root->fs_info->delalloc_lock); |
@@ -903,7 +910,7 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page, | |||
903 | kunmap(page); | 910 | kunmap(page); |
904 | } | 911 | } |
905 | set_page_dirty(page); | 912 | set_page_dirty(page); |
906 | unlock_extent(em_tree, page_start, page_end, GFP_NOFS); | 913 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
907 | 914 | ||
908 | return ret; | 915 | return ret; |
909 | } | 916 | } |
@@ -961,7 +968,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
961 | attr->ia_valid & ATTR_SIZE && attr->ia_size > inode->i_size) { | 968 | attr->ia_valid & ATTR_SIZE && attr->ia_size > inode->i_size) { |
962 | struct btrfs_trans_handle *trans; | 969 | struct btrfs_trans_handle *trans; |
963 | struct btrfs_root *root = BTRFS_I(inode)->root; | 970 | struct btrfs_root *root = BTRFS_I(inode)->root; |
964 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 971 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
965 | 972 | ||
966 | u64 mask = root->sectorsize - 1; | 973 | u64 mask = root->sectorsize - 1; |
967 | u64 pos = (inode->i_size + mask) & ~mask; | 974 | u64 pos = (inode->i_size + mask) & ~mask; |
@@ -986,7 +993,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
986 | 993 | ||
987 | btrfs_truncate_page(inode->i_mapping, inode->i_size); | 994 | btrfs_truncate_page(inode->i_mapping, inode->i_size); |
988 | 995 | ||
989 | lock_extent(em_tree, pos, block_end, GFP_NOFS); | 996 | lock_extent(io_tree, pos, block_end, GFP_NOFS); |
990 | hole_size = block_end - hole_start; | 997 | hole_size = block_end - hole_start; |
991 | 998 | ||
992 | mutex_lock(&root->fs_info->fs_mutex); | 999 | mutex_lock(&root->fs_info->fs_mutex); |
@@ -1001,11 +1008,13 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
1001 | inode->i_ino, | 1008 | inode->i_ino, |
1002 | hole_start, 0, 0, | 1009 | hole_start, 0, 0, |
1003 | hole_size); | 1010 | hole_size); |
1011 | btrfs_drop_extent_cache(inode, hole_start, | ||
1012 | hole_size - 1); | ||
1004 | btrfs_check_file(root, inode); | 1013 | btrfs_check_file(root, inode); |
1005 | } | 1014 | } |
1006 | btrfs_end_transaction(trans, root); | 1015 | btrfs_end_transaction(trans, root); |
1007 | mutex_unlock(&root->fs_info->fs_mutex); | 1016 | mutex_unlock(&root->fs_info->fs_mutex); |
1008 | unlock_extent(em_tree, pos, block_end, GFP_NOFS); | 1017 | unlock_extent(io_tree, pos, block_end, GFP_NOFS); |
1009 | if (err) | 1018 | if (err) |
1010 | return err; | 1019 | return err; |
1011 | } | 1020 | } |
@@ -1189,7 +1198,8 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
1189 | struct btrfs_iget_args *args = p; | 1198 | struct btrfs_iget_args *args = p; |
1190 | inode->i_ino = args->ino; | 1199 | inode->i_ino = args->ino; |
1191 | BTRFS_I(inode)->root = args->root; | 1200 | BTRFS_I(inode)->root = args->root; |
1192 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, | 1201 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
1202 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
1193 | inode->i_mapping, GFP_NOFS); | 1203 | inode->i_mapping, GFP_NOFS); |
1194 | return 0; | 1204 | return 0; |
1195 | } | 1205 | } |
@@ -1485,7 +1495,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1485 | if (!inode) | 1495 | if (!inode) |
1486 | return ERR_PTR(-ENOMEM); | 1496 | return ERR_PTR(-ENOMEM); |
1487 | 1497 | ||
1488 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, | 1498 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
1499 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
1489 | inode->i_mapping, GFP_NOFS); | 1500 | inode->i_mapping, GFP_NOFS); |
1490 | BTRFS_I(inode)->root = root; | 1501 | BTRFS_I(inode)->root = root; |
1491 | 1502 | ||
@@ -1672,9 +1683,10 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
1672 | inode->i_mapping->a_ops = &btrfs_aops; | 1683 | inode->i_mapping->a_ops = &btrfs_aops; |
1673 | inode->i_fop = &btrfs_file_operations; | 1684 | inode->i_fop = &btrfs_file_operations; |
1674 | inode->i_op = &btrfs_file_inode_operations; | 1685 | inode->i_op = &btrfs_file_inode_operations; |
1675 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, | 1686 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
1687 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
1676 | inode->i_mapping, GFP_NOFS); | 1688 | inode->i_mapping, GFP_NOFS); |
1677 | BTRFS_I(inode)->extent_tree.ops = &btrfs_extent_map_ops; | 1689 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
1678 | } | 1690 | } |
1679 | dir->i_sb->s_dirt = 1; | 1691 | dir->i_sb->s_dirt = 1; |
1680 | btrfs_update_inode_block_group(trans, inode); | 1692 | btrfs_update_inode_block_group(trans, inode); |
@@ -1816,7 +1828,7 @@ out_unlock: | |||
1816 | } | 1828 | } |
1817 | 1829 | ||
1818 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | 1830 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, |
1819 | size_t page_offset, u64 start, u64 end, | 1831 | size_t page_offset, u64 start, u64 len, |
1820 | int create) | 1832 | int create) |
1821 | { | 1833 | { |
1822 | int ret; | 1834 | int ret; |
@@ -1826,7 +1838,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
1826 | u64 extent_end = 0; | 1838 | u64 extent_end = 0; |
1827 | u64 objectid = inode->i_ino; | 1839 | u64 objectid = inode->i_ino; |
1828 | u32 found_type; | 1840 | u32 found_type; |
1829 | int failed_insert = 0; | ||
1830 | struct btrfs_path *path; | 1841 | struct btrfs_path *path; |
1831 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1842 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1832 | struct btrfs_file_extent_item *item; | 1843 | struct btrfs_file_extent_item *item; |
@@ -1834,6 +1845,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
1834 | struct btrfs_key found_key; | 1845 | struct btrfs_key found_key; |
1835 | struct extent_map *em = NULL; | 1846 | struct extent_map *em = NULL; |
1836 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 1847 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
1848 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | ||
1837 | struct btrfs_trans_handle *trans = NULL; | 1849 | struct btrfs_trans_handle *trans = NULL; |
1838 | 1850 | ||
1839 | path = btrfs_alloc_path(); | 1851 | path = btrfs_alloc_path(); |
@@ -1841,24 +1853,26 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
1841 | mutex_lock(&root->fs_info->fs_mutex); | 1853 | mutex_lock(&root->fs_info->fs_mutex); |
1842 | 1854 | ||
1843 | again: | 1855 | again: |
1844 | em = lookup_extent_mapping(em_tree, start, end); | 1856 | spin_lock(&em_tree->lock); |
1857 | em = lookup_extent_mapping(em_tree, start, len); | ||
1858 | spin_unlock(&em_tree->lock); | ||
1859 | |||
1845 | if (em) { | 1860 | if (em) { |
1846 | if (em->start > start) { | 1861 | if (em->start > start) { |
1847 | printk("get_extent start %Lu em start %Lu\n", | 1862 | printk("get_extent lookup [%Lu %Lu] em [%Lu %Lu]\n", |
1848 | start, em->start); | 1863 | start, len, em->start, em->len); |
1849 | WARN_ON(1); | 1864 | WARN_ON(1); |
1850 | } | 1865 | } |
1851 | goto out; | 1866 | goto out; |
1852 | } | 1867 | } |
1868 | em = alloc_extent_map(GFP_NOFS); | ||
1853 | if (!em) { | 1869 | if (!em) { |
1854 | em = alloc_extent_map(GFP_NOFS); | 1870 | err = -ENOMEM; |
1855 | if (!em) { | 1871 | goto out; |
1856 | err = -ENOMEM; | ||
1857 | goto out; | ||
1858 | } | ||
1859 | em->start = EXTENT_MAP_HOLE; | ||
1860 | em->end = EXTENT_MAP_HOLE; | ||
1861 | } | 1872 | } |
1873 | |||
1874 | em->start = EXTENT_MAP_HOLE; | ||
1875 | em->len = (u64)-1; | ||
1862 | em->bdev = inode->i_sb->s_bdev; | 1876 | em->bdev = inode->i_sb->s_bdev; |
1863 | ret = btrfs_lookup_file_extent(trans, root, path, | 1877 | ret = btrfs_lookup_file_extent(trans, root, path, |
1864 | objectid, start, trans != NULL); | 1878 | objectid, start, trans != NULL); |
@@ -1893,28 +1907,25 @@ again: | |||
1893 | if (start < extent_start || start >= extent_end) { | 1907 | if (start < extent_start || start >= extent_end) { |
1894 | em->start = start; | 1908 | em->start = start; |
1895 | if (start < extent_start) { | 1909 | if (start < extent_start) { |
1896 | if (end < extent_start) | 1910 | if (start + len <= extent_start) |
1897 | goto not_found; | 1911 | goto not_found; |
1898 | em->end = extent_end - 1; | 1912 | em->len = extent_end - extent_start; |
1899 | } else { | 1913 | } else { |
1900 | em->end = end; | 1914 | em->len = len; |
1901 | } | 1915 | } |
1902 | goto not_found_em; | 1916 | goto not_found_em; |
1903 | } | 1917 | } |
1904 | bytenr = btrfs_file_extent_disk_bytenr(leaf, item); | 1918 | bytenr = btrfs_file_extent_disk_bytenr(leaf, item); |
1905 | if (bytenr == 0) { | 1919 | if (bytenr == 0) { |
1906 | em->start = extent_start; | 1920 | em->start = extent_start; |
1907 | em->end = extent_end - 1; | 1921 | em->len = extent_end - extent_start; |
1908 | em->block_start = EXTENT_MAP_HOLE; | 1922 | em->block_start = EXTENT_MAP_HOLE; |
1909 | em->block_end = EXTENT_MAP_HOLE; | ||
1910 | goto insert; | 1923 | goto insert; |
1911 | } | 1924 | } |
1912 | bytenr += btrfs_file_extent_offset(leaf, item); | 1925 | bytenr += btrfs_file_extent_offset(leaf, item); |
1913 | em->block_start = bytenr; | 1926 | em->block_start = bytenr; |
1914 | em->block_end = em->block_start + | ||
1915 | btrfs_file_extent_num_bytes(leaf, item) - 1; | ||
1916 | em->start = extent_start; | 1927 | em->start = extent_start; |
1917 | em->end = extent_end - 1; | 1928 | em->len = extent_end - extent_start; |
1918 | goto insert; | 1929 | goto insert; |
1919 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 1930 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
1920 | unsigned long ptr; | 1931 | unsigned long ptr; |
@@ -1925,25 +1936,24 @@ again: | |||
1925 | 1936 | ||
1926 | size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf, | 1937 | size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf, |
1927 | path->slots[0])); | 1938 | path->slots[0])); |
1928 | extent_end = (extent_start + size - 1) | | 1939 | extent_end = (extent_start + size + root->sectorsize - 1) & |
1929 | ((u64)root->sectorsize - 1); | 1940 | ~((u64)root->sectorsize - 1); |
1930 | if (start < extent_start || start >= extent_end) { | 1941 | if (start < extent_start || start >= extent_end) { |
1931 | em->start = start; | 1942 | em->start = start; |
1932 | if (start < extent_start) { | 1943 | if (start < extent_start) { |
1933 | if (end < extent_start) | 1944 | if (start + len <= extent_start) |
1934 | goto not_found; | 1945 | goto not_found; |
1935 | em->end = extent_end; | 1946 | em->len = extent_end - extent_start; |
1936 | } else { | 1947 | } else { |
1937 | em->end = end; | 1948 | em->len = len; |
1938 | } | 1949 | } |
1939 | goto not_found_em; | 1950 | goto not_found_em; |
1940 | } | 1951 | } |
1941 | em->block_start = EXTENT_MAP_INLINE; | 1952 | em->block_start = EXTENT_MAP_INLINE; |
1942 | em->block_end = EXTENT_MAP_INLINE; | ||
1943 | 1953 | ||
1944 | if (!page) { | 1954 | if (!page) { |
1945 | em->start = extent_start; | 1955 | em->start = extent_start; |
1946 | em->end = extent_start + size - 1; | 1956 | em->len = size; |
1947 | goto out; | 1957 | goto out; |
1948 | } | 1958 | } |
1949 | 1959 | ||
@@ -1952,8 +1962,7 @@ again: | |||
1952 | copy_size = min_t(u64, PAGE_CACHE_SIZE - page_offset, | 1962 | copy_size = min_t(u64, PAGE_CACHE_SIZE - page_offset, |
1953 | size - extent_offset); | 1963 | size - extent_offset); |
1954 | em->start = extent_start + extent_offset; | 1964 | em->start = extent_start + extent_offset; |
1955 | em->end = (em->start + copy_size -1) | | 1965 | em->len = copy_size; |
1956 | ((u64)root->sectorsize -1); | ||
1957 | map = kmap(page); | 1966 | map = kmap(page); |
1958 | ptr = btrfs_file_extent_inline_start(item) + extent_offset; | 1967 | ptr = btrfs_file_extent_inline_start(item) + extent_offset; |
1959 | if (create == 0 && !PageUptodate(page)) { | 1968 | if (create == 0 && !PageUptodate(page)) { |
@@ -1974,7 +1983,8 @@ again: | |||
1974 | btrfs_mark_buffer_dirty(leaf); | 1983 | btrfs_mark_buffer_dirty(leaf); |
1975 | } | 1984 | } |
1976 | kunmap(page); | 1985 | kunmap(page); |
1977 | set_extent_uptodate(em_tree, em->start, em->end, GFP_NOFS); | 1986 | set_extent_uptodate(io_tree, em->start, |
1987 | extent_map_end(em) - 1, GFP_NOFS); | ||
1978 | goto insert; | 1988 | goto insert; |
1979 | } else { | 1989 | } else { |
1980 | printk("unkknown found_type %d\n", found_type); | 1990 | printk("unkknown found_type %d\n", found_type); |
@@ -1982,33 +1992,29 @@ again: | |||
1982 | } | 1992 | } |
1983 | not_found: | 1993 | not_found: |
1984 | em->start = start; | 1994 | em->start = start; |
1985 | em->end = end; | 1995 | em->len = len; |
1986 | not_found_em: | 1996 | not_found_em: |
1987 | em->block_start = EXTENT_MAP_HOLE; | 1997 | em->block_start = EXTENT_MAP_HOLE; |
1988 | em->block_end = EXTENT_MAP_HOLE; | ||
1989 | insert: | 1998 | insert: |
1990 | btrfs_release_path(root, path); | 1999 | btrfs_release_path(root, path); |
1991 | if (em->start > start || em->end < start) { | 2000 | if (em->start > start || extent_map_end(em) <= start) { |
1992 | printk("bad extent! em: [%Lu %Lu] passed [%Lu %Lu]\n", em->start, em->end, start, end); | 2001 | printk("bad extent! em: [%Lu %Lu] passed [%Lu %Lu]\n", em->start, em->len, start, len); |
1993 | err = -EIO; | 2002 | err = -EIO; |
1994 | goto out; | 2003 | goto out; |
1995 | } | 2004 | } |
2005 | |||
2006 | err = 0; | ||
2007 | spin_lock(&em_tree->lock); | ||
1996 | ret = add_extent_mapping(em_tree, em); | 2008 | ret = add_extent_mapping(em_tree, em); |
1997 | if (ret == -EEXIST) { | 2009 | if (ret == -EEXIST) { |
1998 | free_extent_map(em); | 2010 | free_extent_map(em); |
1999 | em = NULL; | 2011 | em = lookup_extent_mapping(em_tree, start, len); |
2000 | if (0 && failed_insert == 1) { | 2012 | if (!em) { |
2001 | btrfs_drop_extent_cache(inode, start, end); | ||
2002 | } | ||
2003 | failed_insert++; | ||
2004 | if (failed_insert > 5) { | ||
2005 | printk("failing to insert %Lu %Lu\n", start, end); | ||
2006 | err = -EIO; | 2013 | err = -EIO; |
2007 | goto out; | 2014 | printk("failing to insert %Lu %Lu\n", start, len); |
2008 | } | 2015 | } |
2009 | goto again; | ||
2010 | } | 2016 | } |
2011 | err = 0; | 2017 | spin_unlock(&em_tree->lock); |
2012 | out: | 2018 | out: |
2013 | btrfs_free_path(path); | 2019 | btrfs_free_path(path); |
2014 | if (trans) { | 2020 | if (trans) { |
@@ -2032,14 +2038,14 @@ static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) | |||
2032 | 2038 | ||
2033 | int btrfs_readpage(struct file *file, struct page *page) | 2039 | int btrfs_readpage(struct file *file, struct page *page) |
2034 | { | 2040 | { |
2035 | struct extent_map_tree *tree; | 2041 | struct extent_io_tree *tree; |
2036 | tree = &BTRFS_I(page->mapping->host)->extent_tree; | 2042 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2037 | return extent_read_full_page(tree, page, btrfs_get_extent); | 2043 | return extent_read_full_page(tree, page, btrfs_get_extent); |
2038 | } | 2044 | } |
2039 | 2045 | ||
2040 | static int btrfs_writepage(struct page *page, struct writeback_control *wbc) | 2046 | static int btrfs_writepage(struct page *page, struct writeback_control *wbc) |
2041 | { | 2047 | { |
2042 | struct extent_map_tree *tree; | 2048 | struct extent_io_tree *tree; |
2043 | 2049 | ||
2044 | 2050 | ||
2045 | if (current->flags & PF_MEMALLOC) { | 2051 | if (current->flags & PF_MEMALLOC) { |
@@ -2047,15 +2053,15 @@ static int btrfs_writepage(struct page *page, struct writeback_control *wbc) | |||
2047 | unlock_page(page); | 2053 | unlock_page(page); |
2048 | return 0; | 2054 | return 0; |
2049 | } | 2055 | } |
2050 | tree = &BTRFS_I(page->mapping->host)->extent_tree; | 2056 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2051 | return extent_write_full_page(tree, page, btrfs_get_extent, wbc); | 2057 | return extent_write_full_page(tree, page, btrfs_get_extent, wbc); |
2052 | } | 2058 | } |
2053 | 2059 | ||
2054 | static int btrfs_writepages(struct address_space *mapping, | 2060 | static int btrfs_writepages(struct address_space *mapping, |
2055 | struct writeback_control *wbc) | 2061 | struct writeback_control *wbc) |
2056 | { | 2062 | { |
2057 | struct extent_map_tree *tree; | 2063 | struct extent_io_tree *tree; |
2058 | tree = &BTRFS_I(mapping->host)->extent_tree; | 2064 | tree = &BTRFS_I(mapping->host)->io_tree; |
2059 | return extent_writepages(tree, mapping, btrfs_get_extent, wbc); | 2065 | return extent_writepages(tree, mapping, btrfs_get_extent, wbc); |
2060 | } | 2066 | } |
2061 | 2067 | ||
@@ -2063,19 +2069,21 @@ static int | |||
2063 | btrfs_readpages(struct file *file, struct address_space *mapping, | 2069 | btrfs_readpages(struct file *file, struct address_space *mapping, |
2064 | struct list_head *pages, unsigned nr_pages) | 2070 | struct list_head *pages, unsigned nr_pages) |
2065 | { | 2071 | { |
2066 | struct extent_map_tree *tree; | 2072 | struct extent_io_tree *tree; |
2067 | tree = &BTRFS_I(mapping->host)->extent_tree; | 2073 | tree = &BTRFS_I(mapping->host)->io_tree; |
2068 | return extent_readpages(tree, mapping, pages, nr_pages, | 2074 | return extent_readpages(tree, mapping, pages, nr_pages, |
2069 | btrfs_get_extent); | 2075 | btrfs_get_extent); |
2070 | } | 2076 | } |
2071 | 2077 | ||
2072 | static int btrfs_releasepage(struct page *page, gfp_t unused_gfp_flags) | 2078 | static int btrfs_releasepage(struct page *page, gfp_t unused_gfp_flags) |
2073 | { | 2079 | { |
2074 | struct extent_map_tree *tree; | 2080 | struct extent_io_tree *tree; |
2081 | struct extent_map_tree *map; | ||
2075 | int ret; | 2082 | int ret; |
2076 | 2083 | ||
2077 | tree = &BTRFS_I(page->mapping->host)->extent_tree; | 2084 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2078 | ret = try_release_extent_mapping(tree, page); | 2085 | map = &BTRFS_I(page->mapping->host)->extent_tree; |
2086 | ret = try_release_extent_mapping(map, tree, page); | ||
2079 | if (ret == 1) { | 2087 | if (ret == 1) { |
2080 | ClearPagePrivate(page); | 2088 | ClearPagePrivate(page); |
2081 | set_page_private(page, 0); | 2089 | set_page_private(page, 0); |
@@ -2086,9 +2094,9 @@ static int btrfs_releasepage(struct page *page, gfp_t unused_gfp_flags) | |||
2086 | 2094 | ||
2087 | static void btrfs_invalidatepage(struct page *page, unsigned long offset) | 2095 | static void btrfs_invalidatepage(struct page *page, unsigned long offset) |
2088 | { | 2096 | { |
2089 | struct extent_map_tree *tree; | 2097 | struct extent_io_tree *tree; |
2090 | 2098 | ||
2091 | tree = &BTRFS_I(page->mapping->host)->extent_tree; | 2099 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2092 | extent_invalidatepage(tree, page, offset); | 2100 | extent_invalidatepage(tree, page, offset); |
2093 | btrfs_releasepage(page, GFP_NOFS); | 2101 | btrfs_releasepage(page, GFP_NOFS); |
2094 | } | 2102 | } |
@@ -2374,7 +2382,7 @@ unsigned long btrfs_force_ra(struct address_space *mapping, | |||
2374 | int btrfs_defrag_file(struct file *file) { | 2382 | int btrfs_defrag_file(struct file *file) { |
2375 | struct inode *inode = fdentry(file)->d_inode; | 2383 | struct inode *inode = fdentry(file)->d_inode; |
2376 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2384 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2377 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 2385 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2378 | struct page *page; | 2386 | struct page *page; |
2379 | unsigned long last_index; | 2387 | unsigned long last_index; |
2380 | unsigned long ra_index = 0; | 2388 | unsigned long ra_index = 0; |
@@ -2414,13 +2422,13 @@ int btrfs_defrag_file(struct file *file) { | |||
2414 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | 2422 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; |
2415 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 2423 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
2416 | 2424 | ||
2417 | lock_extent(em_tree, page_start, page_end, GFP_NOFS); | 2425 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
2418 | delalloc_start = page_start; | 2426 | delalloc_start = page_start; |
2419 | existing_delalloc = | 2427 | existing_delalloc = |
2420 | count_range_bits(&BTRFS_I(inode)->extent_tree, | 2428 | count_range_bits(&BTRFS_I(inode)->io_tree, |
2421 | &delalloc_start, page_end, | 2429 | &delalloc_start, page_end, |
2422 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); | 2430 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); |
2423 | set_extent_delalloc(em_tree, page_start, | 2431 | set_extent_delalloc(io_tree, page_start, |
2424 | page_end, GFP_NOFS); | 2432 | page_end, GFP_NOFS); |
2425 | 2433 | ||
2426 | spin_lock(&root->fs_info->delalloc_lock); | 2434 | spin_lock(&root->fs_info->delalloc_lock); |
@@ -2428,7 +2436,7 @@ int btrfs_defrag_file(struct file *file) { | |||
2428 | existing_delalloc; | 2436 | existing_delalloc; |
2429 | spin_unlock(&root->fs_info->delalloc_lock); | 2437 | spin_unlock(&root->fs_info->delalloc_lock); |
2430 | 2438 | ||
2431 | unlock_extent(em_tree, page_start, page_end, GFP_NOFS); | 2439 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
2432 | set_page_dirty(page); | 2440 | set_page_dirty(page); |
2433 | unlock_page(page); | 2441 | unlock_page(page); |
2434 | page_cache_release(page); | 2442 | page_cache_release(page); |
@@ -2842,9 +2850,10 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2842 | inode->i_mapping->a_ops = &btrfs_aops; | 2850 | inode->i_mapping->a_ops = &btrfs_aops; |
2843 | inode->i_fop = &btrfs_file_operations; | 2851 | inode->i_fop = &btrfs_file_operations; |
2844 | inode->i_op = &btrfs_file_inode_operations; | 2852 | inode->i_op = &btrfs_file_inode_operations; |
2845 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, | 2853 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
2854 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
2846 | inode->i_mapping, GFP_NOFS); | 2855 | inode->i_mapping, GFP_NOFS); |
2847 | BTRFS_I(inode)->extent_tree.ops = &btrfs_extent_map_ops; | 2856 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
2848 | } | 2857 | } |
2849 | dir->i_sb->s_dirt = 1; | 2858 | dir->i_sb->s_dirt = 1; |
2850 | btrfs_update_inode_block_group(trans, inode); | 2859 | btrfs_update_inode_block_group(trans, inode); |
@@ -2934,7 +2943,7 @@ static struct file_operations btrfs_dir_file_operations = { | |||
2934 | #endif | 2943 | #endif |
2935 | }; | 2944 | }; |
2936 | 2945 | ||
2937 | static struct extent_map_ops btrfs_extent_map_ops = { | 2946 | static struct extent_io_ops btrfs_extent_io_ops = { |
2938 | .fill_delalloc = run_delalloc_range, | 2947 | .fill_delalloc = run_delalloc_range, |
2939 | .writepage_io_hook = btrfs_writepage_io_hook, | 2948 | .writepage_io_hook = btrfs_writepage_io_hook, |
2940 | .readpage_io_hook = btrfs_readpage_io_hook, | 2949 | .readpage_io_hook = btrfs_readpage_io_hook, |