]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: zoned: bail out if we can't read a reliable write pointer
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Fri, 30 Apr 2021 13:34:18 +0000 (15:34 +0200)
committerDavid Sterba <dsterba@suse.com>
Tue, 4 May 2021 12:41:57 +0000 (14:41 +0200)
If we can't read a reliable write pointer from a sequential zone fail
creating the block group with an I/O error.

Also if the read write pointer is beyond the end of the respective zone,
fail the creation of the block group on this zone with an I/O error.

While this could also happen in real world scenarios with misbehaving
drives, this issue addresses a problem uncovered by fstests' test case
generic/475.

CC: stable@vger.kernel.org # 5.12+
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/zoned.c

index 304ce64c70a44957a51b3b632d98de8ca72bcb78..29adf846f33b59008f0e267d21f45830c6df81ea 100644 (file)
@@ -1187,6 +1187,12 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
 
        switch (map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
        case 0: /* single */
+               if (alloc_offsets[0] == WP_MISSING_DEV) {
+                       btrfs_err(fs_info,
+                                 "zoned: cannot recover write pointer");
+                       ret = -EIO;
+                       goto out;
+               }
                cache->alloc_offset = alloc_offsets[0];
                break;
        case BTRFS_BLOCK_GROUP_DUP:
@@ -1204,6 +1210,12 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
        }
 
 out:
+       if (cache->alloc_offset > fs_info->zone_size) {
+               btrfs_err(fs_info, "zoned: invalid write pointer: %llu",
+                         cache->alloc_offset);
+               ret = -EIO;
+       }
+
        /* An extent is allocated after the write pointer */
        if (!ret && num_conventional && last_alloc > cache->alloc_offset) {
                btrfs_err(fs_info,