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 /fs | |
parent | 2115133f8b9a8dbdb217d14080814df07ce90479 (diff) | |
parent | 04d21a244fdf79d0ac892eaaa9a46b682467277c (diff) |
Merge branch 'mount-fixes' of git://github.com/idryomov/btrfs-unstable into integration
Diffstat (limited to 'fs')
-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 e53a5bb85670..b6a5c0dd0dd8 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, | |||
1890 | u64 features; | 1890 | u64 features; |
1891 | struct btrfs_key location; | 1891 | struct btrfs_key location; |
1892 | struct buffer_head *bh; | 1892 | struct buffer_head *bh; |
1893 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), | 1893 | struct btrfs_super_block *disk_super; |
1894 | GFP_NOFS); | ||
1895 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | ||
1896 | GFP_NOFS); | ||
1897 | struct btrfs_root *tree_root = btrfs_sb(sb); | 1894 | struct btrfs_root *tree_root = btrfs_sb(sb); |
1898 | struct btrfs_fs_info *fs_info = NULL; | 1895 | struct btrfs_fs_info *fs_info = tree_root->fs_info; |
1899 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1896 | struct btrfs_root *extent_root; |
1900 | GFP_NOFS); | 1897 | struct btrfs_root *csum_root; |
1901 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1898 | struct btrfs_root *chunk_root; |
1902 | GFP_NOFS); | 1899 | struct btrfs_root *dev_root; |
1903 | struct btrfs_root *log_tree_root; | 1900 | struct btrfs_root *log_tree_root; |
1904 | |||
1905 | int ret; | 1901 | int ret; |
1906 | int err = -EINVAL; | 1902 | int err = -EINVAL; |
1907 | int num_backups_tried = 0; | 1903 | int num_backups_tried = 0; |
1908 | int backup_index = 0; | 1904 | int backup_index = 0; |
1909 | 1905 | ||
1910 | struct btrfs_super_block *disk_super; | 1906 | extent_root = fs_info->extent_root = |
1907 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1908 | csum_root = fs_info->csum_root = | ||
1909 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1910 | chunk_root = fs_info->chunk_root = | ||
1911 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1912 | dev_root = fs_info->dev_root = | ||
1913 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1911 | 1914 | ||
1912 | if (!extent_root || !tree_root || !tree_root->fs_info || | 1915 | if (!extent_root || !csum_root || !chunk_root || !dev_root) { |
1913 | !chunk_root || !dev_root || !csum_root) { | ||
1914 | err = -ENOMEM; | 1916 | err = -ENOMEM; |
1915 | goto fail; | 1917 | goto fail; |
1916 | } | 1918 | } |
1917 | fs_info = tree_root->fs_info; | ||
1918 | 1919 | ||
1919 | ret = init_srcu_struct(&fs_info->subvol_srcu); | 1920 | ret = init_srcu_struct(&fs_info->subvol_srcu); |
1920 | if (ret) { | 1921 | if (ret) { |
@@ -1954,12 +1955,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1954 | mutex_init(&fs_info->reloc_mutex); | 1955 | mutex_init(&fs_info->reloc_mutex); |
1955 | 1956 | ||
1956 | init_completion(&fs_info->kobj_unregister); | 1957 | init_completion(&fs_info->kobj_unregister); |
1957 | fs_info->tree_root = tree_root; | ||
1958 | fs_info->extent_root = extent_root; | ||
1959 | fs_info->csum_root = csum_root; | ||
1960 | fs_info->chunk_root = chunk_root; | ||
1961 | fs_info->dev_root = dev_root; | ||
1962 | fs_info->fs_devices = fs_devices; | ||
1963 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 1958 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
1964 | INIT_LIST_HEAD(&fs_info->space_info); | 1959 | INIT_LIST_HEAD(&fs_info->space_info); |
1965 | btrfs_mapping_init(&fs_info->mapping_tree); | 1960 | btrfs_mapping_init(&fs_info->mapping_tree); |
@@ -2465,21 +2460,20 @@ fail_sb_buffer: | |||
2465 | btrfs_stop_workers(&fs_info->caching_workers); | 2460 | btrfs_stop_workers(&fs_info->caching_workers); |
2466 | fail_alloc: | 2461 | fail_alloc: |
2467 | fail_iput: | 2462 | fail_iput: |
2463 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | ||
2464 | |||
2468 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2465 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2469 | iput(fs_info->btree_inode); | 2466 | iput(fs_info->btree_inode); |
2470 | |||
2471 | btrfs_close_devices(fs_info->fs_devices); | ||
2472 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | ||
2473 | fail_bdi: | 2467 | fail_bdi: |
2474 | bdi_destroy(&fs_info->bdi); | 2468 | bdi_destroy(&fs_info->bdi); |
2475 | fail_srcu: | 2469 | fail_srcu: |
2476 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 2470 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
2477 | fail: | 2471 | fail: |
2472 | btrfs_close_devices(fs_info->fs_devices); | ||
2478 | free_fs_info(fs_info); | 2473 | free_fs_info(fs_info); |
2479 | return ERR_PTR(err); | 2474 | return ERR_PTR(err); |
2480 | 2475 | ||
2481 | recovery_tree_root: | 2476 | recovery_tree_root: |
2482 | |||
2483 | if (!btrfs_test_opt(tree_root, RECOVERY)) | 2477 | if (!btrfs_test_opt(tree_root, RECOVERY)) |
2484 | goto fail_tree_roots; | 2478 | goto fail_tree_roots; |
2485 | 2479 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index dcd5aef6b614..629281c65ff5 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, | |||
448 | token = match_token(p, tokens, args); | 448 | token = match_token(p, tokens, args); |
449 | switch (token) { | 449 | switch (token) { |
450 | case Opt_subvol: | 450 | case Opt_subvol: |
451 | kfree(*subvol_name); | ||
451 | *subvol_name = match_strdup(&args[0]); | 452 | *subvol_name = match_strdup(&args[0]); |
452 | break; | 453 | break; |
453 | case Opt_subvolid: | 454 | case Opt_subvolid: |
@@ -890,7 +891,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
890 | struct super_block *s; | 891 | struct super_block *s; |
891 | struct dentry *root; | 892 | struct dentry *root; |
892 | struct btrfs_fs_devices *fs_devices = NULL; | 893 | struct btrfs_fs_devices *fs_devices = NULL; |
893 | struct btrfs_root *tree_root = NULL; | ||
894 | struct btrfs_fs_info *fs_info = NULL; | 894 | struct btrfs_fs_info *fs_info = NULL; |
895 | fmode_t mode = FMODE_READ; | 895 | fmode_t mode = FMODE_READ; |
896 | char *subvol_name = NULL; | 896 | char *subvol_name = NULL; |
@@ -904,8 +904,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
904 | error = btrfs_parse_early_options(data, mode, fs_type, | 904 | error = btrfs_parse_early_options(data, mode, fs_type, |
905 | &subvol_name, &subvol_objectid, | 905 | &subvol_name, &subvol_objectid, |
906 | &subvol_rootid, &fs_devices); | 906 | &subvol_rootid, &fs_devices); |
907 | if (error) | 907 | if (error) { |
908 | kfree(subvol_name); | ||
908 | return ERR_PTR(error); | 909 | return ERR_PTR(error); |
910 | } | ||
909 | 911 | ||
910 | if (subvol_name) { | 912 | if (subvol_name) { |
911 | root = mount_subvol(subvol_name, flags, device_name, data); | 913 | 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, | |||
917 | if (error) | 919 | if (error) |
918 | return ERR_PTR(error); | 920 | return ERR_PTR(error); |
919 | 921 | ||
920 | error = btrfs_open_devices(fs_devices, mode, fs_type); | ||
921 | if (error) | ||
922 | return ERR_PTR(error); | ||
923 | |||
924 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { | ||
925 | error = -EACCES; | ||
926 | goto error_close_devices; | ||
927 | } | ||
928 | |||
929 | /* | 922 | /* |
930 | * Setup a dummy root and fs_info for test/set super. This is because | 923 | * Setup a dummy root and fs_info for test/set super. This is because |
931 | * we don't actually fill this stuff out until open_ctree, but we need | 924 | * 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, | |||
933 | * then open_ctree will properly initialize everything later. | 926 | * then open_ctree will properly initialize everything later. |
934 | */ | 927 | */ |
935 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); | 928 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); |
936 | if (!fs_info) { | 929 | if (!fs_info) |
937 | error = -ENOMEM; | 930 | return ERR_PTR(-ENOMEM); |
938 | goto error_close_devices; | 931 | |
939 | } | 932 | fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); |
940 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 933 | if (!fs_info->tree_root) { |
941 | if (!tree_root) { | ||
942 | error = -ENOMEM; | 934 | error = -ENOMEM; |
943 | goto error_close_devices; | 935 | goto error_fs_info; |
944 | } | 936 | } |
945 | fs_info->tree_root = tree_root; | 937 | fs_info->tree_root->fs_info = fs_info; |
946 | fs_info->fs_devices = fs_devices; | 938 | fs_info->fs_devices = fs_devices; |
947 | tree_root->fs_info = fs_info; | ||
948 | 939 | ||
949 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 940 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
950 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 941 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
951 | if (!fs_info->super_copy || !fs_info->super_for_commit) { | 942 | if (!fs_info->super_copy || !fs_info->super_for_commit) { |
952 | error = -ENOMEM; | 943 | error = -ENOMEM; |
944 | goto error_fs_info; | ||
945 | } | ||
946 | |||
947 | error = btrfs_open_devices(fs_devices, mode, fs_type); | ||
948 | if (error) | ||
949 | goto error_fs_info; | ||
950 | |||
951 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { | ||
952 | error = -EACCES; | ||
953 | goto error_close_devices; | 953 | goto error_close_devices; |
954 | } | 954 | } |
955 | 955 | ||
956 | bdev = fs_devices->latest_bdev; | 956 | bdev = fs_devices->latest_bdev; |
957 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); | 957 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, |
958 | fs_info->tree_root); | ||
958 | if (IS_ERR(s)) { | 959 | if (IS_ERR(s)) { |
959 | error = PTR_ERR(s); | 960 | error = PTR_ERR(s); |
960 | goto error_close_devices; | 961 | goto error_close_devices; |
@@ -963,7 +964,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
963 | if (s->s_root) { | 964 | if (s->s_root) { |
964 | if ((flags ^ s->s_flags) & MS_RDONLY) { | 965 | if ((flags ^ s->s_flags) & MS_RDONLY) { |
965 | deactivate_locked_super(s); | 966 | deactivate_locked_super(s); |
966 | return ERR_PTR(-EBUSY); | 967 | error = -EBUSY; |
968 | goto error_close_devices; | ||
967 | } | 969 | } |
968 | 970 | ||
969 | btrfs_close_devices(fs_devices); | 971 | btrfs_close_devices(fs_devices); |
@@ -994,6 +996,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
994 | 996 | ||
995 | error_close_devices: | 997 | error_close_devices: |
996 | btrfs_close_devices(fs_devices); | 998 | btrfs_close_devices(fs_devices); |
999 | error_fs_info: | ||
997 | free_fs_info(fs_info); | 1000 | free_fs_info(fs_info); |
998 | return ERR_PTR(error); | 1001 | return ERR_PTR(error); |
999 | } | 1002 | } |