[Btrfs-devel][PATCH]Fix inline extent handling in btrfs_get_extent

Yan Zheng yanzheng at 21cn.com
Sun Oct 28 17:21:37 PDT 2007


Hello,

This patch contain following fix:
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)

Regards
YZ
---
diff -r a1bde8e797ff inode.c
--- a/inode.c	Thu Oct 25 15:49:25 2007 -0400
+++ b/inode.c	Sun Oct 28 21:32:02 2007 +0800
@@ -1597,7 +1597,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;
@@ -1611,28 +1611,34 @@ again:
 			goto not_found_em;
 		}

-		extent_offset = (page->index << PAGE_CACHE_SHIFT) -
-			extent_start;
-		ptr = btrfs_file_extent_inline_start(item) + extent_offset;
-		map = kmap(page);
+		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 + 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);
-		/*
-		memset(map + page_offset + copy_size, 0,
-		       PAGE_CACHE_SIZE - copy_size - page_offset);
-		       */
+		
+		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);
+		}
+
 		flush_dcache_page(page);
 		kunmap(page);
 		set_extent_uptodate(em_tree, em->start, em->end, GFP_NOFS);



More information about the Btrfs-devel mailing list