diff options
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 8 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 17 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 132 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 43 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 2 |
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 | ||
658 | struct btrfs_leaf_ref_tree { | 661 | struct btrfs_leaf_ref_tree { |
@@ -1706,10 +1709,8 @@ int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy); | |||
1706 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | 1709 | struct 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); |
1709 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | 1712 | u64 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); | ||
1713 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1714 | struct 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); |
1771 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | 1772 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
1772 | struct btrfs_root *root); | 1773 | struct btrfs_root *root); |
1774 | int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr); | ||
1773 | int btrfs_free_block_groups(struct btrfs_fs_info *info); | 1775 | int btrfs_free_block_groups(struct btrfs_fs_info *info); |
1774 | int btrfs_read_block_groups(struct btrfs_root *root); | 1776 | int btrfs_read_block_groups(struct btrfs_root *root); |
1775 | int btrfs_make_block_group(struct btrfs_trans_handle *trans, | 1777 | int btrfs_make_block_group(struct btrfs_trans_handle *trans, |
@@ -2019,10 +2021,9 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root); | |||
2019 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); | 2021 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); |
2020 | int btrfs_writepages(struct address_space *mapping, | 2022 | int btrfs_writepages(struct address_space *mapping, |
2021 | struct writeback_control *wbc); | 2023 | struct writeback_control *wbc); |
2022 | int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry, | 2024 | int 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 | |||
2026 | int btrfs_merge_bio_hook(struct page *page, unsigned long offset, | 2027 | int 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); |
54 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 54 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
55 | btrfs_root *extent_root, int all); | 55 | btrfs_root *extent_root, int all); |
56 | static 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); | ||
60 | static int pin_down_bytes(struct btrfs_trans_handle *trans, | 56 | static 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 | ||
319 | static 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 | |||
321 | static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | 325 | static 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 | ||
344 | static struct btrfs_block_group_cache * | 348 | u64 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 | } | ||
392 | again: | 358 | again: |
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 | } |
425 | found: | 393 | found: |
426 | return found_group; | 394 | return group_start; |
427 | } | ||
428 | |||
429 | struct 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 | ||
1769 | int 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 | |||
1812 | static int update_space_info(struct btrfs_fs_info *info, u64 flags, | 1782 | static 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, | |||
2008 | static u64 first_logical_byte(struct btrfs_root *root, u64 search_start) | 1978 | static 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 | ||
2019 | int btrfs_update_pinned_extents(struct btrfs_root *root, | 1993 | int 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 | } |
2929 | new_group: | 2906 | new_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; | ||
2931 | new_group_no_lock: | 2910 | new_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; |
5707 | out: | 5693 | out: |
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 | */ |
4369 | int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry, | 4352 | int 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 | }; |