Btrfs: fix trim 0 bytes after a device delete
authorLiu Bo <liubo2009@cn.fujitsu.com>
Thu, 9 Feb 2012 10:17:41 +0000 (18:17 +0800)
committerDavid Sterba <dsterba@suse.cz>
Wed, 15 Feb 2012 15:40:23 +0000 (16:40 +0100)
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>
fs/btrfs/extent-tree.c

index 283af7a676a39b4c2f31d7d9b7caf81607eee4ea..60bfe2d68547b8f7a7fed66c6d41d75c6dd7daef 100644 (file)
@@ -7886,9 +7886,16 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
        u64 start;
        u64 end;
        u64 trimmed = 0;
+       u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
        int ret = 0;
 
-       cache = btrfs_lookup_block_group(fs_info, range->start);
+       /*
+        * try to trim all FS space, our block group may start from non-zero.
+        */
+       if (range->len == total_bytes)
+               cache = btrfs_lookup_first_block_group(fs_info, range->start);
+       else
+               cache = btrfs_lookup_block_group(fs_info, range->start);
 
        while (cache) {
                if (cache->key.objectid >= (range->start + range->len)) {