aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-12-11 16:30:39 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-11 16:30:39 -0500
commitd2fb3437e4d8d12c73c587615ad187d5288547ec (patch)
tree894e4c698970dd35226b2614b8a38fb8a96580e7 /fs
parentcfc8ea87201dc9bb6aeb3fc80c61abee83e7cc06 (diff)
Btrfs: fix leaking block group on balance
The block group structs are referenced in many different places, and it's not safe to free while balancing. So, those block group structs were simply leaked instead. This patch replaces the block group pointer in the inode with the starting byte offset of the block group and adds reference counting to the block group struct. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/btrfs_inode.h8
-rw-r--r--fs/btrfs/ctree.h17
-rw-r--r--fs/btrfs/extent-tree.c132
-rw-r--r--fs/btrfs/inode.c43
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/transaction.c2
-rw-r--r--fs/btrfs/transaction.h2
7 files changed, 88 insertions, 118 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 1b9ec1ab1f68..a8c9693b75ac 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -28,11 +28,6 @@ struct btrfs_inode {
28 /* which subvolume this inode belongs to */ 28 /* which subvolume this inode belongs to */
29 struct btrfs_root *root; 29 struct btrfs_root *root;
30 30
31 /* the block group preferred for allocations. This pointer is buggy
32 * and needs to be replaced with a bytenr instead
33 */
34 struct btrfs_block_group_cache *block_group;
35
36 /* key used to find this inode on disk. This is used by the code 31 /* key used to find this inode on disk. This is used by the code
37 * to read in roots of subvolumes 32 * to read in roots of subvolumes
38 */ 33 */
@@ -115,6 +110,9 @@ struct btrfs_inode {
115 */ 110 */
116 u64 index_cnt; 111 u64 index_cnt;
117 112
113 /* the start of block group preferred for allocations. */
114 u64 block_group;
115
118 struct inode vfs_inode; 116 struct inode vfs_inode;
119}; 117};
120 118
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5b0c79d22c09..8733081d97a3 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -653,6 +653,9 @@ struct btrfs_block_group_cache {
653 653
654 /* for block groups in the same raid type */ 654 /* for block groups in the same raid type */
655 struct list_head list; 655 struct list_head list;
656
657 /* usage count */
658 atomic_t count;
656}; 659};
657 660
658struct btrfs_leaf_ref_tree { 661struct btrfs_leaf_ref_tree {
@@ -1706,10 +1709,8 @@ int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy);
1706struct btrfs_block_group_cache *btrfs_lookup_block_group(struct 1709struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
1707 btrfs_fs_info *info, 1710 btrfs_fs_info *info,
1708 u64 bytenr); 1711 u64 bytenr);
1709struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, 1712u64 btrfs_find_block_group(struct btrfs_root *root,
1710 struct btrfs_block_group_cache 1713 u64 search_start, u64 search_hint, int owner);
1711 *hint, u64 search_start,
1712 int data, int owner);
1713struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 1714struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1714 struct btrfs_root *root, 1715 struct btrfs_root *root,
1715 u32 blocksize, u64 parent, 1716 u32 blocksize, u64 parent,
@@ -1770,6 +1771,7 @@ int btrfs_update_extent_ref(struct btrfs_trans_handle *trans,
1770 u64 owner_objectid); 1771 u64 owner_objectid);
1771int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, 1772int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
1772 struct btrfs_root *root); 1773 struct btrfs_root *root);
1774int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr);
1773int btrfs_free_block_groups(struct btrfs_fs_info *info); 1775int btrfs_free_block_groups(struct btrfs_fs_info *info);
1774int btrfs_read_block_groups(struct btrfs_root *root); 1776int btrfs_read_block_groups(struct btrfs_root *root);
1775int btrfs_make_block_group(struct btrfs_trans_handle *trans, 1777int btrfs_make_block_group(struct btrfs_trans_handle *trans,
@@ -2019,10 +2021,9 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root);
2019int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); 2021int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end);
2020int btrfs_writepages(struct address_space *mapping, 2022int btrfs_writepages(struct address_space *mapping,
2021 struct writeback_control *wbc); 2023 struct writeback_control *wbc);
2022int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry, 2024int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
2023 struct btrfs_trans_handle *trans, u64 new_dirid, 2025 struct btrfs_root *new_root, struct dentry *dentry,
2024 struct btrfs_block_group_cache *block_group); 2026 u64 new_dirid, u64 alloc_hint);
2025
2026int btrfs_merge_bio_hook(struct page *page, unsigned long offset, 2027int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
2027 size_t size, struct bio *bio, unsigned long bio_flags); 2028 size_t size, struct bio *bio, unsigned long bio_flags);
2028 2029
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 673ff59c288a..1cc89246ee2f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -53,10 +53,6 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
53 btrfs_root *extent_root, int all); 53 btrfs_root *extent_root, int all);
54static int del_pending_extents(struct btrfs_trans_handle *trans, struct 54static int del_pending_extents(struct btrfs_trans_handle *trans, struct
55 btrfs_root *extent_root, int all); 55 btrfs_root *extent_root, int all);
56static struct btrfs_block_group_cache *
57__btrfs_find_block_group(struct btrfs_root *root,
58 struct btrfs_block_group_cache *hint,
59 u64 search_start, int data, int owner);
60static int pin_down_bytes(struct btrfs_trans_handle *trans, 56static int pin_down_bytes(struct btrfs_trans_handle *trans,
61 struct btrfs_root *root, 57 struct btrfs_root *root,
62 u64 bytenr, u64 num_bytes, int is_data); 58 u64 bytenr, u64 num_bytes, int is_data);
@@ -142,6 +138,8 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr,
142 break; 138 break;
143 } 139 }
144 } 140 }
141 if (ret)
142 atomic_inc(&ret->count);
145 spin_unlock(&info->block_group_cache_lock); 143 spin_unlock(&info->block_group_cache_lock);
146 144
147 return ret; 145 return ret;
@@ -318,6 +316,12 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
318 return cache; 316 return cache;
319} 317}
320 318
319static inline void put_block_group(struct btrfs_block_group_cache *cache)
320{
321 if (atomic_dec_and_test(&cache->count))
322 kfree(cache);
323}
324
321static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, 325static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
322 u64 flags) 326 u64 flags)
323{ 327{
@@ -341,54 +345,16 @@ static u64 div_factor(u64 num, int factor)
341 return num; 345 return num;
342} 346}
343 347
344static struct btrfs_block_group_cache * 348u64 btrfs_find_block_group(struct btrfs_root *root,
345__btrfs_find_block_group(struct btrfs_root *root, 349 u64 search_start, u64 search_hint, int owner)
346 struct btrfs_block_group_cache *hint,
347 u64 search_start, int data, int owner)
348{ 350{
349 struct btrfs_block_group_cache *cache; 351 struct btrfs_block_group_cache *cache;
350 struct btrfs_block_group_cache *found_group = NULL;
351 struct btrfs_fs_info *info = root->fs_info;
352 u64 used; 352 u64 used;
353 u64 last = 0; 353 u64 last = max(search_hint, search_start);
354 u64 free_check; 354 u64 group_start = 0;
355 int full_search = 0; 355 int full_search = 0;
356 int factor = 10; 356 int factor = 9;
357 int wrapped = 0; 357 int wrapped = 0;
358
359 if (data & BTRFS_BLOCK_GROUP_METADATA)
360 factor = 9;
361
362 if (search_start) {
363 struct btrfs_block_group_cache *shint;
364 shint = btrfs_lookup_first_block_group(info, search_start);
365 if (shint && block_group_bits(shint, data)) {
366 spin_lock(&shint->lock);
367 used = btrfs_block_group_used(&shint->item);
368 if (used + shint->pinned + shint->reserved <
369 div_factor(shint->key.offset, factor)) {
370 spin_unlock(&shint->lock);
371 return shint;
372 }
373 spin_unlock(&shint->lock);
374 }
375 }
376 if (hint && block_group_bits(hint, data)) {
377 spin_lock(&hint->lock);
378 used = btrfs_block_group_used(&hint->item);
379 if (used + hint->pinned + hint->reserved <
380 div_factor(hint->key.offset, factor)) {
381 spin_unlock(&hint->lock);
382 return hint;
383 }
384 spin_unlock(&hint->lock);
385 last = hint->key.objectid + hint->key.offset;
386 } else {
387 if (hint)
388 last = max(hint->key.objectid, search_start);
389 else
390 last = search_start;
391 }
392again: 358again:
393 while (1) { 359 while (1) {
394 cache = btrfs_lookup_first_block_group(root->fs_info, last); 360 cache = btrfs_lookup_first_block_group(root->fs_info, last);
@@ -399,16 +365,18 @@ again:
399 last = cache->key.objectid + cache->key.offset; 365 last = cache->key.objectid + cache->key.offset;
400 used = btrfs_block_group_used(&cache->item); 366 used = btrfs_block_group_used(&cache->item);
401 367
402 if (block_group_bits(cache, data)) { 368 if ((full_search || !cache->ro) &&
403 free_check = div_factor(cache->key.offset, factor); 369 block_group_bits(cache, BTRFS_BLOCK_GROUP_METADATA)) {
404 if (used + cache->pinned + cache->reserved < 370 if (used + cache->pinned + cache->reserved <
405 free_check) { 371 div_factor(cache->key.offset, factor)) {
406 found_group = cache; 372 group_start = cache->key.objectid;
407 spin_unlock(&cache->lock); 373 spin_unlock(&cache->lock);
374 put_block_group(cache);
408 goto found; 375 goto found;
409 } 376 }
410 } 377 }
411 spin_unlock(&cache->lock); 378 spin_unlock(&cache->lock);
379 put_block_group(cache);
412 cond_resched(); 380 cond_resched();
413 } 381 }
414 if (!wrapped) { 382 if (!wrapped) {
@@ -423,18 +391,7 @@ again:
423 goto again; 391 goto again;
424 } 392 }
425found: 393found:
426 return found_group; 394 return group_start;
427}
428
429struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
430 struct btrfs_block_group_cache
431 *hint, u64 search_start,
432 int data, int owner)
433{
434
435 struct btrfs_block_group_cache *ret;
436 ret = __btrfs_find_block_group(root, hint, search_start, data, owner);
437 return ret;
438} 395}
439 396
440/* simple helper to search for an existing extent at a given offset */ 397/* simple helper to search for an existing extent at a given offset */
@@ -1809,6 +1766,19 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
1809 return werr; 1766 return werr;
1810} 1767}
1811 1768
1769int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr)
1770{
1771 struct btrfs_block_group_cache *block_group;
1772 int readonly = 0;
1773
1774 block_group = btrfs_lookup_block_group(root->fs_info, bytenr);
1775 if (!block_group || block_group->ro)
1776 readonly = 1;
1777 if (block_group)
1778 put_block_group(block_group);
1779 return readonly;
1780}
1781
1812static int update_space_info(struct btrfs_fs_info *info, u64 flags, 1782static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1813 u64 total_bytes, u64 bytes_used, 1783 u64 total_bytes, u64 bytes_used,
1814 struct btrfs_space_info **space_info) 1784 struct btrfs_space_info **space_info)
@@ -1995,10 +1965,10 @@ static int update_block_group(struct btrfs_trans_handle *trans,
1995 int ret; 1965 int ret;
1996 ret = btrfs_add_free_space(cache, bytenr, 1966 ret = btrfs_add_free_space(cache, bytenr,
1997 num_bytes); 1967 num_bytes);
1998 if (ret) 1968 WARN_ON(ret);
1999 return -1;
2000 } 1969 }
2001 } 1970 }
1971 put_block_group(cache);
2002 total -= num_bytes; 1972 total -= num_bytes;
2003 bytenr += num_bytes; 1973 bytenr += num_bytes;
2004 } 1974 }
@@ -2008,12 +1978,16 @@ static int update_block_group(struct btrfs_trans_handle *trans,
2008static u64 first_logical_byte(struct btrfs_root *root, u64 search_start) 1978static u64 first_logical_byte(struct btrfs_root *root, u64 search_start)
2009{ 1979{
2010 struct btrfs_block_group_cache *cache; 1980 struct btrfs_block_group_cache *cache;
1981 u64 bytenr;
2011 1982
2012 cache = btrfs_lookup_first_block_group(root->fs_info, search_start); 1983 cache = btrfs_lookup_first_block_group(root->fs_info, search_start);
2013 if (!cache) 1984 if (!cache)
2014 return 0; 1985 return 0;
2015 1986
2016 return cache->key.objectid; 1987 bytenr = cache->key.objectid;
1988 put_block_group(cache);
1989
1990 return bytenr;
2017} 1991}
2018 1992
2019int btrfs_update_pinned_extents(struct btrfs_root *root, 1993int btrfs_update_pinned_extents(struct btrfs_root *root,
@@ -2055,6 +2029,7 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
2055 if (cache->cached) 2029 if (cache->cached)
2056 btrfs_add_free_space(cache, bytenr, len); 2030 btrfs_add_free_space(cache, bytenr, len);
2057 } 2031 }
2032 put_block_group(cache);
2058 bytenr += len; 2033 bytenr += len;
2059 num -= len; 2034 num -= len;
2060 } 2035 }
@@ -2085,6 +2060,7 @@ static int update_reserved_extents(struct btrfs_root *root,
2085 } 2060 }
2086 spin_unlock(&cache->lock); 2061 spin_unlock(&cache->lock);
2087 spin_unlock(&cache->space_info->lock); 2062 spin_unlock(&cache->space_info->lock);
2063 put_block_group(cache);
2088 bytenr += len; 2064 bytenr += len;
2089 num -= len; 2065 num -= len;
2090 } 2066 }
@@ -2724,6 +2700,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
2724 cache = btrfs_lookup_block_group(root->fs_info, bytenr); 2700 cache = btrfs_lookup_block_group(root->fs_info, bytenr);
2725 BUG_ON(!cache); 2701 BUG_ON(!cache);
2726 btrfs_add_free_space(cache, bytenr, num_bytes); 2702 btrfs_add_free_space(cache, bytenr, num_bytes);
2703 put_block_group(cache);
2727 update_reserved_extents(root, bytenr, num_bytes, 0); 2704 update_reserved_extents(root, bytenr, num_bytes, 0);
2728 return 0; 2705 return 0;
2729 } 2706 }
@@ -2928,6 +2905,8 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2928 } 2905 }
2929new_group: 2906new_group:
2930 mutex_unlock(&block_group->alloc_mutex); 2907 mutex_unlock(&block_group->alloc_mutex);
2908 put_block_group(block_group);
2909 block_group = NULL;
2931new_group_no_lock: 2910new_group_no_lock:
2932 /* don't try to compare new allocations against the 2911 /* don't try to compare new allocations against the
2933 * last allocation any more 2912 * last allocation any more
@@ -2997,6 +2976,8 @@ loop_check:
2997 2976
2998 block_group = list_entry(cur, struct btrfs_block_group_cache, 2977 block_group = list_entry(cur, struct btrfs_block_group_cache,
2999 list); 2978 list);
2979 atomic_inc(&block_group->count);
2980
3000 search_start = block_group->key.objectid; 2981 search_start = block_group->key.objectid;
3001 cur = cur->next; 2982 cur = cur->next;
3002 } 2983 }
@@ -3004,7 +2985,7 @@ loop_check:
3004 /* we found what we needed */ 2985 /* we found what we needed */
3005 if (ins->objectid) { 2986 if (ins->objectid) {
3006 if (!(data & BTRFS_BLOCK_GROUP_DATA)) 2987 if (!(data & BTRFS_BLOCK_GROUP_DATA))
3007 trans->block_group = block_group; 2988 trans->block_group = block_group->key.objectid;
3008 2989
3009 if (last_ptr) 2990 if (last_ptr)
3010 *last_ptr = ins->objectid + ins->offset; 2991 *last_ptr = ins->objectid + ins->offset;
@@ -3015,6 +2996,8 @@ loop_check:
3015 loop, allowed_chunk_alloc); 2996 loop, allowed_chunk_alloc);
3016 ret = -ENOSPC; 2997 ret = -ENOSPC;
3017 } 2998 }
2999 if (block_group)
3000 put_block_group(block_group);
3018 3001
3019 up_read(&space_info->groups_sem); 3002 up_read(&space_info->groups_sem);
3020 return ret; 3003 return ret;
@@ -3124,6 +3107,7 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
3124 return -ENOSPC; 3107 return -ENOSPC;
3125 } 3108 }
3126 btrfs_add_free_space(cache, start, len); 3109 btrfs_add_free_space(cache, start, len);
3110 put_block_group(cache);
3127 update_reserved_extents(root, start, len, 0); 3111 update_reserved_extents(root, start, len, 0);
3128 return 0; 3112 return 0;
3129} 3113}
@@ -3288,6 +3272,7 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans,
3288 ret = btrfs_remove_free_space(block_group, ins->objectid, 3272 ret = btrfs_remove_free_space(block_group, ins->objectid,
3289 ins->offset); 3273 ins->offset);
3290 BUG_ON(ret); 3274 BUG_ON(ret);
3275 put_block_group(block_group);
3291 ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid, 3276 ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid,
3292 ref_generation, owner, ins); 3277 ref_generation, owner, ins);
3293 return ret; 3278 return ret;
@@ -5703,6 +5688,7 @@ next:
5703 WARN_ON(block_group->reserved > 0); 5688 WARN_ON(block_group->reserved > 0);
5704 WARN_ON(btrfs_block_group_used(&block_group->item) > 0); 5689 WARN_ON(btrfs_block_group_used(&block_group->item) > 0);
5705 spin_unlock(&block_group->lock); 5690 spin_unlock(&block_group->lock);
5691 put_block_group(block_group);
5706 ret = 0; 5692 ret = 0;
5707out: 5693out:
5708 btrfs_free_path(path); 5694 btrfs_free_path(path);
@@ -5763,6 +5749,8 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
5763 down_write(&block_group->space_info->groups_sem); 5749 down_write(&block_group->space_info->groups_sem);
5764 list_del(&block_group->list); 5750 list_del(&block_group->list);
5765 up_write(&block_group->space_info->groups_sem); 5751 up_write(&block_group->space_info->groups_sem);
5752
5753 WARN_ON(atomic_read(&block_group->count) != 1);
5766 kfree(block_group); 5754 kfree(block_group);
5767 5755
5768 spin_lock(&info->block_group_cache_lock); 5756 spin_lock(&info->block_group_cache_lock);
@@ -5807,6 +5795,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
5807 break; 5795 break;
5808 } 5796 }
5809 5797
5798 atomic_set(&cache->count, 1);
5810 spin_lock_init(&cache->lock); 5799 spin_lock_init(&cache->lock);
5811 mutex_init(&cache->alloc_mutex); 5800 mutex_init(&cache->alloc_mutex);
5812 mutex_init(&cache->cache_mutex); 5801 mutex_init(&cache->cache_mutex);
@@ -5861,11 +5850,12 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
5861 5850
5862 cache->key.objectid = chunk_offset; 5851 cache->key.objectid = chunk_offset;
5863 cache->key.offset = size; 5852 cache->key.offset = size;
5853 cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
5854 atomic_set(&cache->count, 1);
5864 spin_lock_init(&cache->lock); 5855 spin_lock_init(&cache->lock);
5865 mutex_init(&cache->alloc_mutex); 5856 mutex_init(&cache->alloc_mutex);
5866 mutex_init(&cache->cache_mutex); 5857 mutex_init(&cache->cache_mutex);
5867 INIT_LIST_HEAD(&cache->list); 5858 INIT_LIST_HEAD(&cache->list);
5868 btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
5869 5859
5870 btrfs_set_block_group_used(&cache->item, bytes_used); 5860 btrfs_set_block_group_used(&cache->item, bytes_used);
5871 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); 5861 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
@@ -5926,10 +5916,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
5926 spin_unlock(&block_group->space_info->lock); 5916 spin_unlock(&block_group->space_info->lock);
5927 block_group->space_info->full = 0; 5917 block_group->space_info->full = 0;
5928 5918
5929 /* 5919 put_block_group(block_group);
5930 memset(shrink_block_group, 0, sizeof(*shrink_block_group)); 5920 put_block_group(block_group);
5931 kfree(shrink_block_group);
5932 */
5933 5921
5934 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 5922 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
5935 if (ret > 0) 5923 if (ret > 0)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 932d8c0b2c05..0a28b7706314 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -989,7 +989,6 @@ next_slot:
989 989
990 if (extent_type == BTRFS_FILE_EXTENT_REG || 990 if (extent_type == BTRFS_FILE_EXTENT_REG ||
991 extent_type == BTRFS_FILE_EXTENT_PREALLOC) { 991 extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
992 struct btrfs_block_group_cache *block_group;
993 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); 992 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
994 extent_end = found_key.offset + 993 extent_end = found_key.offset +
995 btrfs_file_extent_num_bytes(leaf, fi); 994 btrfs_file_extent_num_bytes(leaf, fi);
@@ -1007,9 +1006,7 @@ next_slot:
1007 goto out_check; 1006 goto out_check;
1008 if (btrfs_cross_ref_exist(trans, root, disk_bytenr)) 1007 if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
1009 goto out_check; 1008 goto out_check;
1010 block_group = btrfs_lookup_block_group(root->fs_info, 1009 if (btrfs_extent_readonly(root, disk_bytenr))
1011 disk_bytenr);
1012 if (!block_group || block_group->ro)
1013 goto out_check; 1010 goto out_check;
1014 disk_bytenr += btrfs_file_extent_offset(leaf, fi); 1011 disk_bytenr += btrfs_file_extent_offset(leaf, fi);
1015 nocow = 1; 1012 nocow = 1;
@@ -1969,16 +1966,11 @@ void btrfs_read_locked_inode(struct inode *inode)
1969 rdev = btrfs_inode_rdev(leaf, inode_item); 1966 rdev = btrfs_inode_rdev(leaf, inode_item);
1970 1967
1971 BTRFS_I(inode)->index_cnt = (u64)-1; 1968 BTRFS_I(inode)->index_cnt = (u64)-1;
1969 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
1972 1970
1973 alloc_group_block = btrfs_inode_block_group(leaf, inode_item); 1971 alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
1974 BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info, 1972 BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
1975 alloc_group_block); 1973 alloc_group_block, 0);
1976 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
1977 if (!BTRFS_I(inode)->block_group) {
1978 BTRFS_I(inode)->block_group = btrfs_find_block_group(root,
1979 NULL, 0,
1980 BTRFS_BLOCK_GROUP_METADATA, 0);
1981 }
1982 btrfs_free_path(path); 1974 btrfs_free_path(path);
1983 inode_item = NULL; 1975 inode_item = NULL;
1984 1976
@@ -2048,8 +2040,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
2048 btrfs_set_inode_transid(leaf, item, trans->transid); 2040 btrfs_set_inode_transid(leaf, item, trans->transid);
2049 btrfs_set_inode_rdev(leaf, item, inode->i_rdev); 2041 btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
2050 btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); 2042 btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
2051 btrfs_set_inode_block_group(leaf, item, 2043 btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group);
2052 BTRFS_I(inode)->block_group->key.objectid);
2053} 2044}
2054 2045
2055/* 2046/*
@@ -3358,14 +3349,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3358 struct btrfs_root *root, 3349 struct btrfs_root *root,
3359 struct inode *dir, 3350 struct inode *dir,
3360 const char *name, int name_len, 3351 const char *name, int name_len,
3361 u64 ref_objectid, 3352 u64 ref_objectid, u64 objectid,
3362 u64 objectid, 3353 u64 alloc_hint, int mode, u64 *index)
3363 struct btrfs_block_group_cache *group,
3364 int mode, u64 *index)
3365{ 3354{
3366 struct inode *inode; 3355 struct inode *inode;
3367 struct btrfs_inode_item *inode_item; 3356 struct btrfs_inode_item *inode_item;
3368 struct btrfs_block_group_cache *new_inode_group;
3369 struct btrfs_key *location; 3357 struct btrfs_key *location;
3370 struct btrfs_path *path; 3358 struct btrfs_path *path;
3371 struct btrfs_inode_ref *ref; 3359 struct btrfs_inode_ref *ref;
@@ -3401,13 +3389,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3401 owner = 0; 3389 owner = 0;
3402 else 3390 else
3403 owner = 1; 3391 owner = 1;
3404 new_inode_group = btrfs_find_block_group(root, group, 0, 3392 BTRFS_I(inode)->block_group =
3405 BTRFS_BLOCK_GROUP_METADATA, owner); 3393 btrfs_find_block_group(root, 0, alloc_hint, owner);
3406 if (!new_inode_group) {
3407 printk("find_block group failed\n");
3408 new_inode_group = group;
3409 }
3410 BTRFS_I(inode)->block_group = new_inode_group;
3411 3394
3412 key[0].objectid = objectid; 3395 key[0].objectid = objectid;
3413 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 3396 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
@@ -4366,16 +4349,16 @@ out:
4366/* 4349/*
4367 * create a new subvolume directory/inode (helper for the ioctl). 4350 * create a new subvolume directory/inode (helper for the ioctl).
4368 */ 4351 */
4369int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry, 4352int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
4370 struct btrfs_trans_handle *trans, u64 new_dirid, 4353 struct btrfs_root *new_root, struct dentry *dentry,
4371 struct btrfs_block_group_cache *block_group) 4354 u64 new_dirid, u64 alloc_hint)
4372{ 4355{
4373 struct inode *inode; 4356 struct inode *inode;
4374 int error; 4357 int error;
4375 u64 index = 0; 4358 u64 index = 0;
4376 4359
4377 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, 4360 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
4378 new_dirid, block_group, S_IFDIR | 0700, &index); 4361 new_dirid, alloc_hint, S_IFDIR | 0700, &index);
4379 if (IS_ERR(inode)) 4362 if (IS_ERR(inode))
4380 return PTR_ERR(inode); 4363 return PTR_ERR(inode);
4381 inode->i_op = &btrfs_dir_inode_operations; 4364 inode->i_op = &btrfs_dir_inode_operations;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 69c4a07f5869..5d67858ce993 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -173,7 +173,7 @@ static noinline int create_subvol(struct btrfs_root *root,
173 trans = btrfs_start_transaction(new_root, 1); 173 trans = btrfs_start_transaction(new_root, 1);
174 BUG_ON(!trans); 174 BUG_ON(!trans);
175 175
176 ret = btrfs_create_subvol_root(new_root, dentry, trans, new_dirid, 176 ret = btrfs_create_subvol_root(trans, new_root, dentry, new_dirid,
177 BTRFS_I(dir)->block_group); 177 BTRFS_I(dir)->block_group);
178 if (ret) 178 if (ret)
179 goto fail; 179 goto fail;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 47cd5fcad2c8..4604178a43a9 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -182,7 +182,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
182 h->transaction = root->fs_info->running_transaction; 182 h->transaction = root->fs_info->running_transaction;
183 h->blocks_reserved = num_blocks; 183 h->blocks_reserved = num_blocks;
184 h->blocks_used = 0; 184 h->blocks_used = 0;
185 h->block_group = NULL; 185 h->block_group = 0;
186 h->alloc_exclude_nr = 0; 186 h->alloc_exclude_nr = 0;
187 h->alloc_exclude_start = 0; 187 h->alloc_exclude_start = 0;
188 root->fs_info->running_transaction->use_count++; 188 root->fs_info->running_transaction->use_count++;
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 202c8be6c05d..ffe7f639732b 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -41,7 +41,7 @@ struct btrfs_trans_handle {
41 unsigned long blocks_reserved; 41 unsigned long blocks_reserved;
42 unsigned long blocks_used; 42 unsigned long blocks_used;
43 struct btrfs_transaction *transaction; 43 struct btrfs_transaction *transaction;
44 struct btrfs_block_group_cache *block_group; 44 u64 block_group;
45 u64 alloc_exclude_start; 45 u64 alloc_exclude_start;
46 u64 alloc_exclude_nr; 46 u64 alloc_exclude_nr;
47}; 47};