diff options
author | Josef Bacik <jbacik@fb.com> | 2013-12-16 13:24:27 -0500 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-01-28 16:19:55 -0500 |
commit | f28491e0a6c46d99cbbef0f8ef7e314afa2359c8 (patch) | |
tree | 4a64b0042fbdd784a4dd2e038d9e3833f69bab7a /fs | |
parent | 34b41acec1ccc06373ec584de19618d48ceb09fc (diff) |
Btrfs: move the extent buffer radix tree into the fs_info
I need to create a fake tree to test qgroups and I don't want to have to setup a
fake btree_inode. The fact is we only use the radix tree for the fs_info, so
everybody else who allocates an extent_io_tree is just wasting the space anyway.
This patch moves the radix tree and its lock into btrfs_fs_info so there is less
stuff I have to fake to do qgroup sanity tests. Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 14 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 47 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 8 |
4 files changed, 34 insertions, 39 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 7158c97fdc5e..a924274a503e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1659,6 +1659,10 @@ struct btrfs_fs_info { | |||
1659 | spinlock_t reada_lock; | 1659 | spinlock_t reada_lock; |
1660 | struct radix_tree_root reada_tree; | 1660 | struct radix_tree_root reada_tree; |
1661 | 1661 | ||
1662 | /* Extent buffer radix tree */ | ||
1663 | spinlock_t buffer_lock; | ||
1664 | struct radix_tree_root buffer_radix; | ||
1665 | |||
1662 | /* next backup root to be overwritten */ | 1666 | /* next backup root to be overwritten */ |
1663 | int backup_root_index; | 1667 | int backup_root_index; |
1664 | 1668 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4ecee0a009cb..4a1871cf797b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1089,21 +1089,13 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, | |||
1089 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | 1089 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
1090 | u64 bytenr, u32 blocksize) | 1090 | u64 bytenr, u32 blocksize) |
1091 | { | 1091 | { |
1092 | struct inode *btree_inode = root->fs_info->btree_inode; | 1092 | return find_extent_buffer(root->fs_info, bytenr); |
1093 | struct extent_buffer *eb; | ||
1094 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, bytenr); | ||
1095 | return eb; | ||
1096 | } | 1093 | } |
1097 | 1094 | ||
1098 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | 1095 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, |
1099 | u64 bytenr, u32 blocksize) | 1096 | u64 bytenr, u32 blocksize) |
1100 | { | 1097 | { |
1101 | struct inode *btree_inode = root->fs_info->btree_inode; | 1098 | return alloc_extent_buffer(root->fs_info, bytenr, blocksize); |
1102 | struct extent_buffer *eb; | ||
1103 | |||
1104 | eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree, | ||
1105 | bytenr, blocksize); | ||
1106 | return eb; | ||
1107 | } | 1099 | } |
1108 | 1100 | ||
1109 | 1101 | ||
@@ -2145,6 +2137,7 @@ int open_ctree(struct super_block *sb, | |||
2145 | mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); | 2137 | mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); |
2146 | 2138 | ||
2147 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); | 2139 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); |
2140 | INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC); | ||
2148 | INIT_LIST_HEAD(&fs_info->trans_list); | 2141 | INIT_LIST_HEAD(&fs_info->trans_list); |
2149 | INIT_LIST_HEAD(&fs_info->dead_roots); | 2142 | INIT_LIST_HEAD(&fs_info->dead_roots); |
2150 | INIT_LIST_HEAD(&fs_info->delayed_iputs); | 2143 | INIT_LIST_HEAD(&fs_info->delayed_iputs); |
@@ -2158,6 +2151,7 @@ int open_ctree(struct super_block *sb, | |||
2158 | spin_lock_init(&fs_info->free_chunk_lock); | 2151 | spin_lock_init(&fs_info->free_chunk_lock); |
2159 | spin_lock_init(&fs_info->tree_mod_seq_lock); | 2152 | spin_lock_init(&fs_info->tree_mod_seq_lock); |
2160 | spin_lock_init(&fs_info->super_lock); | 2153 | spin_lock_init(&fs_info->super_lock); |
2154 | spin_lock_init(&fs_info->buffer_lock); | ||
2161 | rwlock_init(&fs_info->tree_mod_log_lock); | 2155 | rwlock_init(&fs_info->tree_mod_log_lock); |
2162 | mutex_init(&fs_info->reloc_mutex); | 2156 | mutex_init(&fs_info->reloc_mutex); |
2163 | seqlock_init(&fs_info->profiles_lock); | 2157 | seqlock_init(&fs_info->profiles_lock); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 92a3ad4656a6..2fa23b57d8df 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -194,11 +194,9 @@ void extent_io_tree_init(struct extent_io_tree *tree, | |||
194 | struct address_space *mapping) | 194 | struct address_space *mapping) |
195 | { | 195 | { |
196 | tree->state = RB_ROOT; | 196 | tree->state = RB_ROOT; |
197 | INIT_RADIX_TREE(&tree->buffer, GFP_ATOMIC); | ||
198 | tree->ops = NULL; | 197 | tree->ops = NULL; |
199 | tree->dirty_bytes = 0; | 198 | tree->dirty_bytes = 0; |
200 | spin_lock_init(&tree->lock); | 199 | spin_lock_init(&tree->lock); |
201 | spin_lock_init(&tree->buffer_lock); | ||
202 | tree->mapping = mapping; | 200 | tree->mapping = mapping; |
203 | } | 201 | } |
204 | 202 | ||
@@ -3489,6 +3487,7 @@ static int write_one_eb(struct extent_buffer *eb, | |||
3489 | struct extent_page_data *epd) | 3487 | struct extent_page_data *epd) |
3490 | { | 3488 | { |
3491 | struct block_device *bdev = fs_info->fs_devices->latest_bdev; | 3489 | struct block_device *bdev = fs_info->fs_devices->latest_bdev; |
3490 | struct extent_io_tree *tree = &BTRFS_I(fs_info->btree_inode)->io_tree; | ||
3492 | u64 offset = eb->start; | 3491 | u64 offset = eb->start; |
3493 | unsigned long i, num_pages; | 3492 | unsigned long i, num_pages; |
3494 | unsigned long bio_flags = 0; | 3493 | unsigned long bio_flags = 0; |
@@ -3506,7 +3505,7 @@ static int write_one_eb(struct extent_buffer *eb, | |||
3506 | 3505 | ||
3507 | clear_page_dirty_for_io(p); | 3506 | clear_page_dirty_for_io(p); |
3508 | set_page_writeback(p); | 3507 | set_page_writeback(p); |
3509 | ret = submit_extent_page(rw, eb->tree, p, offset >> 9, | 3508 | ret = submit_extent_page(rw, tree, p, offset >> 9, |
3510 | PAGE_CACHE_SIZE, 0, bdev, &epd->bio, | 3509 | PAGE_CACHE_SIZE, 0, bdev, &epd->bio, |
3511 | -1, end_bio_extent_buffer_writepage, | 3510 | -1, end_bio_extent_buffer_writepage, |
3512 | 0, epd->bio_flags, bio_flags); | 3511 | 0, epd->bio_flags, bio_flags); |
@@ -4370,10 +4369,9 @@ static inline void btrfs_release_extent_buffer(struct extent_buffer *eb) | |||
4370 | __free_extent_buffer(eb); | 4369 | __free_extent_buffer(eb); |
4371 | } | 4370 | } |
4372 | 4371 | ||
4373 | static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, | 4372 | static struct extent_buffer * |
4374 | u64 start, | 4373 | __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start, |
4375 | unsigned long len, | 4374 | unsigned long len, gfp_t mask) |
4376 | gfp_t mask) | ||
4377 | { | 4375 | { |
4378 | struct extent_buffer *eb = NULL; | 4376 | struct extent_buffer *eb = NULL; |
4379 | 4377 | ||
@@ -4382,7 +4380,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, | |||
4382 | return NULL; | 4380 | return NULL; |
4383 | eb->start = start; | 4381 | eb->start = start; |
4384 | eb->len = len; | 4382 | eb->len = len; |
4385 | eb->tree = tree; | 4383 | eb->fs_info = fs_info; |
4386 | eb->bflags = 0; | 4384 | eb->bflags = 0; |
4387 | rwlock_init(&eb->lock); | 4385 | rwlock_init(&eb->lock); |
4388 | atomic_set(&eb->write_locks, 0); | 4386 | atomic_set(&eb->write_locks, 0); |
@@ -4514,13 +4512,14 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb) | |||
4514 | } | 4512 | } |
4515 | } | 4513 | } |
4516 | 4514 | ||
4517 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | 4515 | struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, |
4518 | u64 start) | 4516 | u64 start) |
4519 | { | 4517 | { |
4520 | struct extent_buffer *eb; | 4518 | struct extent_buffer *eb; |
4521 | 4519 | ||
4522 | rcu_read_lock(); | 4520 | rcu_read_lock(); |
4523 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | 4521 | eb = radix_tree_lookup(&fs_info->buffer_radix, |
4522 | start >> PAGE_CACHE_SHIFT); | ||
4524 | if (eb && atomic_inc_not_zero(&eb->refs)) { | 4523 | if (eb && atomic_inc_not_zero(&eb->refs)) { |
4525 | rcu_read_unlock(); | 4524 | rcu_read_unlock(); |
4526 | mark_extent_buffer_accessed(eb); | 4525 | mark_extent_buffer_accessed(eb); |
@@ -4531,7 +4530,7 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | |||
4531 | return NULL; | 4530 | return NULL; |
4532 | } | 4531 | } |
4533 | 4532 | ||
4534 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | 4533 | struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, |
4535 | u64 start, unsigned long len) | 4534 | u64 start, unsigned long len) |
4536 | { | 4535 | { |
4537 | unsigned long num_pages = num_extent_pages(start, len); | 4536 | unsigned long num_pages = num_extent_pages(start, len); |
@@ -4540,16 +4539,15 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
4540 | struct extent_buffer *eb; | 4539 | struct extent_buffer *eb; |
4541 | struct extent_buffer *exists = NULL; | 4540 | struct extent_buffer *exists = NULL; |
4542 | struct page *p; | 4541 | struct page *p; |
4543 | struct address_space *mapping = tree->mapping; | 4542 | struct address_space *mapping = fs_info->btree_inode->i_mapping; |
4544 | int uptodate = 1; | 4543 | int uptodate = 1; |
4545 | int ret; | 4544 | int ret; |
4546 | 4545 | ||
4547 | 4546 | eb = find_extent_buffer(fs_info, start); | |
4548 | eb = find_extent_buffer(tree, start); | ||
4549 | if (eb) | 4547 | if (eb) |
4550 | return eb; | 4548 | return eb; |
4551 | 4549 | ||
4552 | eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); | 4550 | eb = __alloc_extent_buffer(fs_info, start, len, GFP_NOFS); |
4553 | if (!eb) | 4551 | if (!eb) |
4554 | return NULL; | 4552 | return NULL; |
4555 | 4553 | ||
@@ -4604,12 +4602,13 @@ again: | |||
4604 | if (ret) | 4602 | if (ret) |
4605 | goto free_eb; | 4603 | goto free_eb; |
4606 | 4604 | ||
4607 | spin_lock(&tree->buffer_lock); | 4605 | spin_lock(&fs_info->buffer_lock); |
4608 | ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); | 4606 | ret = radix_tree_insert(&fs_info->buffer_radix, |
4609 | spin_unlock(&tree->buffer_lock); | 4607 | start >> PAGE_CACHE_SHIFT, eb); |
4608 | spin_unlock(&fs_info->buffer_lock); | ||
4610 | radix_tree_preload_end(); | 4609 | radix_tree_preload_end(); |
4611 | if (ret == -EEXIST) { | 4610 | if (ret == -EEXIST) { |
4612 | exists = find_extent_buffer(tree, start); | 4611 | exists = find_extent_buffer(fs_info, start); |
4613 | if (exists) | 4612 | if (exists) |
4614 | goto free_eb; | 4613 | goto free_eb; |
4615 | else | 4614 | else |
@@ -4662,14 +4661,14 @@ static int release_extent_buffer(struct extent_buffer *eb) | |||
4662 | WARN_ON(atomic_read(&eb->refs) == 0); | 4661 | WARN_ON(atomic_read(&eb->refs) == 0); |
4663 | if (atomic_dec_and_test(&eb->refs)) { | 4662 | if (atomic_dec_and_test(&eb->refs)) { |
4664 | if (test_and_clear_bit(EXTENT_BUFFER_IN_TREE, &eb->bflags)) { | 4663 | if (test_and_clear_bit(EXTENT_BUFFER_IN_TREE, &eb->bflags)) { |
4665 | struct extent_io_tree *tree = eb->tree; | 4664 | struct btrfs_fs_info *fs_info = eb->fs_info; |
4666 | 4665 | ||
4667 | spin_unlock(&eb->refs_lock); | 4666 | spin_unlock(&eb->refs_lock); |
4668 | 4667 | ||
4669 | spin_lock(&tree->buffer_lock); | 4668 | spin_lock(&fs_info->buffer_lock); |
4670 | radix_tree_delete(&tree->buffer, | 4669 | radix_tree_delete(&fs_info->buffer_radix, |
4671 | eb->start >> PAGE_CACHE_SHIFT); | 4670 | eb->start >> PAGE_CACHE_SHIFT); |
4672 | spin_unlock(&tree->buffer_lock); | 4671 | spin_unlock(&fs_info->buffer_lock); |
4673 | } else { | 4672 | } else { |
4674 | spin_unlock(&eb->refs_lock); | 4673 | spin_unlock(&eb->refs_lock); |
4675 | } | 4674 | } |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 92e4347315e6..58b27e5ab521 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -95,12 +95,10 @@ struct extent_io_ops { | |||
95 | 95 | ||
96 | struct extent_io_tree { | 96 | struct extent_io_tree { |
97 | struct rb_root state; | 97 | struct rb_root state; |
98 | struct radix_tree_root buffer; | ||
99 | struct address_space *mapping; | 98 | struct address_space *mapping; |
100 | u64 dirty_bytes; | 99 | u64 dirty_bytes; |
101 | int track_uptodate; | 100 | int track_uptodate; |
102 | spinlock_t lock; | 101 | spinlock_t lock; |
103 | spinlock_t buffer_lock; | ||
104 | struct extent_io_ops *ops; | 102 | struct extent_io_ops *ops; |
105 | }; | 103 | }; |
106 | 104 | ||
@@ -131,7 +129,7 @@ struct extent_buffer { | |||
131 | unsigned long map_start; | 129 | unsigned long map_start; |
132 | unsigned long map_len; | 130 | unsigned long map_len; |
133 | unsigned long bflags; | 131 | unsigned long bflags; |
134 | struct extent_io_tree *tree; | 132 | struct btrfs_fs_info *fs_info; |
135 | spinlock_t refs_lock; | 133 | spinlock_t refs_lock; |
136 | atomic_t refs; | 134 | atomic_t refs; |
137 | atomic_t io_pages; | 135 | atomic_t io_pages; |
@@ -267,11 +265,11 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
267 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); | 265 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); |
268 | void set_page_extent_mapped(struct page *page); | 266 | void set_page_extent_mapped(struct page *page); |
269 | 267 | ||
270 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | 268 | struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, |
271 | u64 start, unsigned long len); | 269 | u64 start, unsigned long len); |
272 | struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len); | 270 | struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len); |
273 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); | 271 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); |
274 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | 272 | struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, |
275 | u64 start); | 273 | u64 start); |
276 | void free_extent_buffer(struct extent_buffer *eb); | 274 | void free_extent_buffer(struct extent_buffer *eb); |
277 | void free_extent_buffer_stale(struct extent_buffer *eb); | 275 | void free_extent_buffer_stale(struct extent_buffer *eb); |