Btrfs: Fixup last found extent caching
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
037e639048
commit
0579da4280
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS = -Wall
|
CFLAGS = -g -Wall
|
||||||
headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
|
headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
|
||||||
objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o
|
objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct ctree_root {
|
||||||
struct tree_buffer *commit_root;
|
struct tree_buffer *commit_root;
|
||||||
struct ctree_root *extent_root;
|
struct ctree_root *extent_root;
|
||||||
struct key current_insert;
|
struct key current_insert;
|
||||||
|
struct key last_insert;
|
||||||
int fp;
|
int fp;
|
||||||
struct radix_tree_root cache_radix;
|
struct radix_tree_root cache_radix;
|
||||||
struct radix_tree_root pinned_radix;
|
struct radix_tree_root pinned_radix;
|
||||||
|
|
|
@ -186,6 +186,7 @@ static int __setup_root(struct ctree_root *root, struct ctree_root *extent_root,
|
||||||
root->commit_root = NULL;
|
root->commit_root = NULL;
|
||||||
root->node = read_tree_block(root, info->tree_root);
|
root->node = read_tree_block(root, info->tree_root);
|
||||||
memset(&root->current_insert, 0, sizeof(root->current_insert));
|
memset(&root->current_insert, 0, sizeof(root->current_insert));
|
||||||
|
memset(&root->last_insert, 0, sizeof(root->last_insert));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,9 +102,12 @@ int btrfs_finish_extent_commit(struct ctree_root *root)
|
||||||
ARRAY_SIZE(gang));
|
ARRAY_SIZE(gang));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
for (i = 0; i < ret; i++)
|
for (i = 0; i < ret; i++) {
|
||||||
radix_tree_delete(&extent_root->pinned_radix, gang[i]);
|
radix_tree_delete(&extent_root->pinned_radix, gang[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
extent_root->last_insert.objectid = 0;
|
||||||
|
extent_root->last_insert.offset = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +173,9 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
|
||||||
radix_tree_preload_end();
|
radix_tree_preload_end();
|
||||||
}
|
}
|
||||||
ret = del_item(extent_root, &path);
|
ret = del_item(extent_root, &path);
|
||||||
|
if (root != extent_root &&
|
||||||
|
extent_root->last_insert.objectid < blocknr)
|
||||||
|
extent_root->last_insert.objectid = blocknr;
|
||||||
if (ret)
|
if (ret)
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
@ -261,8 +267,11 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
|
||||||
int start_found;
|
int start_found;
|
||||||
struct leaf *l;
|
struct leaf *l;
|
||||||
struct ctree_root * root = orig_root->extent_root;
|
struct ctree_root * root = orig_root->extent_root;
|
||||||
int total_needed = num_blocks + MAX_LEVEL * 3;
|
int total_needed = num_blocks;
|
||||||
|
|
||||||
|
total_needed += (node_level(root->node->node.header.flags) + 1) * 3;
|
||||||
|
if (root->last_insert.objectid > search_start)
|
||||||
|
search_start = root->last_insert.objectid;
|
||||||
check_failed:
|
check_failed:
|
||||||
init_path(&path);
|
init_path(&path);
|
||||||
ins->objectid = search_start;
|
ins->objectid = search_start;
|
||||||
|
@ -273,6 +282,9 @@ check_failed:
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (path.slots[0] > 0)
|
||||||
|
path.slots[0]--;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
l = &path.nodes[0]->leaf;
|
l = &path.nodes[0]->leaf;
|
||||||
slot = path.slots[0];
|
slot = path.slots[0];
|
||||||
|
@ -293,31 +305,21 @@ check_failed:
|
||||||
ins->offset = (u64)-1;
|
ins->offset = (u64)-1;
|
||||||
goto check_pending;
|
goto check_pending;
|
||||||
}
|
}
|
||||||
if (slot == 0) {
|
|
||||||
int last_slot = l->header.nritems - 1;
|
|
||||||
u64 span = l->items[last_slot].key.objectid;
|
|
||||||
span -= l->items[slot].key.objectid;
|
|
||||||
if (span + total_needed > last_slot - slot) {
|
|
||||||
path.slots[0] = last_slot + 1;
|
|
||||||
key = &l->items[last_slot].key;
|
|
||||||
last_block = key->objectid + key->offset;
|
|
||||||
start_found = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key = &l->items[slot].key;
|
key = &l->items[slot].key;
|
||||||
if (key->objectid >= search_start) {
|
if (key->objectid >= search_start) {
|
||||||
if (start_found) {
|
if (start_found) {
|
||||||
|
if (last_block < search_start)
|
||||||
|
last_block = search_start;
|
||||||
hole_size = key->objectid - last_block;
|
hole_size = key->objectid - last_block;
|
||||||
if (hole_size > total_needed) {
|
if (hole_size > total_needed) {
|
||||||
ins->objectid = last_block;
|
ins->objectid = last_block;
|
||||||
ins->offset = hole_size;
|
ins->offset = hole_size;
|
||||||
goto check_pending;
|
goto check_pending;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
start_found = 1;
|
|
||||||
last_block = key->objectid + key->offset;
|
|
||||||
}
|
}
|
||||||
|
start_found = 1;
|
||||||
|
last_block = key->objectid + key->offset;
|
||||||
path.slots[0]++;
|
path.slots[0]++;
|
||||||
}
|
}
|
||||||
// FIXME -ENOSPC
|
// FIXME -ENOSPC
|
||||||
|
@ -335,9 +337,10 @@ check_pending:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BUG_ON(root->current_insert.offset);
|
BUG_ON(root->current_insert.offset);
|
||||||
root->current_insert.offset = total_needed;
|
root->current_insert.offset = total_needed - num_blocks;
|
||||||
root->current_insert.objectid = ins->objectid + num_blocks;
|
root->current_insert.objectid = ins->objectid + num_blocks;
|
||||||
root->current_insert.flags = 0;
|
root->current_insert.flags = 0;
|
||||||
|
root->last_insert.objectid = ins->objectid;
|
||||||
ins->offset = num_blocks;
|
ins->offset = num_blocks;
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
|
|
Loading…
Reference in New Issue