mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-08 22:16:29 -04:00
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>
This commit is contained in:
@@ -779,11 +779,38 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void assert_bbio_alignment(struct btrfs_bio *bbio)
|
||||
{
|
||||
#ifdef CONFIG_BTRFS_ASSERT
|
||||
struct btrfs_fs_info *fs_info = bbio->fs_info;
|
||||
struct bio_vec bvec;
|
||||
struct bvec_iter iter;
|
||||
const u32 blocksize = fs_info->sectorsize;
|
||||
|
||||
/* Metadata has no extra bs > ps alignment requirement. */
|
||||
if (!is_data_bbio(bbio))
|
||||
return;
|
||||
|
||||
bio_for_each_bvec(bvec, &bbio->bio, iter)
|
||||
ASSERT(IS_ALIGNED(bvec.bv_offset, blocksize) &&
|
||||
IS_ALIGNED(bvec.bv_len, blocksize),
|
||||
"root=%llu inode=%llu logical=%llu length=%u index=%u bv_offset=%u bv_len=%u",
|
||||
btrfs_root_id(bbio->inode->root),
|
||||
btrfs_ino(bbio->inode),
|
||||
bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT,
|
||||
bbio->bio.bi_iter.bi_size, iter.bi_idx,
|
||||
bvec.bv_offset,
|
||||
bvec.bv_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num)
|
||||
{
|
||||
/* If bbio->inode is not populated, its file_offset must be 0. */
|
||||
ASSERT(bbio->inode || bbio->file_offset == 0);
|
||||
|
||||
assert_bbio_alignment(bbio);
|
||||
|
||||
while (!btrfs_submit_chunk(bbio, mirror_num))
|
||||
;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user