aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2014-01-13 06:53:53 -0500
committerChris Mason <clm@fb.com>2014-01-28 16:20:35 -0500
commit1a4319cc3c495d5b6b8e41f4d4c73b950d54c2be (patch)
treefca5ffd2b1b88281063a288552e04c6864a12fa8 /fs
parent078025347c8ed43ff330e392476d8866ac1b297f (diff)
Btrfs: fix extent state leak on transaction abortion
When transaction is aborted, we fail to commit transaction, instead we do cleanup work. After that when we umount btrfs, we get to free fs roots' log trees respectively, but that happens after we unpin extents, so those extents pinned by freeing log trees will remain in memory and lead to the leak. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/disk-io.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4f142c986544..47c2bc21caad 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2065,6 +2065,12 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
2065 for (i = 0; i < ret; i++) 2065 for (i = 0; i < ret; i++)
2066 btrfs_drop_and_free_fs_root(fs_info, gang[i]); 2066 btrfs_drop_and_free_fs_root(fs_info, gang[i]);
2067 } 2067 }
2068
2069 if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
2070 btrfs_free_log_root_tree(NULL, fs_info);
2071 btrfs_destroy_pinned_extent(fs_info->tree_root,
2072 fs_info->pinned_extents);
2073 }
2068} 2074}
2069 2075
2070int open_ctree(struct super_block *sb, 2076int open_ctree(struct super_block *sb,
@@ -3455,10 +3461,8 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
3455 if (btrfs_root_refs(&root->root_item) == 0) 3461 if (btrfs_root_refs(&root->root_item) == 0)
3456 synchronize_srcu(&fs_info->subvol_srcu); 3462 synchronize_srcu(&fs_info->subvol_srcu);
3457 3463
3458 if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { 3464 if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
3459 btrfs_free_log(NULL, root); 3465 btrfs_free_log(NULL, root);
3460 btrfs_free_log_root_tree(NULL, fs_info);
3461 }
3462 3466
3463 __btrfs_remove_free_space_cache(root->free_ino_pinned); 3467 __btrfs_remove_free_space_cache(root->free_ino_pinned);
3464 __btrfs_remove_free_space_cache(root->free_ino_ctl); 3468 __btrfs_remove_free_space_cache(root->free_ino_ctl);
@@ -3569,8 +3573,6 @@ int close_ctree(struct btrfs_root *root)
3569 if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) 3573 if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
3570 btrfs_error_commit_super(root); 3574 btrfs_error_commit_super(root);
3571 3575
3572 btrfs_put_block_group_cache(fs_info);
3573
3574 kthread_stop(fs_info->transaction_kthread); 3576 kthread_stop(fs_info->transaction_kthread);
3575 kthread_stop(fs_info->cleaner_kthread); 3577 kthread_stop(fs_info->cleaner_kthread);
3576 3578
@@ -3588,6 +3590,8 @@ int close_ctree(struct btrfs_root *root)
3588 3590
3589 del_fs_roots(fs_info); 3591 del_fs_roots(fs_info);
3590 3592
3593 btrfs_put_block_group_cache(fs_info);
3594
3591 btrfs_free_block_groups(fs_info); 3595 btrfs_free_block_groups(fs_info);
3592 3596
3593 btrfs_stop_all_workers(fs_info); 3597 btrfs_stop_all_workers(fs_info);