aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-11 21:33:38 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-11 21:33:38 -0400
commit5276aedab0baacfb3c5483208b8be85a8416bd5f (patch)
treed9370bef282b75e0e2b81ab1f74c146fd308cfd6 /fs/btrfs
parent0cf6c620176a294bdf1bedddc492f6ae857e0019 (diff)
Btrfs: fix oops after block group lookup
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/TODO1
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/extent-tree.c29
-rw-r--r--fs/btrfs/super.c8
4 files changed, 21 insertions, 20 deletions
diff --git a/fs/btrfs/TODO b/fs/btrfs/TODO
index 61d25b5de287..d9b6d38c603a 100644
--- a/fs/btrfs/TODO
+++ b/fs/btrfs/TODO
@@ -16,6 +16,5 @@
16* Use relocation to try and fix write errors 16* Use relocation to try and fix write errors
17* Make allocator much smarter 17* Make allocator much smarter
18* xattrs (directory streams for regular files) 18* xattrs (directory streams for regular files)
19* fsck
20* Scrub & defrag 19* Scrub & defrag
21 20
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5ab25a0cb16a..4e136b7b03ae 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -998,6 +998,9 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh)
998 btrfs_item_offset((leaf)->items + (slot)))) 998 btrfs_item_offset((leaf)->items + (slot))))
999 999
1000/* extent-tree.c */ 1000/* extent-tree.c */
1001struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
1002 btrfs_fs_info *info,
1003 u64 blocknr);
1001struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, 1004struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
1002 struct btrfs_block_group_cache 1005 struct btrfs_block_group_cache
1003 *hint, u64 search_start, 1006 *hint, u64 search_start,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 645a4228bfe2..f509ffa38d03 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -135,9 +135,9 @@ printk("cache block group %Lu\n", block_group->key.objectid);
135 return 0; 135 return 0;
136} 136}
137 137
138static struct btrfs_block_group_cache *lookup_block_group(struct 138struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
139 btrfs_fs_info *info, 139 btrfs_fs_info *info,
140 u64 blocknr) 140 u64 blocknr)
141{ 141{
142 struct btrfs_block_group_cache *block_group; 142 struct btrfs_block_group_cache *block_group;
143 int ret; 143 int ret;
@@ -208,7 +208,8 @@ out:
208 return max(cache->last_alloc, search_start); 208 return max(cache->last_alloc, search_start);
209 209
210new_group: 210new_group:
211 cache = lookup_block_group(root->fs_info, last + cache->key.offset - 1); 211 cache = btrfs_lookup_block_group(root->fs_info,
212 last + cache->key.offset - 1);
212 if (!cache) { 213 if (!cache) {
213 return max((*cache_ret)->last_alloc, search_start); 214 return max((*cache_ret)->last_alloc, search_start);
214 } 215 }
@@ -250,7 +251,7 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
250 251
251 if (search_start) { 252 if (search_start) {
252 struct btrfs_block_group_cache *shint; 253 struct btrfs_block_group_cache *shint;
253 shint = lookup_block_group(info, search_start); 254 shint = btrfs_lookup_block_group(info, search_start);
254 if (shint->data == data) { 255 if (shint->data == data) {
255 used = btrfs_block_group_used(&shint->item); 256 used = btrfs_block_group_used(&shint->item);
256 if (used + shint->pinned < 257 if (used + shint->pinned <
@@ -576,7 +577,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
576 int ret; 577 int ret;
577 578
578 while(total) { 579 while(total) {
579 cache = lookup_block_group(info, blocknr); 580 cache = btrfs_lookup_block_group(info, blocknr);
580 if (!cache) { 581 if (!cache) {
581 printk(KERN_CRIT "blocknr %Lu lookup failed\n", 582 printk(KERN_CRIT "blocknr %Lu lookup failed\n",
582 blocknr); 583 blocknr);
@@ -677,8 +678,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
677 first = gang[0]; 678 first = gang[0];
678 for (i = 0; i < ret; i++) { 679 for (i = 0; i < ret; i++) {
679 clear_radix_bit(pinned_radix, gang[i]); 680 clear_radix_bit(pinned_radix, gang[i]);
680 block_group = lookup_block_group(root->fs_info, 681 block_group = btrfs_lookup_block_group(root->fs_info,
681 gang[i]); 682 gang[i]);
682 if (block_group) { 683 if (block_group) {
683 WARN_ON(block_group->pinned == 0); 684 WARN_ON(block_group->pinned == 0);
684 block_group->pinned--; 685 block_group->pinned--;
@@ -751,7 +752,8 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
751 err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); 752 err = set_radix_bit(&root->fs_info->pinned_radix, blocknr);
752 if (!err) { 753 if (!err) {
753 struct btrfs_block_group_cache *cache; 754 struct btrfs_block_group_cache *cache;
754 cache = lookup_block_group(root->fs_info, blocknr); 755 cache = btrfs_lookup_block_group(root->fs_info,
756 blocknr);
755 if (cache) 757 if (cache)
756 cache->pinned++; 758 cache->pinned++;
757 } 759 }
@@ -851,7 +853,8 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
851 for (i = 0; i < ret; i++) { 853 for (i = 0; i < ret; i++) {
852 wret = set_radix_bit(pinned_radix, gang[i]); 854 wret = set_radix_bit(pinned_radix, gang[i]);
853 if (wret == 0) { 855 if (wret == 0) {
854 cache = lookup_block_group(extent_root->fs_info, 856 cache =
857 btrfs_lookup_block_group(extent_root->fs_info,
855 gang[i]); 858 gang[i]);
856 if (cache) 859 if (cache)
857 cache->pinned++; 860 cache->pinned++;
@@ -938,7 +941,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
938 if (search_end == (u64)-1) 941 if (search_end == (u64)-1)
939 search_end = btrfs_super_total_blocks(info->disk_super); 942 search_end = btrfs_super_total_blocks(info->disk_super);
940 if (hint_block) { 943 if (hint_block) {
941 block_group = lookup_block_group(info, hint_block); 944 block_group = btrfs_lookup_block_group(info, hint_block);
942 block_group = btrfs_find_block_group(root, block_group, 945 block_group = btrfs_find_block_group(root, block_group,
943 hint_block, data, 1); 946 hint_block, data, 1);
944 } else { 947 } else {
@@ -1118,7 +1121,7 @@ check_pending:
1118 info->extent_tree_prealloc_nr = total_found; 1121 info->extent_tree_prealloc_nr = total_found;
1119 } 1122 }
1120 if (!data) { 1123 if (!data) {
1121 block_group = lookup_block_group(info, ins->objectid); 1124 block_group = btrfs_lookup_block_group(info, ins->objectid);
1122 if (block_group) { 1125 if (block_group) {
1123 if (fill_prealloc) 1126 if (fill_prealloc)
1124 block_group->last_prealloc = 1127 block_group->last_prealloc =
@@ -1143,7 +1146,7 @@ new_group:
1143 else 1146 else
1144 wrapped = 1; 1147 wrapped = 1;
1145 } 1148 }
1146 block_group = lookup_block_group(info, search_start); 1149 block_group = btrfs_lookup_block_group(info, search_start);
1147 cond_resched(); 1150 cond_resched();
1148 if (!full_scan) 1151 if (!full_scan)
1149 block_group = btrfs_find_block_group(root, block_group, 1152 block_group = btrfs_find_block_group(root, block_group,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 2b24a5a2be63..9749090cfbb8 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -62,7 +62,6 @@ static void btrfs_read_locked_inode(struct inode *inode)
62 struct btrfs_inode_item *inode_item; 62 struct btrfs_inode_item *inode_item;
63 struct btrfs_root *root = BTRFS_I(inode)->root; 63 struct btrfs_root *root = BTRFS_I(inode)->root;
64 struct btrfs_key location; 64 struct btrfs_key location;
65 struct btrfs_block_group_cache *alloc_group;
66 u64 alloc_group_block; 65 u64 alloc_group_block;
67 int ret; 66 int ret;
68 67
@@ -95,11 +94,8 @@ static void btrfs_read_locked_inode(struct inode *inode)
95 inode->i_blocks = btrfs_inode_nblocks(inode_item); 94 inode->i_blocks = btrfs_inode_nblocks(inode_item);
96 inode->i_generation = btrfs_inode_generation(inode_item); 95 inode->i_generation = btrfs_inode_generation(inode_item);
97 alloc_group_block = btrfs_inode_block_group(inode_item); 96 alloc_group_block = btrfs_inode_block_group(inode_item);
98 ret = radix_tree_gang_lookup(&root->fs_info->block_group_radix, 97 BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info,
99 (void **)&alloc_group, 98 alloc_group_block);
100 alloc_group_block, 1);
101 BUG_ON(!ret);
102 BTRFS_I(inode)->block_group = alloc_group;
103 99
104 btrfs_free_path(path); 100 btrfs_free_path(path);
105 inode_item = NULL; 101 inode_item = NULL;