diff options
author | David Sterba <dsterba@suse.cz> | 2011-04-13 09:41:04 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-11-06 03:04:01 -0500 |
commit | 6c41761fc6efe1503103a1afe03a6635c0b5d4ec (patch) | |
tree | 08ad34d43aac48e8f8143a0b1fa07141df8f202a /fs/btrfs/super.c | |
parent | c8174313a8102e874aaa321e2fc4c7c460a87151 (diff) |
btrfs: separate superblock items out of fs_info
fs_info has now ~9kb, more than fits into one page. This will cause
mount failure when memory is too fragmented. Top space consumers are
super block structures super_copy and super_for_commit, ~2.8kb each.
Allocate them dynamically. fs_info will be ~3.5kb. (measured on x86_64)
Add a wrapper for freeing fs_info and all of it's dynamically allocated
members.
Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 5429b1fa0bfc..f7e9de724ef2 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -216,7 +216,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
216 | char *compress_type; | 216 | char *compress_type; |
217 | bool compress_force = false; | 217 | bool compress_force = false; |
218 | 218 | ||
219 | cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy); | 219 | cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); |
220 | if (cache_gen) | 220 | if (cache_gen) |
221 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 221 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
222 | 222 | ||
@@ -524,7 +524,7 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
524 | * will mount by default if we haven't been given a specific subvolume | 524 | * will mount by default if we haven't been given a specific subvolume |
525 | * to mount. | 525 | * to mount. |
526 | */ | 526 | */ |
527 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 527 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); |
528 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | 528 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); |
529 | if (IS_ERR(di)) { | 529 | if (IS_ERR(di)) { |
530 | btrfs_free_path(path); | 530 | btrfs_free_path(path); |
@@ -937,6 +937,13 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
937 | fs_info->fs_devices = fs_devices; | 937 | fs_info->fs_devices = fs_devices; |
938 | tree_root->fs_info = fs_info; | 938 | tree_root->fs_info = fs_info; |
939 | 939 | ||
940 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | ||
941 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | ||
942 | if (!fs_info->super_copy || !fs_info->super_for_commit) { | ||
943 | error = -ENOMEM; | ||
944 | goto error_close_devices; | ||
945 | } | ||
946 | |||
940 | bdev = fs_devices->latest_bdev; | 947 | bdev = fs_devices->latest_bdev; |
941 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); | 948 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); |
942 | if (IS_ERR(s)) { | 949 | if (IS_ERR(s)) { |
@@ -951,7 +958,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
951 | } | 958 | } |
952 | 959 | ||
953 | btrfs_close_devices(fs_devices); | 960 | btrfs_close_devices(fs_devices); |
954 | kfree(fs_info); | 961 | free_fs_info(fs_info); |
955 | kfree(tree_root); | 962 | kfree(tree_root); |
956 | } else { | 963 | } else { |
957 | char b[BDEVNAME_SIZE]; | 964 | char b[BDEVNAME_SIZE]; |
@@ -979,7 +986,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
979 | 986 | ||
980 | error_close_devices: | 987 | error_close_devices: |
981 | btrfs_close_devices(fs_devices); | 988 | btrfs_close_devices(fs_devices); |
982 | kfree(fs_info); | 989 | free_fs_info(fs_info); |
983 | kfree(tree_root); | 990 | kfree(tree_root); |
984 | return ERR_PTR(error); | 991 | return ERR_PTR(error); |
985 | } | 992 | } |
@@ -1005,7 +1012,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1005 | if (root->fs_info->fs_devices->rw_devices == 0) | 1012 | if (root->fs_info->fs_devices->rw_devices == 0) |
1006 | return -EACCES; | 1013 | return -EACCES; |
1007 | 1014 | ||
1008 | if (btrfs_super_log_root(&root->fs_info->super_copy) != 0) | 1015 | if (btrfs_super_log_root(root->fs_info->super_copy) != 0) |
1009 | return -EINVAL; | 1016 | return -EINVAL; |
1010 | 1017 | ||
1011 | ret = btrfs_cleanup_fs_roots(root->fs_info); | 1018 | ret = btrfs_cleanup_fs_roots(root->fs_info); |
@@ -1171,7 +1178,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1171 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1178 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1172 | { | 1179 | { |
1173 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 1180 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); |
1174 | struct btrfs_super_block *disk_super = &root->fs_info->super_copy; | 1181 | struct btrfs_super_block *disk_super = root->fs_info->super_copy; |
1175 | struct list_head *head = &root->fs_info->space_info; | 1182 | struct list_head *head = &root->fs_info->space_info; |
1176 | struct btrfs_space_info *found; | 1183 | struct btrfs_space_info *found; |
1177 | u64 total_used = 0; | 1184 | u64 total_used = 0; |