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 1b9ec1ab1f6..a8c9693b75a 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 5b0c79d22c0..8733081d97a 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 673ff59c288..1cc89246ee2 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 932d8c0b2c0..0a28b770631 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 69c4a07f586..5d67858ce99 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 47cd5fcad2c..4604178a43a 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 202c8be6c05..ffe7f639732 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 | }; |
