Btrfs: fix oops after block group lookup
Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/TODO b/fs/btrfs/TODO
index 61d25b5..d9b6d38 100644
--- a/fs/btrfs/TODO
+++ b/fs/btrfs/TODO
@@ -16,6 +16,5 @@
* Use relocation to try and fix write errors
* Make allocator much smarter
* xattrs (directory streams for regular files)
-* fsck
* Scrub & defrag
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5ab25a0..4e136b7 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -998,6 +998,9 @@
btrfs_item_offset((leaf)->items + (slot))))
/* extent-tree.c */
+struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
+ btrfs_fs_info *info,
+ u64 blocknr);
struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
struct btrfs_block_group_cache
*hint, u64 search_start,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 645a422..f509ffa 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -135,9 +135,9 @@
return 0;
}
-static struct btrfs_block_group_cache *lookup_block_group(struct
- btrfs_fs_info *info,
- u64 blocknr)
+struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
+ btrfs_fs_info *info,
+ u64 blocknr)
{
struct btrfs_block_group_cache *block_group;
int ret;
@@ -208,7 +208,8 @@
return max(cache->last_alloc, search_start);
new_group:
- cache = lookup_block_group(root->fs_info, last + cache->key.offset - 1);
+ cache = btrfs_lookup_block_group(root->fs_info,
+ last + cache->key.offset - 1);
if (!cache) {
return max((*cache_ret)->last_alloc, search_start);
}
@@ -250,7 +251,7 @@
if (search_start) {
struct btrfs_block_group_cache *shint;
- shint = lookup_block_group(info, search_start);
+ shint = btrfs_lookup_block_group(info, search_start);
if (shint->data == data) {
used = btrfs_block_group_used(&shint->item);
if (used + shint->pinned <
@@ -576,7 +577,7 @@
int ret;
while(total) {
- cache = lookup_block_group(info, blocknr);
+ cache = btrfs_lookup_block_group(info, blocknr);
if (!cache) {
printk(KERN_CRIT "blocknr %Lu lookup failed\n",
blocknr);
@@ -677,8 +678,8 @@
first = gang[0];
for (i = 0; i < ret; i++) {
clear_radix_bit(pinned_radix, gang[i]);
- block_group = lookup_block_group(root->fs_info,
- gang[i]);
+ block_group = btrfs_lookup_block_group(root->fs_info,
+ gang[i]);
if (block_group) {
WARN_ON(block_group->pinned == 0);
block_group->pinned--;
@@ -751,7 +752,8 @@
err = set_radix_bit(&root->fs_info->pinned_radix, blocknr);
if (!err) {
struct btrfs_block_group_cache *cache;
- cache = lookup_block_group(root->fs_info, blocknr);
+ cache = btrfs_lookup_block_group(root->fs_info,
+ blocknr);
if (cache)
cache->pinned++;
}
@@ -851,7 +853,8 @@
for (i = 0; i < ret; i++) {
wret = set_radix_bit(pinned_radix, gang[i]);
if (wret == 0) {
- cache = lookup_block_group(extent_root->fs_info,
+ cache =
+ btrfs_lookup_block_group(extent_root->fs_info,
gang[i]);
if (cache)
cache->pinned++;
@@ -938,7 +941,7 @@
if (search_end == (u64)-1)
search_end = btrfs_super_total_blocks(info->disk_super);
if (hint_block) {
- block_group = lookup_block_group(info, hint_block);
+ block_group = btrfs_lookup_block_group(info, hint_block);
block_group = btrfs_find_block_group(root, block_group,
hint_block, data, 1);
} else {
@@ -1118,7 +1121,7 @@
info->extent_tree_prealloc_nr = total_found;
}
if (!data) {
- block_group = lookup_block_group(info, ins->objectid);
+ block_group = btrfs_lookup_block_group(info, ins->objectid);
if (block_group) {
if (fill_prealloc)
block_group->last_prealloc =
@@ -1143,7 +1146,7 @@
else
wrapped = 1;
}
- block_group = lookup_block_group(info, search_start);
+ block_group = btrfs_lookup_block_group(info, search_start);
cond_resched();
if (!full_scan)
block_group = btrfs_find_block_group(root, block_group,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 2b24a5a..9749090 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -62,7 +62,6 @@
struct btrfs_inode_item *inode_item;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_key location;
- struct btrfs_block_group_cache *alloc_group;
u64 alloc_group_block;
int ret;
@@ -95,11 +94,8 @@
inode->i_blocks = btrfs_inode_nblocks(inode_item);
inode->i_generation = btrfs_inode_generation(inode_item);
alloc_group_block = btrfs_inode_block_group(inode_item);
- ret = radix_tree_gang_lookup(&root->fs_info->block_group_radix,
- (void **)&alloc_group,
- alloc_group_block, 1);
- BUG_ON(!ret);
- BTRFS_I(inode)->block_group = alloc_group;
+ BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info,
+ alloc_group_block);
btrfs_free_path(path);
inode_item = NULL;