[PATCH] btrfs: separate fs_info allocation from open_ctree()

From: Pekka Enberg
Date: Thu Jul 23 2009 - 14:15:05 EST


From: Pekka Enberg <penberg@xxxxxxxxxxxxxx>

The open_ctree() function is huge so lets move fs_info allocation to a
separate function to clean it up a bit.

Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxxxxxx>
---
fs/btrfs/disk-io.c | 163 ++++++++++++++++++++++++++++-----------------------
1 files changed, 89 insertions(+), 74 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d28d29c..7ea94c1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1520,19 +1520,8 @@ sleep:
return 0;
}

-struct btrfs_root *open_ctree(struct super_block *sb,
- struct btrfs_fs_devices *fs_devices,
- char *options)
+static struct btrfs_fs_info *btrfs_alloc_fs_info(struct super_block *sb, struct btrfs_fs_devices *fs_devices)
{
- u32 sectorsize;
- u32 nodesize;
- u32 leafsize;
- u32 blocksize;
- u32 stripesize;
- u64 generation;
- u64 features;
- struct btrfs_key location;
- struct buffer_head *bh;
struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root),
GFP_NOFS);
struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
@@ -1545,13 +1534,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
GFP_NOFS);
struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
GFP_NOFS);
- struct btrfs_root *log_tree_root;

- int ret;
int err = -EINVAL;

