aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-07 16:15:30 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-07 16:15:30 -0500
commit0579da4280812f34f382fb0f8004d7b0219e7a33 (patch)
tree817da9340020ac01849b610b90f6803d81bc97d3 /fs/btrfs
parent037e6390488af8ab96137e1e5cccc15ad14ef887 (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/Makefile2
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/extent-tree.c39
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
2CC=gcc 2CC=gcc
3CFLAGS = -Wall 3CFLAGS = -g -Wall
4headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h 4headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
5objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o 5objects = 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;
266check_failed: 275check_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;
343error: 346error: