[btrfs-devel][patch]Cache blocks in the hole at beginning of a block group

Yan Zheng yanzheng at 21cn.com
Wed Sep 12 01:49:30 PDT 2007


2007/9/12, Chris Mason <chris.mason at oracle.com>:
> Thanks, you've definitely found a bug in the current code, but I'm
> afraid we can't assume the start of the block group is free.  There
> could be an extent allocated in the last block group that extends into
> the current one.
>

Thanks for comment.

I feel if there are extent items across block group boundary,  we also
can't guarantee start of the block group is free in other tests (in
cache_block_group) . In addition, the subtraction operation in codes
like:
--------------------------------------------------------
if (found) {
    hole_size = block_group->key.objectid +
                         block_group->key.offset - last;
}
-------------------------------------------------------
may overflow. The overflow bug can  easily produce by adding a extent
item across boundary of block group 0 and block group 1.


here is the new patch . it finds the start of free block in a block
group by checking the first extent item (the one found by
btrfs_search_slot directly, it should belong to preceding block group
except for the first block group).  it also add check for overflow.

Regards
YZ

diff -r 9cb5f0f5c713 extent-tree.c
--- a/extent-tree.c	Thu Aug 30 12:16:51 2007 -0400
+++ b/extent-tree.c	Wed Sep 12 13:08:17 2007 +0800
@@ -39,6 +39,7 @@ static int cache_block_group(struct btrf
 	u64 i;
 	u64 last = 0;
 	u64 hole_size;
+	u64 first_free;
 	int found = 0;

 	root = root->fs_info->extent_root;
@@ -52,6 +53,7 @@ static int cache_block_group(struct btrf
 	if (!path)
 		return -ENOMEM;
 	path->reada = 2;
+	first_free = block_group->key.objectid;
 	key.objectid = block_group->key.objectid;
 	key.flags = 0;
 	key.offset = 0;
@@ -71,13 +73,13 @@ static int cache_block_group(struct btrf
 			if (ret == 0) {
 				continue;
 			} else {
-				if (found) {
-					hole_size = block_group->key.objectid +
-						block_group->key.offset - last;
-				} else {
-					last = block_group->key.objectid;
-					hole_size = block_group->key.offset;
-				}
+				if (!found)
+					last = first_free;
+				if (block_group->key.objectid +
+				    block_group->key.offset < last)
+					break;
+				hole_size = block_group->key.objectid +
+					block_group->key.offset - last;
 				for (i = 0; i < hole_size; i++) {
 					set_radix_bit(extent_radix,
 						      last + i);
@@ -86,15 +88,20 @@ static int cache_block_group(struct btrf
 			}
 		}
 		btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
+		if (key.objectid < block_group->key.objectid) {
+			if (key.objectid + key.offset > first_free)
+				first_free = key.objectid + key.offset;
+			goto next;
+		}
 		if (key.objectid >= block_group->key.objectid +
 		    block_group->key.offset) {
-			if (found) {
-				hole_size = block_group->key.objectid +
-					block_group->key.offset - last;
-			} else {
-				last = block_group->key.objectid;
-				hole_size = block_group->key.offset;
-			}
+			if (!found)
+				last = first_free;
+			if (block_group->key.objectid +
+			    block_group->key.offset < last)	
+				break;
+			hole_size = block_group->key.objectid +
+				block_group->key.offset - last;
 			for (i = 0; i < hole_size; i++) {
 				set_radix_bit(extent_radix, last + i);
 			}
@@ -102,16 +109,16 @@ static int cache_block_group(struct btrf
 		}
 		if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) {
 			if (!found) {
-				last = key.objectid + key.offset;
+				last = first_free;
 				found = 1;
-			} else {
-				hole_size = key.objectid - last;
-				for (i = 0; i < hole_size; i++) {
-					set_radix_bit(extent_radix, last + i);
-				}
-				last = key.objectid + key.offset;
-			}
-		}
+			}
+			hole_size = key.objectid - last;
+			for (i = 0; i < hole_size; i++) {
+				set_radix_bit(extent_radix, last + i);
+			}
+			last = key.objectid + key.offset;
+		}
+next:
 		path->slots[0]++;
 	}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: extent-tree.patch
Type: text/x-patch
Size: 2673 bytes
Desc: not available
Url : http://oss.oracle.com/pipermail/btrfs-devel/attachments/20070912/330807f3/extent-tree.bin


More information about the Btrfs-devel mailing list