aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-24 16:35:41 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:55:08 -0400
commit171f6537abb1929ab9072ed084872273300ca175 (patch)
treeec2b1a84ecd88c5d49485b4d28c56cbab0036ef8
parenteb384b55ae9c2055ea00c5cc87971e182d47aefa (diff)
Btrfs: cleanup fs roots if we fail to mount
We can run the tree logging recovery or the orphan cleanup on mount, so we'll end up looking up a random fs tree in the meantime. So we need to clean this up so we don't leave extent buffers hanging around on the cache. With this patch we no longer leak extent buffers on failure to mount. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/disk-io.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index deb6e3d07281..b20f1121efae 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2011,6 +2011,36 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
2011 } 2011 }
2012} 2012}
2013 2013
2014static void del_fs_roots(struct btrfs_fs_info *fs_info)
2015{
2016 int ret;
2017 struct btrfs_root *gang[8];
2018 int i;
2019
2020 while (!list_empty(&fs_info->dead_roots)) {
2021 gang[0] = list_entry(fs_info->dead_roots.next,
2022 struct btrfs_root, root_list);
2023 list_del(&gang[0]->root_list);
2024
2025 if (gang[0]->in_radix) {
2026 btrfs_free_fs_root(fs_info, gang[0]);
2027 } else {
2028 free_extent_buffer(gang[0]->node);
2029 free_extent_buffer(gang[0]->commit_root);
2030 kfree(gang[0]);
2031 }
2032 }
2033
2034 while (1) {
2035 ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
2036 (void **)gang, 0,
2037 ARRAY_SIZE(gang));
2038 if (!ret)
2039 break;
2040 for (i = 0; i < ret; i++)
2041 btrfs_free_fs_root(fs_info, gang[i]);
2042 }
2043}
2014 2044
2015int open_ctree(struct super_block *sb, 2045int open_ctree(struct super_block *sb,
2016 struct btrfs_fs_devices *fs_devices, 2046 struct btrfs_fs_devices *fs_devices,
@@ -2795,6 +2825,7 @@ fail_qgroup:
2795 btrfs_free_qgroup_config(fs_info); 2825 btrfs_free_qgroup_config(fs_info);
2796fail_trans_kthread: 2826fail_trans_kthread:
2797 kthread_stop(fs_info->transaction_kthread); 2827 kthread_stop(fs_info->transaction_kthread);
2828 del_fs_roots(fs_info);
2798fail_cleaner: 2829fail_cleaner:
2799 kthread_stop(fs_info->cleaner_kthread); 2830 kthread_stop(fs_info->cleaner_kthread);
2800 2831
@@ -3323,37 +3354,6 @@ static void free_fs_root(struct btrfs_root *root)
3323 kfree(root); 3354 kfree(root);
3324} 3355}
3325 3356
3326static void del_fs_roots(struct btrfs_fs_info *fs_info)
3327{
3328 int ret;
3329 struct btrfs_root *gang[8];
3330 int i;
3331
3332 while (!list_empty(&fs_info->dead_roots)) {
3333 gang[0] = list_entry(fs_info->dead_roots.next,
3334 struct btrfs_root, root_list);
3335 list_del(&gang[0]->root_list);
3336
3337 if (gang[0]->in_radix) {
3338 btrfs_free_fs_root(fs_info, gang[0]);
3339 } else {
3340 free_extent_buffer(gang[0]->node);
3341 free_extent_buffer(gang[0]->commit_root);
3342 kfree(gang[0]);
3343 }
3344 }
3345
3346 while (1) {
3347 ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
3348 (void **)gang, 0,
3349 ARRAY_SIZE(gang));
3350 if (!ret)
3351 break;
3352 for (i = 0; i < ret; i++)
3353 btrfs_free_fs_root(fs_info, gang[i]);
3354 }
3355}
3356
3357int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) 3357int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
3358{ 3358{
3359 u64 root_objectid = 0; 3359 u64 root_objectid = 0;