Skip to content

Commit

Permalink
Btrfs: Fix cache_block_group to catch holes at the start of the group
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yan authored and David Woodhouse committed Sep 14, 2007
1 parent 6af858b commit 7d7d606
Showing 1 changed file with 33 additions and 28 deletions.
61 changes: 33 additions & 28 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static int cache_block_group(struct btrfs_root *root,
u64 i;
u64 last = 0;
u64 hole_size;
u64 first_free;
int found = 0;

root = root->fs_info->extent_root;
Expand All @@ -51,16 +52,22 @@ static int cache_block_group(struct btrfs_root *root,
path = btrfs_alloc_path();
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;

btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);

if (ret < 0)
return ret;

if (ret && path->slots[0] > 0)
path->slots[0]--;

while(1) {
leaf = btrfs_buffer_leaf(path->nodes[0]);
slot = path->slots[0];
Expand All @@ -71,50 +78,48 @@ static int cache_block_group(struct btrfs_root *root,
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;
}
for (i = 0; i < hole_size; i++) {
set_radix_bit(extent_radix,
last + i);
}
break;
}
}

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;
}
for (i = 0; i < hole_size; i++) {
set_radix_bit(extent_radix, last + i);
}
break;
}

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]++;
}

if (!found)
last = first_free;
if (block_group->key.objectid +
block_group->key.offset > last) {
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);
}
}
block_group->cached = 1;
err:
btrfs_free_path(path);
Expand Down

0 comments on commit 7d7d606

Please sign in to comment.