Skip to content

Commit 1c3ab6d

Browse files
adam900710kdave
authored andcommitted
btrfs: handle missing chunk mapping more gracefully
[BUG] During my scrub rework, I did a stupid thing like this: bio->bi_iter.bi_sector = stripe->logical; btrfs_submit_bio(fs_info, bio, stripe->mirror_num); Above bi_sector assignment is using logical address directly, which lacks ">> SECTOR_SHIFT". This results a read on a range which has no chunk mapping. This results the following crash: BTRFS critical (device dm-1): unable to find logical 11274289152 length 65536 assertion failed: !IS_ERR(em), in fs/btrfs/volumes.c:6387 Sure this is all my fault, but this shows a possible problem in real world, that some bit flip in file extents/tree block can point to unmapped ranges, and trigger above ASSERT(), or if CONFIG_BTRFS_ASSERT is not configured, cause invalid pointer access. [PROBLEMS] In the above call chain, we just don't handle the possible error from btrfs_get_chunk_map() inside __btrfs_map_block(). [FIX] The fix is straightforward, replace the ASSERT() with proper error handling (callers handle errors already). Reviewed-by: Anand Jain <[email protected]> Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 675dfe1 commit 1c3ab6d

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

fs/btrfs/volumes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6363,7 +6363,8 @@ int __btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
63636363
ASSERT(op != BTRFS_MAP_DISCARD);
63646364

63656365
em = btrfs_get_chunk_map(fs_info, logical, *length);
6366-
ASSERT(!IS_ERR(em));
6366+
if (IS_ERR(em))
6367+
return PTR_ERR(em);
63676368

63686369
map = em->map_lookup;
63696370
data_stripes = nr_data_stripes(map);

0 commit comments

Comments
 (0)