diff options
| author | Chris Mason <chris.mason@oracle.com> | 2011-11-10 20:42:53 -0500 | 
|---|---|---|
| committer | Chris Mason <chris.mason@oracle.com> | 2011-11-10 20:42:53 -0500 | 
| commit | f7d572188b7b2a6d07081688f8602dc407186e64 (patch) | |
| tree | d6a386fbe7c44afcb05847e1f9d1405583b0fff9 | |
| parent | 2115133f8b9a8dbdb217d14080814df07ce90479 (diff) | |
| parent | 04d21a244fdf79d0ac892eaaa9a46b682467277c (diff) | |
| download | olio-linux-3.10-f7d572188b7b2a6d07081688f8602dc407186e64.tar.xz olio-linux-3.10-f7d572188b7b2a6d07081688f8602dc407186e64.zip  | |
Merge branch 'mount-fixes' of git://github.com/idryomov/btrfs-unstable into integration
| -rw-r--r-- | fs/btrfs/disk-io.c | 42 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 47 | 
2 files changed, 43 insertions, 46 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e53a5bb8567..b6a5c0dd0dd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1890,31 +1890,32 @@ struct btrfs_root *open_ctree(struct super_block *sb,  	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), -						 GFP_NOFS); +	struct btrfs_super_block *disk_super;  	struct btrfs_root *tree_root = btrfs_sb(sb); -	struct btrfs_fs_info *fs_info = NULL; -	struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), -						GFP_NOFS); -	struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), -					      GFP_NOFS); +	struct btrfs_fs_info *fs_info = tree_root->fs_info; +	struct btrfs_root *extent_root; +	struct btrfs_root *csum_root; +	struct btrfs_root *chunk_root; +	struct btrfs_root *dev_root;  	struct btrfs_root *log_tree_root; -  	int ret;  	int err = -EINVAL;  	int num_backups_tried = 0;  	int backup_index = 0; -	struct btrfs_super_block *disk_super; +	extent_root = fs_info->extent_root = +		kzalloc(sizeof(struct btrfs_root), GFP_NOFS); +	csum_root = fs_info->csum_root = +		kzalloc(sizeof(struct btrfs_root), GFP_NOFS); +	chunk_root = fs_info->chunk_root = +		kzalloc(sizeof(struct btrfs_root), GFP_NOFS); +	dev_root = fs_info->dev_root = +		kzalloc(sizeof(struct btrfs_root), GFP_NOFS); -	if (!extent_root || !tree_root || !tree_root->fs_info || -	    !chunk_root || !dev_root || !csum_root) { +	if (!extent_root || !csum_root || !chunk_root || !dev_root) {  		err = -ENOMEM;  		goto fail;  	} -	fs_info = tree_root->fs_info;  	ret = init_srcu_struct(&fs_info->subvol_srcu);  	if (ret) { @@ -1954,12 +1955,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,  	mutex_init(&fs_info->reloc_mutex);  	init_completion(&fs_info->kobj_unregister); -	fs_info->tree_root = tree_root; -	fs_info->extent_root = extent_root; -	fs_info->csum_root = csum_root; -	fs_info->chunk_root = chunk_root; -	fs_info->dev_root = dev_root; -	fs_info->fs_devices = fs_devices;  	INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);  	INIT_LIST_HEAD(&fs_info->space_info);  	btrfs_mapping_init(&fs_info->mapping_tree); @@ -2465,21 +2460,20 @@ fail_sb_buffer:  	btrfs_stop_workers(&fs_info->caching_workers);  fail_alloc:  fail_iput: +	btrfs_mapping_tree_free(&fs_info->mapping_tree); +  	invalidate_inode_pages2(fs_info->btree_inode->i_mapping);  	iput(fs_info->btree_inode); - -	btrfs_close_devices(fs_info->fs_devices); -	btrfs_mapping_tree_free(&fs_info->mapping_tree);  fail_bdi:  	bdi_destroy(&fs_info->bdi);  fail_srcu:  	cleanup_srcu_struct(&fs_info->subvol_srcu);  fail: +	btrfs_close_devices(fs_info->fs_devices);  	free_fs_info(fs_info);  	return ERR_PTR(err);  recovery_tree_root: -  	if (!btrfs_test_opt(tree_root, RECOVERY))  		goto fail_tree_roots; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index dcd5aef6b61..629281c65ff 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -448,6 +448,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,  		token = match_token(p, tokens, args);  		switch (token) {  		case Opt_subvol: +			kfree(*subvol_name);  			*subvol_name = match_strdup(&args[0]);  			break;  		case Opt_subvolid: @@ -890,7 +891,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  	struct super_block *s;  	struct dentry *root;  	struct btrfs_fs_devices *fs_devices = NULL; -	struct btrfs_root *tree_root = NULL;  	struct btrfs_fs_info *fs_info = NULL;  	fmode_t mode = FMODE_READ;  	char *subvol_name = NULL; @@ -904,8 +904,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  	error = btrfs_parse_early_options(data, mode, fs_type,  					  &subvol_name, &subvol_objectid,  					  &subvol_rootid, &fs_devices); -	if (error) +	if (error) { +		kfree(subvol_name);  		return ERR_PTR(error); +	}  	if (subvol_name) {  		root = mount_subvol(subvol_name, flags, device_name, data); @@ -917,15 +919,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  	if (error)  		return ERR_PTR(error); -	error = btrfs_open_devices(fs_devices, mode, fs_type); -	if (error) -		return ERR_PTR(error); - -	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { -		error = -EACCES; -		goto error_close_devices; -	} -  	/*  	 * Setup a dummy root and fs_info for test/set super.  This is because  	 * we don't actually fill this stuff out until open_ctree, but we need @@ -933,28 +926,36 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  	 * then open_ctree will properly initialize everything later.  	 */  	fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); -	if (!fs_info) { -		error = -ENOMEM; -		goto error_close_devices; -	} -	tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); -	if (!tree_root) { +	if (!fs_info) +		return ERR_PTR(-ENOMEM); + +	fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); +	if (!fs_info->tree_root) {  		error = -ENOMEM; -		goto error_close_devices; +		goto error_fs_info;  	} -	fs_info->tree_root = tree_root; +	fs_info->tree_root->fs_info = fs_info;  	fs_info->fs_devices = fs_devices; -	tree_root->fs_info = fs_info;  	fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);  	fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);  	if (!fs_info->super_copy || !fs_info->super_for_commit) {  		error = -ENOMEM; +		goto error_fs_info; +	} + +	error = btrfs_open_devices(fs_devices, mode, fs_type); +	if (error) +		goto error_fs_info; + +	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { +		error = -EACCES;  		goto error_close_devices;  	}  	bdev = fs_devices->latest_bdev; -	s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); +	s = sget(fs_type, btrfs_test_super, btrfs_set_super, +		 fs_info->tree_root);  	if (IS_ERR(s)) {  		error = PTR_ERR(s);  		goto error_close_devices; @@ -963,7 +964,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  	if (s->s_root) {  		if ((flags ^ s->s_flags) & MS_RDONLY) {  			deactivate_locked_super(s); -			return ERR_PTR(-EBUSY); +			error = -EBUSY; +			goto error_close_devices;  		}  		btrfs_close_devices(fs_devices); @@ -994,6 +996,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,  error_close_devices:  	btrfs_close_devices(fs_devices); +error_fs_info:  	free_fs_info(fs_info);  	return ERR_PTR(error);  }  |