Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5276aeda authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse
Browse files

Btrfs: fix oops after block group lookup

parent 0cf6c620
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -998,6 +998,9 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh)
	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,
+16 −13
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ printk("cache block group %Lu\n", block_group->key.objectid);
	return 0;
}

static struct btrfs_block_group_cache *lookup_block_group(struct
struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
							 btrfs_fs_info *info,
							 u64 blocknr)
{
@@ -208,7 +208,8 @@ static u64 find_search_start(struct btrfs_root *root,
	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 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,

	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 @@ static int update_block_group(struct btrfs_trans_handle *trans,
	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,7 +678,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
			first = gang[0];
		for (i = 0; i < ret; i++) {
			clear_radix_bit(pinned_radix, gang[i]);
			block_group = lookup_block_group(root->fs_info,
			block_group = btrfs_lookup_block_group(root->fs_info,
							       gang[i]);
			if (block_group) {
				WARN_ON(block_group->pinned == 0);
@@ -751,7 +752,8 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
		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 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
		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 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
	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 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
		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 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
		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,
+2 −6
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ static void btrfs_read_locked_inode(struct inode *inode)
	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 @@ static void btrfs_read_locked_inode(struct inode *inode)
	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;