diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-07 16:15:30 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-07 16:15:30 -0500 |
commit | 0579da4280812f34f382fb0f8004d7b0219e7a33 (patch) | |
tree | 817da9340020ac01849b610b90f6803d81bc97d3 /fs/btrfs | |
parent | 037e6390488af8ab96137e1e5cccc15ad14ef887 (diff) |
Btrfs: Fixup last found extent caching
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/Makefile | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 39 |
4 files changed, 24 insertions, 19 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index d92d08dde0ff..ae7f4c00c39c 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | CC=gcc | 2 | CC=gcc |
3 | CFLAGS = -Wall | 3 | CFLAGS = -g -Wall |
4 | headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h | 4 | headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h |
5 | objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o | 5 | objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o |
6 | 6 | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 4a7bc4e6e747..518326fa3694 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -54,6 +54,7 @@ struct ctree_root { | |||
54 | struct tree_buffer *commit_root; | 54 | struct tree_buffer *commit_root; |
55 | struct ctree_root *extent_root; | 55 | struct ctree_root *extent_root; |
56 | struct key current_insert; | 56 | struct key current_insert; |
57 | struct key last_insert; | ||
57 | int fp; | 58 | int fp; |
58 | struct radix_tree_root cache_radix; | 59 | struct radix_tree_root cache_radix; |
59 | struct radix_tree_root pinned_radix; | 60 | struct radix_tree_root pinned_radix; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2fe31c3508c1..997cc578a185 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -186,6 +186,7 @@ static int __setup_root(struct ctree_root *root, struct ctree_root *extent_root, | |||
186 | root->commit_root = NULL; | 186 | root->commit_root = NULL; |
187 | root->node = read_tree_block(root, info->tree_root); | 187 | root->node = read_tree_block(root, info->tree_root); |
188 | memset(&root->current_insert, 0, sizeof(root->current_insert)); | 188 | memset(&root->current_insert, 0, sizeof(root->current_insert)); |
189 | memset(&root->last_insert, 0, sizeof(root->last_insert)); | ||
189 | return 0; | 190 | return 0; |
190 | } | 191 | } |
191 | 192 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 8a2b8aaf9b86..dd11532cb2f6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -102,9 +102,12 @@ int btrfs_finish_extent_commit(struct ctree_root *root) | |||
102 | ARRAY_SIZE(gang)); | 102 | ARRAY_SIZE(gang)); |
103 | if (!ret) | 103 | if (!ret) |
104 | break; | 104 | break; |
105 | for (i = 0; i < ret; i++) | 105 | for (i = 0; i < ret; i++) { |
106 | radix_tree_delete(&extent_root->pinned_radix, gang[i]); | 106 | radix_tree_delete(&extent_root->pinned_radix, gang[i]); |
107 | } | ||
107 | } | 108 | } |
109 | extent_root->last_insert.objectid = 0; | ||
110 | extent_root->last_insert.offset = 0; | ||
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
110 | 113 | ||
@@ -170,6 +173,9 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks) | |||
170 | radix_tree_preload_end(); | 173 | radix_tree_preload_end(); |
171 | } | 174 | } |
172 | ret = del_item(extent_root, &path); | 175 | ret = del_item(extent_root, &path); |
176 | if (root != extent_root && | ||
177 | extent_root->last_insert.objectid < blocknr) | ||
178 | extent_root->last_insert.objectid = blocknr; | ||
173 | if (ret) | 179 | if (ret) |
174 | BUG(); | 180 | BUG(); |
175 | } | 181 | } |
@@ -261,8 +267,11 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks, | |||
261 | int start_found; | 267 | int start_found; |
262 | struct leaf *l; | 268 | struct leaf *l; |
263 | struct ctree_root * root = orig_root->extent_root; | 269 | struct ctree_root * root = orig_root->extent_root; |
264 | int total_needed = num_blocks + MAX_LEVEL * 3; | 270 | int total_needed = num_blocks; |
265 | 271 | ||
272 | total_needed += (node_level(root->node->node.header.flags) + 1) * 3; | ||
273 | if (root->last_insert.objectid > search_start) | ||
274 | search_start = root->last_insert.objectid; | ||
266 | check_failed: | 275 | check_failed: |
267 | init_path(&path); | 276 | init_path(&path); |
268 | ins->objectid = search_start; | 277 | ins->objectid = search_start; |
@@ -273,6 +282,9 @@ check_failed: | |||
273 | if (ret < 0) | 282 | if (ret < 0) |
274 | goto error; | 283 | goto error; |
275 | 284 | ||
285 | if (path.slots[0] > 0) | ||
286 | path.slots[0]--; | ||
287 | |||
276 | while (1) { | 288 | while (1) { |
277 | l = &path.nodes[0]->leaf; | 289 | l = &path.nodes[0]->leaf; |
278 | slot = path.slots[0]; | 290 | slot = path.slots[0]; |
@@ -293,31 +305,21 @@ check_failed: | |||
293 | ins->offset = (u64)-1; | 305 | ins->offset = (u64)-1; |
294 | goto check_pending; | 306 | goto check_pending; |
295 | } | 307 | } |
296 | if (slot == 0) { | ||
297 | int last_slot = l->header.nritems - 1; | ||
298 | u64 span = l->items[last_slot].key.objectid; | ||
299 | span -= l->items[slot].key.objectid; | ||
300 | if (span + total_needed > last_slot - slot) { | ||
301 | path.slots[0] = last_slot + 1; | ||
302 | key = &l->items[last_slot].key; | ||
303 | last_block = key->objectid + key->offset; | ||
304 | start_found = 1; | ||
305 | continue; | ||
306 | } | ||
307 | } | ||
308 | key = &l->items[slot].key; | 308 | key = &l->items[slot].key; |
309 | if (key->objectid >= search_start) { | 309 | if (key->objectid >= search_start) { |
310 | if (start_found) { | 310 | if (start_found) { |
311 | if (last_block < search_start) | ||
312 | last_block = search_start; | ||
311 | hole_size = key->objectid - last_block; | 313 | hole_size = key->objectid - last_block; |
312 | if (hole_size > total_needed) { | 314 | if (hole_size > total_needed) { |
313 | ins->objectid = last_block; | 315 | ins->objectid = last_block; |
314 | ins->offset = hole_size; | 316 | ins->offset = hole_size; |
315 | goto check_pending; | 317 | goto check_pending; |
316 | } | 318 | } |
317 | } else | 319 | } |
318 | start_found = 1; | ||
319 | last_block = key->objectid + key->offset; | ||
320 | } | 320 | } |
321 | start_found = 1; | ||
322 | last_block = key->objectid + key->offset; | ||
321 | path.slots[0]++; | 323 | path.slots[0]++; |
322 | } | 324 | } |
323 | // FIXME -ENOSPC | 325 | // FIXME -ENOSPC |
@@ -335,9 +337,10 @@ check_pending: | |||
335 | } | 337 | } |
336 | } | 338 | } |
337 | BUG_ON(root->current_insert.offset); | 339 | BUG_ON(root->current_insert.offset); |
338 | root->current_insert.offset = total_needed; | 340 | root->current_insert.offset = total_needed - num_blocks; |
339 | root->current_insert.objectid = ins->objectid + num_blocks; | 341 | root->current_insert.objectid = ins->objectid + num_blocks; |
340 | root->current_insert.flags = 0; | 342 | root->current_insert.flags = 0; |
343 | root->last_insert.objectid = ins->objectid; | ||
341 | ins->offset = num_blocks; | 344 | ins->offset = num_blocks; |
342 | return 0; | 345 | return 0; |
343 | error: | 346 | error: |