Fix inline extent handling in btrfs_get_extent
authorYan <yanzheng@21cn.com>
Mon, 29 Oct 2007 15:41:07 +0000 (11:41 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:57 +0000 (11:03 -0400)
1.  Reorder kmap and the test for  'page != NULL'
2.  Zero-fill rest area of a block when inline extent isn't big enough.
3.  Do not insert extent_map into the map tree when page == NULL.
(If insert the extent_map into the map tree,  subsequent read requests
will find it in the map tree directly and the corresponding inline
extent data aren't copied into page by the the get_extent function.
extent_read_full_page can't handle that case)

Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/inode.c

index c88f13a885555d57baebb6785163ad556528e31b..0ba1cdbdf112bd18824012b332e754805b7967f8 100644 (file)
@@ -1596,8 +1596,7 @@ again:
 
                size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf,
                                                    path->slots[0]));
-
-               extent_end = (extent_start + size) |
+               extent_end = (extent_start + size - 1) |
                        ((u64)root->sectorsize - 1);
                if (start < extent_start || start >= extent_end) {
                        em->start = start;
@@ -1610,29 +1609,32 @@ again:
                        }
                        goto not_found_em;
                }
+               em->block_start = EXTENT_MAP_INLINE;
+               em->block_end = EXTENT_MAP_INLINE;
+
+               if (!page) {
+                       em->start = extent_start;
+                       em->end = extent_start + size - 1;
+                       goto out;
+               }
 
                extent_offset = (page->index << PAGE_CACHE_SHIFT) -
-                       extent_start;
-               ptr = btrfs_file_extent_inline_start(item) + extent_offset;
-               map = kmap(page);
+                       extent_start + page_offset;
                copy_size = min_t(u64, PAGE_CACHE_SIZE - page_offset,
                                size - extent_offset);
-
-               em->block_start = EXTENT_MAP_INLINE;
-               em->block_end = EXTENT_MAP_INLINE;
                em->start = extent_start + extent_offset;
                em->end = (em->start + copy_size -1) |
                        ((u64)root->sectorsize -1);
-
-               if (!page) {
-                       goto insert;
+               map = kmap(page);
+               ptr = btrfs_file_extent_inline_start(item) + extent_offset;
+               read_extent_buffer(leaf, map + page_offset, ptr, copy_size);
+               
+               if (em->start + copy_size <= em->end) {
+                       size = min_t(u64, em->end + 1 - em->start,
+                               PAGE_CACHE_SIZE - page_offset) - copy_size;
+                       memset(map + page_offset + copy_size, 0, size);
                }
 
-               read_extent_buffer(leaf, map + page_offset, ptr, copy_size);
-               /*
-               memset(map + page_offset + copy_size, 0,
-                      PAGE_CACHE_SIZE - copy_size - page_offset);
-                      */
                flush_dcache_page(page);
                kunmap(page);
                set_extent_uptodate(em_tree, em->start, em->end, GFP_NOFS);