Skip to content

Commit 8d488a8

Browse files
fdmananakdave
authored andcommitted
btrfs: fix subvolume/snapshot deletion not triggered on mount
During the mount procedure we are calling btrfs_orphan_cleanup() against the root tree, which will find all orphans items in this tree. When an orphan item corresponds to a deleted subvolume/snapshot (instead of an inode space cache), it must not delete the orphan item, because that will cause btrfs_find_orphan_roots() to not find the orphan item and therefore not add the corresponding subvolume root to the list of dead roots, which results in the subvolume's tree never being deleted by the cleanup thread. The same applies to the remount from RO to RW path. Fix this by making btrfs_find_orphan_roots() run before calling btrfs_orphan_cleanup() against the root tree. A test case for fstests will follow soon. Reported-by: Robbie Ko <[email protected]> Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Fixes: 638331f ("btrfs: fix transaction leak and crash after cleaning up orphans on RO mount") CC: [email protected] # 5.11+ Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent ebd99a6 commit 8d488a8

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

fs/btrfs/disk-io.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,21 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
30103010
}
30113011
}
30123012

3013+
/*
3014+
* btrfs_find_orphan_roots() is responsible for finding all the dead
3015+
* roots (with 0 refs), flag them with BTRFS_ROOT_DEAD_TREE and load
3016+
* them into the fs_info->fs_roots_radix tree. This must be done before
3017+
* calling btrfs_orphan_cleanup() on the tree root. If we don't do it
3018+
* first, then btrfs_orphan_cleanup() will delete a dead root's orphan
3019+
* item before the root's tree is deleted - this means that if we unmount
3020+
* or crash before the deletion completes, on the next mount we will not
3021+
* delete what remains of the tree because the orphan item does not
3022+
* exists anymore, which is what tells us we have a pending deletion.
3023+
*/
3024+
ret = btrfs_find_orphan_roots(fs_info);
3025+
if (ret)
3026+
goto out;
3027+
30133028
ret = btrfs_cleanup_fs_roots(fs_info);
30143029
if (ret)
30153030
goto out;
@@ -3069,7 +3084,6 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
30693084
}
30703085
}
30713086

3072-
ret = btrfs_find_orphan_roots(fs_info);
30733087
out:
30743088
return ret;
30753089
}

0 commit comments

Comments
 (0)