diff options
author | Liu Bo <liubo2009@cn.fujitsu.com> | 2012-02-09 05:17:41 -0500 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2012-02-15 10:40:23 -0500 |
commit | 2cac13e41bf5b99ffc426bd28dfd2248df1dfa67 (patch) | |
tree | b74e7e863b7d7c2e116dc6754d8faf701c0aa3c9 /fs | |
parent | 6af021d8fc3bcce790e7fbb391e39c5920fa3f71 (diff) |
Btrfs: fix trim 0 bytes after a device delete
A user reported a bug of btrfs's trim, that is we will trim 0 bytes
after a device delete.
The reproducer:
$ mkfs.btrfs disk1
$ mkfs.btrfs disk2
$ mount disk1 /mnt
$ fstrim -v /mnt
$ btrfs device add disk2 /mnt
$ btrfs device del disk1 /mnt
$ fstrim -v /mnt
This is because after we delete the device, the block group may start from
a non-zero place, which will confuse trim to discard nothing.
Reported-by: Lutz Euler <lutz.euler@freenet.de>
Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 283af7a676a3..60bfe2d68547 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -7886,9 +7886,16 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) | |||
7886 | u64 start; | 7886 | u64 start; |
7887 | u64 end; | 7887 | u64 end; |
7888 | u64 trimmed = 0; | 7888 | u64 trimmed = 0; |
7889 | u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); | ||
7889 | int ret = 0; | 7890 | int ret = 0; |
7890 | 7891 | ||
7891 | cache = btrfs_lookup_block_group(fs_info, range->start); | 7892 | /* |
7893 | * try to trim all FS space, our block group may start from non-zero. | ||
7894 | */ | ||
7895 | if (range->len == total_bytes) | ||
7896 | cache = btrfs_lookup_first_block_group(fs_info, range->start); | ||
7897 | else | ||
7898 | cache = btrfs_lookup_block_group(fs_info, range->start); | ||
7892 | 7899 | ||
7893 | while (cache) { | 7900 | while (cache) { |
7894 | if (cache->key.objectid >= (range->start + range->len)) { | 7901 | if (cache->key.objectid >= (range->start + range->len)) { |