mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 20:53:03 +02:00
loop, zloop: fix dma_alignment for large or unreported limits
A file system sets STATX_DIOALIGN with zeroed alignments when the file can't be used for direct I/O. The zero underflowed to UINT_MAX and triggered a queue limits validation warning. Fall back to the block device's limits when dio_mem_align isn't reported. A file system with a block size larger than PAGE_SIZE may also report a memory alignment that can't be expressed as a queue limit. File systems fall back to buffered I/O for requests that don't meet their alignment, so cap the reported limit to the largest possible value. Fixes:6c8dec275c("loop: set dma_alignment from the backing file for direct I/O") Fixes:c5059c1af2("zloop: set dma_alignment from the backing files for direct I/O") Reported-by: syzbot+ac00e7bf7ac8c91af921@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ac00e7bf7ac8c91af921 Signed-off-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260810164218.3721636-1-kbusch@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
96c8ea3c5a
commit
e52349a5ea
|
|
@ -458,12 +458,14 @@ static void loop_update_dio_alignment(struct loop_device *lo)
|
|||
* Use the dio alignment of the file system if provided. The incomoing
|
||||
* request's bio_vec is forwarded to the backing file unchanged, so its
|
||||
* required memory alignment becomes the device's dma_alignment when
|
||||
* used for direct-io.
|
||||
* used for direct-io. The file system reports zeroed alignments if the
|
||||
* file can't be used for direct-io at all, so fall back to the block
|
||||
* device limits in that case.
|
||||
*/
|
||||
if (!vfs_getattr(&file->f_path, &st, STATX_DIOALIGN, 0) &&
|
||||
(st.result_mask & STATX_DIOALIGN)) {
|
||||
(st.result_mask & STATX_DIOALIGN) && st.dio_mem_align) {
|
||||
lo->lo_min_dio_size = st.dio_offset_align;
|
||||
lo->lo_dio_mem_align = st.dio_mem_align - 1;
|
||||
lo->lo_dio_mem_align = min(st.dio_mem_align - 1, PAGE_SIZE - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1042,12 +1042,14 @@ static int zloop_get_block_size(struct zloop_device *zlo,
|
|||
* Use the dio alignment of the file system if provided. The incoming
|
||||
* request's bio_vec is forwarded to the backing file unchanged, so its
|
||||
* required memory alignment becomes the device's dma_alignment when
|
||||
* used for direct-io.
|
||||
* used for direct-io. The file system reports zeroed alignments if the
|
||||
* file can't be used for direct-io at all, so fall back to the block
|
||||
* device limits in that case.
|
||||
*/
|
||||
if (!vfs_getattr(&zone->file->f_path, &st, STATX_DIOALIGN, 0) &&
|
||||
(st.result_mask & STATX_DIOALIGN)) {
|
||||
(st.result_mask & STATX_DIOALIGN) && st.dio_mem_align) {
|
||||
zlo->block_size = st.dio_offset_align;
|
||||
zlo->dio_mem_align = st.dio_mem_align - 1;
|
||||
zlo->dio_mem_align = min(st.dio_mem_align - 1, PAGE_SIZE - 1);
|
||||
} else if (sb_bdev) {
|
||||
zlo->block_size = bdev_physical_block_size(sb_bdev);
|
||||
zlo->dio_mem_align = bdev_dma_alignment(sb_bdev);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user