Skip to content

Commit e9bed72

Browse files
adam900710kdave
authored andcommitted
btrfs: add extra ASSERT()s to catch unaligned bios
Btrfs uses btrfs_bio to handle read/write of logical address, for the incoming bs > ps support, btrfs has extra requirements: - One folio must contain at least one fs block - No fs block can cross folio boundaries This requirement is not hard to maintain, thanks to the address space's minimal folio order. But not all btrfs bios are generated through address space, e.g. compression and scrub. To catch possible unaligned bios, introduce a helper, assert_bbio_alginment(), for each btrfs_bio in btrfs_submit_bbio(). This will check the following things: - bv_offset is aligned to block size - bv_len is aligned to block size With a btrfs bio passing above checks, unless it's empty it will ensure the requirements for bs > ps support. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 67378b7 commit e9bed72

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

fs/btrfs/bio.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,11 +779,38 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
779779
return true;
780780
}
781781

782+
static void assert_bbio_alignment(struct btrfs_bio *bbio)
783+
{
784+
#ifdef CONFIG_BTRFS_ASSERT
785+
struct btrfs_fs_info *fs_info = bbio->fs_info;
786+
struct bio_vec bvec;
787+
struct bvec_iter iter;
788+
const u32 blocksize = fs_info->sectorsize;
789+
790+
/* Metadata has no extra bs > ps alignment requirement. */
791+
if (!is_data_bbio(bbio))
792+
return;
793+
794+
bio_for_each_bvec(bvec, &bbio->bio, iter)
795+
ASSERT(IS_ALIGNED(bvec.bv_offset, blocksize) &&
796+
IS_ALIGNED(bvec.bv_len, blocksize),
797+
"root=%llu inode=%llu logical=%llu length=%u index=%u bv_offset=%u bv_len=%u",
798+
btrfs_root_id(bbio->inode->root),
799+
btrfs_ino(bbio->inode),
800+
bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT,
801+
bbio->bio.bi_iter.bi_size, iter.bi_idx,
802+
bvec.bv_offset,
803+
bvec.bv_len);
804+
#endif
805+
}
806+
782807
void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num)
783808
{
784809
/* If bbio->inode is not populated, its file_offset must be 0. */
785810
ASSERT(bbio->inode || bbio->file_offset == 0);
786811

812+
assert_bbio_alignment(bbio);
813+
787814
while (!btrfs_submit_chunk(bbio, mirror_num))
788815
;
789816
}

0 commit comments

Comments
 (0)