Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "alloc misaligned vectors for zoned XFS v2"

Christoph Hellwig <hch@lst.de> says:

This series enables the new block layer support for misaligned
individual vectors for zoned XFS.

The first patch is the from Qu and supposedly already applied to
the vfs iomap 6.19 branch, but I can't find it there. The next
two are small fixups for it, and the last one makes use of this
new functionality in XFS.

* patches from https://patch.msgid.link/20251031131045.1613229-1-hch@lst.de:
xfs: support sub-block aligned vectors in always COW mode
iomap: add IOMAP_DIO_FSBLOCK_ALIGNED flag

Link: https://patch.msgid.link/20251031131045.1613229-1-hch@lst.de
Signed-off-by: Christian Brauner <brauner@kernel.org>

+38 -15
+15 -2
fs/iomap/direct-io.c
··· 336 336 int nr_pages, ret = 0; 337 337 u64 copied = 0; 338 338 size_t orig_count; 339 + unsigned int alignment; 339 340 340 - if ((pos | length) & (bdev_logical_block_size(iomap->bdev) - 1)) 341 + /* 342 + * File systems that write out of place and always allocate new blocks 343 + * need each bio to be block aligned as that's the unit of allocation. 344 + */ 345 + if (dio->flags & IOMAP_DIO_FSBLOCK_ALIGNED) 346 + alignment = fs_block_size; 347 + else 348 + alignment = bdev_logical_block_size(iomap->bdev); 349 + 350 + if ((pos | length) & (alignment - 1)) 341 351 return -EINVAL; 342 352 343 353 if (dio->flags & IOMAP_DIO_WRITE) { ··· 444 434 bio->bi_end_io = iomap_dio_bio_end_io; 445 435 446 436 ret = bio_iov_iter_get_pages(bio, dio->submit.iter, 447 - bdev_logical_block_size(iomap->bdev) - 1); 437 + alignment - 1); 448 438 if (unlikely(ret)) { 449 439 /* 450 440 * We have to stop part way through an IO. We must fall ··· 648 638 649 639 if (iocb->ki_flags & IOCB_NOWAIT) 650 640 iomi.flags |= IOMAP_NOWAIT; 641 + 642 + if (dio_flags & IOMAP_DIO_FSBLOCK_ALIGNED) 643 + dio->flags |= IOMAP_DIO_FSBLOCK_ALIGNED; 651 644 652 645 if (iov_iter_rw(iter) == READ) { 653 646 /* reads can always complete inline */
+4 -3
fs/iomap/trace.h
··· 122 122 123 123 124 124 #define IOMAP_DIO_STRINGS \ 125 - {IOMAP_DIO_FORCE_WAIT, "DIO_FORCE_WAIT" }, \ 126 - {IOMAP_DIO_OVERWRITE_ONLY, "DIO_OVERWRITE_ONLY" }, \ 127 - {IOMAP_DIO_PARTIAL, "DIO_PARTIAL" } 125 + {IOMAP_DIO_FORCE_WAIT, "DIO_FORCE_WAIT" }, \ 126 + {IOMAP_DIO_OVERWRITE_ONLY, "DIO_OVERWRITE_ONLY" }, \ 127 + {IOMAP_DIO_PARTIAL, "DIO_PARTIAL" }, \ 128 + {IOMAP_DIO_FSBLOCK_ALIGNED, "DIO_FSBLOCK_ALIGNED" } 128 129 129 130 DECLARE_EVENT_CLASS(iomap_class, 130 131 TP_PROTO(struct inode *inode, struct iomap *iomap),
+11 -10
fs/xfs/xfs_file.c
··· 676 676 struct xfs_zone_alloc_ctx *ac) 677 677 { 678 678 unsigned int iolock = XFS_IOLOCK_SHARED; 679 + unsigned int dio_flags = 0; 679 680 ssize_t ret; 681 + 682 + /* 683 + * For always COW inodes, each bio must be aligned to the file system 684 + * block size and not just the device sector size because we need to 685 + * allocate a block-aligned amount of space for each write. 686 + */ 687 + if (xfs_is_always_cow_inode(ip)) 688 + dio_flags |= IOMAP_DIO_FSBLOCK_ALIGNED; 680 689 681 690 ret = xfs_ilock_iocb_for_write(iocb, &iolock); 682 691 if (ret) ··· 704 695 iolock = XFS_IOLOCK_SHARED; 705 696 } 706 697 trace_xfs_file_direct_write(iocb, from); 707 - ret = iomap_dio_rw(iocb, from, ops, dops, 0, ac, 0); 698 + ret = iomap_dio_rw(iocb, from, ops, dops, dio_flags, ac, 0); 708 699 out_unlock: 709 700 xfs_iunlock(ip, iolock); 710 701 return ret; ··· 901 892 if ((iocb->ki_pos | count) & target->bt_logical_sectormask) 902 893 return -EINVAL; 903 894 904 - /* 905 - * For always COW inodes we also must check the alignment of each 906 - * individual iovec segment, as they could end up with different 907 - * I/Os due to the way bio_iov_iter_get_pages works, and we'd 908 - * then overwrite an already written block. 909 - */ 910 - if (((iocb->ki_pos | count) & ip->i_mount->m_blockmask) || 911 - (xfs_is_always_cow_inode(ip) && 912 - (iov_iter_alignment(from) & ip->i_mount->m_blockmask))) 895 + if ((iocb->ki_pos | count) & ip->i_mount->m_blockmask) 913 896 return xfs_file_dio_write_unaligned(ip, iocb, from); 914 897 if (xfs_is_zoned_inode(ip)) 915 898 return xfs_file_dio_write_zoned(ip, iocb, from);
+8
include/linux/iomap.h
··· 553 553 */ 554 554 #define IOMAP_DIO_PARTIAL (1 << 2) 555 555 556 + /* 557 + * Ensure each bio is aligned to fs block size. 558 + * 559 + * For filesystems which need to calculate/verify the checksum of each fs 560 + * block. Otherwise they may not be able to handle unaligned bios. 561 + */ 562 + #define IOMAP_DIO_FSBLOCK_ALIGNED (1 << 3) 563 + 556 564 ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, 557 565 const struct iomap_ops *ops, const struct iomap_dio_ops *dops, 558 566 unsigned int dio_flags, void *private, size_t done_before);