aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorYan <yanzheng@21cn.com>2007-09-14 16:15:28 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-09-14 16:15:28 -0400
commit7d7d6068bee9d8004ea7cc8a2ebda2c99a57caec (patch)
tree399cf89116a0110d74ea4c26562bd7aef380734a /fs/btrfs/extent-tree.c
parent6af858b24c0c4e91ce0b40b5dd5fdfc1fe2dda70 (diff)
Btrfs: Fix cache_block_group to catch holes at the start of the group
Cache block group was overly complex and missed free blocks at the very start of the group. This patch simplifies things significantly. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index b074ad1416dd..9151850266b0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -39,6 +39,7 @@ static int cache_block_group(struct btrfs_root *root,
39 u64 i; 39 u64 i;
40 u64 last = 0; 40 u64 last = 0;
41 u64 hole_size; 41 u64 hole_size;
42 u64 first_free;
42 int found = 0; 43 int found = 0;
43 44
44 root = root->fs_info->extent_root; 45 root = root->fs_info->extent_root;
@@ -51,16 +52,22 @@ static int cache_block_group(struct btrfs_root *root,
51 path = btrfs_alloc_path(); 52 path = btrfs_alloc_path();
52 if (!path) 53 if (!path)
53 return -ENOMEM; 54 return -ENOMEM;
55
54 path->reada = 2; 56 path->reada = 2;
57 first_free = block_group->key.objectid;
55 key.objectid = block_group->key.objectid; 58 key.objectid = block_group->key.objectid;
56 key.flags = 0; 59 key.flags = 0;
57 key.offset = 0; 60 key.offset = 0;
61
58 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 62 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
59 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 63 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
64
60 if (ret < 0) 65 if (ret < 0)
61 return ret; 66 return ret;
67
62 if (ret && path->slots[0] > 0) 68 if (ret && path->slots[0] > 0)
63 path->slots[0]--; 69 path->slots[0]--;
70
64 while(1) { 71 while(1) {
65 leaf = btrfs_buffer_leaf(path->nodes[0]); 72 leaf = btrfs_buffer_leaf(path->nodes[0]);
66 slot = path->slots[0]; 73 slot = path->slots[0];
@@ -71,50 +78,48 @@ static int cache_block_group(struct btrfs_root *root,
71 if (ret == 0) { 78 if (ret == 0) {
72 continue; 79 continue;
73 } else { 80 } else {
74 if (found) {
75 hole_size = block_group->key.objectid +
76 block_group->key.offset - last;
77 } else {
78 last = block_group->key.objectid;
79 hole_size = block_group->key.offset;
80 }
81 for (i = 0; i < hole_size; i++) {
82 set_radix_bit(extent_radix,
83 last + i);
84 }
85 break; 81 break;
86 } 82 }
87 } 83 }
84
88 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); 85 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
86 if (key.objectid < block_group->key.objectid) {
87 if (key.objectid + key.offset > first_free)
88 first_free = key.objectid + key.offset;
89 goto next;
90 }
91
89 if (key.objectid >= block_group->key.objectid + 92 if (key.objectid >= block_group->key.objectid +
90 block_group->key.offset) { 93 block_group->key.offset) {
91 if (found) {
92 hole_size = block_group->key.objectid +
93 block_group->key.offset - last;
94 } else {
95 last = block_group->key.objectid;
96 hole_size = block_group->key.offset;
97 }
98 for (i = 0; i < hole_size; i++) {
99 set_radix_bit(extent_radix, last + i);
100 }
101 break; 94 break;
102 } 95 }
96
103 if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) { 97 if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) {
104 if (!found) { 98 if (!found) {
105 last = key.objectid + key.offset; 99 last = first_free;
106 found = 1; 100 found = 1;
107 } else {
108 hole_size = key.objectid - last;
109 for (i = 0; i < hole_size; i++) {
110 set_radix_bit(extent_radix, last + i);
111 }
112 last = key.objectid + key.offset;
113 } 101 }
102 hole_size = key.objectid - last;
103 for (i = 0; i < hole_size; i++) {
104 set_radix_bit(extent_radix, last + i);
105 }
106 last = key.objectid + key.offset;
114 } 107 }
108next:
115 path->slots[0]++; 109 path->slots[0]++;
116 } 110 }
117 111
112 if (!found)
113 last = first_free;
114 if (block_group->key.objectid +
115 block_group->key.offset > last) {
116 hole_size = block_group->key.objectid +
117 block_group->key.offset - last;
118 for (i = 0; i < hole_size; i++) {
119 set_radix_bit(extent_radix,
120 last + i);
121 }
122 }
118 block_group->cached = 1; 123 block_group->cached = 1;
119err: 124err:
120 btrfs_free_path(path); 125 btrfs_free_path(path);