diff options
-rw-r--r-- | fs/btrfs/extent-tree.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e814b1312511..1204c8ef6f32 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -7466,6 +7466,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
7466 | int err = 0; | 7466 | int err = 0; |
7467 | int ret; | 7467 | int ret; |
7468 | int level; | 7468 | int level; |
7469 | bool root_dropped = false; | ||
7469 | 7470 | ||
7470 | path = btrfs_alloc_path(); | 7471 | path = btrfs_alloc_path(); |
7471 | if (!path) { | 7472 | if (!path) { |
@@ -7643,12 +7644,22 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
7643 | free_extent_buffer(root->commit_root); | 7644 | free_extent_buffer(root->commit_root); |
7644 | btrfs_put_fs_root(root); | 7645 | btrfs_put_fs_root(root); |
7645 | } | 7646 | } |
7647 | root_dropped = true; | ||
7646 | out_end_trans: | 7648 | out_end_trans: |
7647 | btrfs_end_transaction_throttle(trans, tree_root); | 7649 | btrfs_end_transaction_throttle(trans, tree_root); |
7648 | out_free: | 7650 | out_free: |
7649 | kfree(wc); | 7651 | kfree(wc); |
7650 | btrfs_free_path(path); | 7652 | btrfs_free_path(path); |
7651 | out: | 7653 | out: |
7654 | /* | ||
7655 | * So if we need to stop dropping the snapshot for whatever reason we | ||
7656 | * need to make sure to add it back to the dead root list so that we | ||
7657 | * keep trying to do the work later. This also cleans up roots if we | ||
7658 | * don't have it in the radix (like when we recover after a power fail | ||
7659 | * or unmount) so we don't leak memory. | ||
7660 | */ | ||
7661 | if (root_dropped == false) | ||
7662 | btrfs_add_dead_root(root); | ||
7652 | if (err) | 7663 | if (err) |
7653 | btrfs_std_error(root->fs_info, err); | 7664 | btrfs_std_error(root->fs_info, err); |
7654 | return err; | 7665 | return err; |