- struct btrfs_super_block *disk_super;
-
if (!extent_root || !tree_root || !fs_info ||
!chunk_root || !dev_root || !csum_root) {
err = -ENOMEM;
@@ -1646,8 +1631,46 @@ struct btrfs_root *open_ctree(struct super_block *sb,
init_waitqueue_head(&fs_info->transaction_throttle);
init_waitqueue_head(&fs_info->transaction_wait);
init_waitqueue_head(&fs_info->async_submit_wait);
+ return fs_info;

- __setup_root(4096, 4096, 4096, 4096, tree_root,
+fail_bdi:
+ bdi_destroy(&fs_info->bdi);
+fail:
+ kfree(extent_root);
+ kfree(tree_root);
+ kfree(fs_info);
+ kfree(chunk_root);
+ kfree(dev_root);
+ kfree(csum_root);
+
+ return ERR_PTR(err);
+}
+
+struct btrfs_root *open_ctree(struct super_block *sb,
+ struct btrfs_fs_devices *fs_devices,
+ char *options)
+{
+ struct btrfs_super_block *disk_super;
+ struct btrfs_root *log_tree_root;
+ struct btrfs_fs_info *fs_info;
+ struct btrfs_key location;
+ struct buffer_head *bh;
+ int ret, err = -EINVAL;
+ u32 sectorsize;
+ u32 nodesize;
+ u32 leafsize;
+ u32 blocksize;
+ u32 stripesize;
+ u64 generation;
+ u64 features;
+
+ fs_info = btrfs_alloc_fs_info(sb, fs_devices);
+ if (IS_ERR(fs_info)) {
+ err = PTR_ERR(fs_info);
+ goto fail;
+ }
+
+ __setup_root(4096, 4096, 4096, 4096, fs_info->tree_root,
fs_info, BTRFS_ROOT_TREE_OBJECTID);


@@ -1666,7 +1689,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
if (!btrfs_super_root(disk_super))
goto fail_iput;

- ret = btrfs_parse_options(tree_root, options);
+ ret = btrfs_parse_options(fs_info->tree_root, options);
if (ret) {
err = ret;
goto fail_iput;
@@ -1765,10 +1788,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
leafsize = btrfs_super_leafsize(disk_super);
sectorsize = btrfs_super_sectorsize(disk_super);
stripesize = btrfs_super_stripesize(disk_super);
- tree_root->nodesize = nodesize;
- tree_root->leafsize = leafsize;
- tree_root->sectorsize = sectorsize;
- tree_root->stripesize = stripesize;
+ fs_info->tree_root->nodesize = nodesize;
+ fs_info->tree_root->leafsize = leafsize;
+ fs_info->tree_root->sectorsize = sectorsize;
+ fs_info->tree_root->stripesize = stripesize;

sb->s_blocksize = sectorsize;
sb->s_blocksize_bits = blksize_bits(sectorsize);
@@ -1780,7 +1803,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
}

mutex_lock(&fs_info->chunk_mutex);
- ret = btrfs_read_sys_array(tree_root);
+ ret = btrfs_read_sys_array(fs_info->tree_root);
mutex_unlock(&fs_info->chunk_mutex);
if (ret) {
printk(KERN_WARNING "btrfs: failed to read the system "
@@ -1788,26 +1811,26 @@ struct btrfs_root *open_ctree(struct super_block *sb,
goto fail_sb_buffer;
}

- blocksize = btrfs_level_size(tree_root,
+ blocksize = btrfs_level_size(fs_info->tree_root,
btrfs_super_chunk_root_level(disk_super));
generation = btrfs_super_chunk_root_generation(disk_super);

__setup_root(nodesize, leafsize, sectorsize, stripesize,
- chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
+ fs_info->chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);

- chunk_root->node = read_tree_block(chunk_root,
+ fs_info->chunk_root->node = read_tree_block(fs_info->chunk_root,
btrfs_super_chunk_root(disk_super),
blocksize, generation);
- BUG_ON(!chunk_root->node);
- btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
- chunk_root->commit_root = btrfs_root_node(chunk_root);
+ BUG_ON(!fs_info->chunk_root->node);
+ btrfs_set_root_node(&fs_info->chunk_root->root_item, fs_info->chunk_root->node);
+ fs_info->chunk_root->commit_root = btrfs_root_node(fs_info->chunk_root);

- read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
- (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
+ read_extent_buffer(fs_info->chunk_root->node, fs_info->chunk_tree_uuid,
+ (unsigned long)btrfs_header_chunk_tree_uuid(fs_info->chunk_root->node),
BTRFS_UUID_SIZE);

mutex_lock(&fs_info->chunk_mutex);
- ret = btrfs_read_chunk_tree(chunk_root);
+ ret = btrfs_read_chunk_tree(fs_info->chunk_root);
mutex_unlock(&fs_info->chunk_mutex);
if (ret) {
printk(KERN_WARNING "btrfs: failed to read chunk tree on %s\n",
@@ -1817,57 +1840,57 @@ struct btrfs_root *open_ctree(struct super_block *sb,

btrfs_close_extra_devices(fs_devices);

- blocksize = btrfs_level_size(tree_root,
+ blocksize = btrfs_level_size(fs_info->tree_root,
btrfs_super_root_level(disk_super));
generation = btrfs_super_generation(disk_super);

- tree_root->node = read_tree_block(tree_root,
+ fs_info->tree_root->node = read_tree_block(fs_info->tree_root,
btrfs_super_root(disk_super),
blocksize, generation);
- if (!tree_root->node)
+ if (!fs_info->tree_root->node)
goto fail_chunk_root;
- btrfs_set_root_node(&tree_root->root_item, tree_root->node);
- tree_root->commit_root = btrfs_root_node(tree_root);
+ btrfs_set_root_node(&fs_info->tree_root->root_item, fs_info->tree_root->node);
+ fs_info->tree_root->commit_root = btrfs_root_node(fs_info->tree_root);

- ret = find_and_setup_root(tree_root, fs_info,
- BTRFS_EXTENT_TREE_OBJECTID, extent_root);
+ ret = find_and_setup_root(fs_info->tree_root, fs_info,
+ BTRFS_EXTENT_TREE_OBJECTID, fs_info->extent_root);
if (ret)
goto fail_tree_root;
- extent_root->track_dirty = 1;
+ fs_info->extent_root->track_dirty = 1;

- ret = find_and_setup_root(tree_root, fs_info,
- BTRFS_DEV_TREE_OBJECTID, dev_root);
+ ret = find_and_setup_root(fs_info->tree_root, fs_info,
+ BTRFS_DEV_TREE_OBJECTID, fs_info->dev_root);
if (ret)
goto fail_extent_root;
- dev_root->track_dirty = 1;
+ fs_info->dev_root->track_dirty = 1;

- ret = find_and_setup_root(tree_root, fs_info,
- BTRFS_CSUM_TREE_OBJECTID, csum_root);
+ ret = find_and_setup_root(fs_info->tree_root, fs_info,
+ BTRFS_CSUM_TREE_OBJECTID, fs_info->csum_root);
if (ret)
goto fail_dev_root;

- csum_root->track_dirty = 1;
+ fs_info->csum_root->track_dirty = 1;

- btrfs_read_block_groups(extent_root);
+ btrfs_read_block_groups(fs_info->extent_root);

fs_info->generation = generation;
fs_info->last_trans_committed = generation;
fs_info->data_alloc_profile = (u64)-1;
fs_info->metadata_alloc_profile = (u64)-1;
fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
- fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
+ fs_info->cleaner_kthread = kthread_run(cleaner_kthread, fs_info->tree_root,
"btrfs-cleaner");
if (IS_ERR(fs_info->cleaner_kthread))
goto fail_csum_root;

fs_info->transaction_kthread = kthread_run(transaction_kthread,
- tree_root,
+ fs_info->tree_root,
"btrfs-transaction");
if (IS_ERR(fs_info->transaction_kthread))
goto fail_cleaner;

- if (!btrfs_test_opt(tree_root, SSD) &&
- !btrfs_test_opt(tree_root, NOSSD) &&
+ if (!btrfs_test_opt(fs_info->tree_root, SSD) &&
+ !btrfs_test_opt(fs_info->tree_root, NOSSD) &&
!fs_info->fs_devices->rotating) {
printk(KERN_INFO "Btrfs detected SSD devices, enabling SSD "
"mode\n");
@@ -1884,7 +1907,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
goto fail_trans_kthread;
}
blocksize =
- btrfs_level_size(tree_root,
+ btrfs_level_size(fs_info->tree_root,
btrfs_super_log_root_level(disk_super));

log_tree_root = kzalloc(sizeof(struct btrfs_root),
@@ -1893,20 +1916,20 @@ struct btrfs_root *open_ctree(struct super_block *sb,
__setup_root(nodesize, leafsize, sectorsize, stripesize,
log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);

- log_tree_root->node = read_tree_block(tree_root, bytenr,
+ log_tree_root->node = read_tree_block(fs_info->tree_root, bytenr,
blocksize,
generation + 1);
ret = btrfs_recover_log_trees(log_tree_root);
BUG_ON(ret);

if (sb->s_flags & MS_RDONLY) {
- ret = btrfs_commit_super(tree_root);
+ ret = btrfs_commit_super(fs_info->tree_root);
BUG_ON(ret);
}
}

if (!(sb->s_flags & MS_RDONLY)) {
- ret = btrfs_recover_relocation(tree_root);
+ ret = btrfs_recover_relocation(fs_info->tree_root);
BUG_ON(ret);
}

@@ -1918,7 +1941,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
if (!fs_info->fs_root)
goto fail_trans_kthread;

- return tree_root;
+ return fs_info->tree_root;

fail_trans_kthread:
kthread_stop(fs_info->transaction_kthread);
@@ -1933,20 +1956,20 @@ fail_cleaner:
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);

fail_csum_root:
- free_extent_buffer(csum_root->node);
- free_extent_buffer(csum_root->commit_root);
+ free_extent_buffer(fs_info->csum_root->node);
+ free_extent_buffer(fs_info->csum_root->commit_root);
fail_dev_root:
- free_extent_buffer(dev_root->node);
- free_extent_buffer(dev_root->commit_root);
+ free_extent_buffer(fs_info->dev_root->node);
+ free_extent_buffer(fs_info->dev_root->commit_root);
fail_extent_root:
- free_extent_buffer(extent_root->node);
- free_extent_buffer(extent_root->commit_root);
+ free_extent_buffer(fs_info->extent_root->node);
+ free_extent_buffer(fs_info->extent_root->commit_root);
fail_tree_root:
- free_extent_buffer(tree_root->node);
- free_extent_buffer(tree_root->commit_root);
+ free_extent_buffer(fs_info->tree_root->node);
+ free_extent_buffer(fs_info->tree_root->commit_root);
fail_chunk_root:
- free_extent_buffer(chunk_root->node);
- free_extent_buffer(chunk_root->commit_root);
+ free_extent_buffer(fs_info->chunk_root->node);
+ free_extent_buffer(fs_info->chunk_root->commit_root);
fail_sb_buffer:
btrfs_stop_workers(&fs_info->fixup_workers);
btrfs_stop_workers(&fs_info->delalloc_workers);
@@ -1962,15 +1985,7 @@ fail_iput:

btrfs_close_devices(fs_info->fs_devices);
btrfs_mapping_tree_free(&fs_info->mapping_tree);
-fail_bdi:
- bdi_destroy(&fs_info->bdi);
fail:
- kfree(extent_root);
- kfree(tree_root);
- kfree(fs_info);
- kfree(chunk_root);
- kfree(dev_root);
- kfree(csum_root);
return ERR_PTR(err);
}

--
1.5.6.3



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/