aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2011-04-13 09:41:04 -0400
committerChris Mason <chris.mason@oracle.com>2011-11-06 03:04:01 -0500
commit6c41761fc6efe1503103a1afe03a6635c0b5d4ec (patch)
tree08ad34d43aac48e8f8143a0b1fa07141df8f202a /fs/btrfs/super.c
parentc8174313a8102e874aaa321e2fc4c7c460a87151 (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.c19
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
980error_close_devices: 987error_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)
1171static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) 1178static 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;