From: Keith Busch <kbusch@kernel.org>
To: Christoph Hellwig <hch@infradead.org>
Cc: Keith Busch <kbusch@meta.com>,
linux-block@vger.kernel.org, shinichiro.kawasaki@wdc.com
Subject: Re: [PATCH blktests] create a test for direct io offsets
Date: Tue, 21 Oct 2025 15:22:08 -0600 [thread overview]
Message-ID: <aPf5gAOlnJtVUV6E@kbusch-mbp> (raw)
In-Reply-To: <aPcZ6ZnAGVwgK1DO@infradead.org>
On Mon, Oct 20, 2025 at 10:28:09PM -0700, Christoph Hellwig wrote:
> seems like a huge win. Any chance you could try to get this done ASAP
> so that we could make the interface fully discoverable before 6.18 is
> released?
I just want to make sure I am aligned to what you have in mind. Is this
something like this what you're looking for? This reports the kernel's
ability to handle a dio with memory that is discontiguous for a single
device "sector", and reports the virtual gap requirements.
---
diff --git a/block/bdev.c b/block/bdev.c
index 810707cca9703..5881edc3bf928 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -1330,6 +1330,12 @@ void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
stat->result_mask |= STATX_DIOALIGN;
}
+ if (request_mask & STATX_DIO_VIRT_SPLIT) {
+ stat->dio_virt_boundary_mask = queue_virt_boundary(
+ bdev->bd_queue);
+ stat->result_mask |= STATX_DIO_VIRT_SPLIT;
+ }
+
if (request_mask & STATX_WRITE_ATOMIC && bdev_can_atomic_write(bdev)) {
struct request_queue *bd_queue = bdev->bd_queue;
@@ -1339,6 +1345,10 @@ void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
0);
}
+ if (bdev_max_segments(bdev) > 1)
+ stat->attributes |= STATX_ATTR_DIO_VEC_SPLIT;
+ stat->attributes_mask |= STATX_ATTR_DIO_VEC_SPLIT;
+
stat->blksize = bdev_io_min(bdev);
blkdev_put_no_open(bdev);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e99306a8f47ce..aec3ed6356aa8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -6105,6 +6105,13 @@ int ext4_getattr(struct mnt_idmap *idmap, const struct path *path,
}
}
+ if (request_mask & STATX_DIO_VIRT_SPLIT) {
+ struct block_device *bdev = inode->i_sb->s_bdev;
+
+ stat->dio_virt_boundary_mask = queue_virt_boundary(bdev->bd_queue);
+ stat->result_mask |= STATX_DIO_VIRT_SPLIT;
+ }
+
if ((request_mask & STATX_WRITE_ATOMIC) && S_ISREG(inode->i_mode)) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
unsigned int awu_min = 0, awu_max = 0;
diff --git a/fs/stat.c b/fs/stat.c
index 6c79661e1b961..7f0e12b3b82e8 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -738,6 +738,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
tmp.stx_dev_minor = MINOR(stat->dev);
tmp.stx_mnt_id = stat->mnt_id;
tmp.stx_dio_mem_align = stat->dio_mem_align;
+ tmp.stx_dio_virtual_boundary_mask = stat->dio_virt_boundary_mask;
tmp.stx_dio_offset_align = stat->dio_offset_align;
tmp.stx_dio_read_offset_align = stat->dio_read_offset_align;
tmp.stx_subvol = stat->subvol;
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index caff0125faeac..ce3234d1f9377 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -599,6 +599,18 @@ xfs_report_dioalign(
stat->dio_offset_align = stat->dio_read_offset_align;
}
+static void
+xfs_report_dio_split(
+ struct xfs_inode *ip,
+ struct kstat *stat)
+{
+ struct xfs_buftarg *target = xfs_inode_buftarg(ip);
+ struct block_device *bdev = target->bt_bdev;
+
+ stat->dio_virt_boundary_mask = queue_virt_boundary(bdev->bd_queue);
+ stat->result_mask |= STATX_DIO_VIRT_SPLIT;
+}
+
unsigned int
xfs_get_atomic_write_min(
struct xfs_inode *ip)
@@ -743,6 +755,8 @@ xfs_vn_getattr(
xfs_report_dioalign(ip, stat);
if (request_mask & STATX_WRITE_ATOMIC)
xfs_report_atomic_write(ip, stat);
+ if (request_mask & STATX_DIO_VIRT_SPLIT)
+ xfs_report_dio_split(ip, stat);
fallthrough;
default:
stat->blksize = xfs_stat_blksize(ip);
diff --git a/include/linux/stat.h b/include/linux/stat.h
index e3d00e7bb26d9..57088eedb6f92 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -55,6 +55,7 @@ struct kstat {
u32 dio_mem_align;
u32 dio_offset_align;
u32 dio_read_offset_align;
+ u32 dio_virt_boundary_mask;
u32 atomic_write_unit_min;
u32 atomic_write_unit_max;
u32 atomic_write_unit_max_opt;
diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
index 1686861aae20a..3f79359cf7154 100644
--- a/include/uapi/linux/stat.h
+++ b/include/uapi/linux/stat.h
@@ -184,7 +184,9 @@ struct statx {
/* Optimised max atomic write unit in bytes */
__u32 stx_atomic_write_unit_max_opt;
- __u32 __spare2[1];
+
+ /* Virtual boundary mask between io vectors that require a split */
+ __u32 stx_dio_virtual_boundary_mask;
/* 0xc0 */
__u64 __spare3[8]; /* Spare space for future expansion */
@@ -219,6 +221,7 @@ struct statx {
#define STATX_SUBVOL 0x00008000U /* Want/got stx_subvol */
#define STATX_WRITE_ATOMIC 0x00010000U /* Want/got atomic_write_* fields */
#define STATX_DIO_READ_ALIGN 0x00020000U /* Want/got dio read alignment info */
+#define STATX_DIO_VIRT_SPLIT 0x00040000U /* Want/got dio virtual boundary split */
#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */
@@ -255,6 +258,7 @@ struct statx {
#define STATX_ATTR_VERITY 0x00100000 /* [I] Verity protected file */
#define STATX_ATTR_DAX 0x00200000 /* File is currently in DAX state */
#define STATX_ATTR_WRITE_ATOMIC 0x00400000 /* File supports atomic write operations */
+#define STATX_ATTR_DIO_VEC_SPLIT 0x00800000 /* File supports vector crossing dio payloads */
#endif /* _UAPI_LINUX_STAT_H */
--
next prev parent reply other threads:[~2025-10-21 21:22 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-14 20:54 [PATCH blktests] create a test for direct io offsets Keith Busch
2025-10-14 21:21 ` Bart Van Assche
2025-10-14 21:59 ` Keith Busch
2025-10-17 11:13 ` Christoph Hellwig
2025-10-20 16:20 ` Keith Busch
2025-10-21 5:28 ` Christoph Hellwig
2025-10-21 21:22 ` Keith Busch [this message]
2025-10-22 4:46 ` Christoph Hellwig
2025-11-17 21:53 ` Keith Busch
2025-11-18 5:54 ` Christoph Hellwig
2025-10-20 12:40 ` Shinichiro Kawasaki
2025-10-20 21:03 ` Keith Busch
2025-10-21 1:32 ` Shinichiro Kawasaki
2025-10-20 23:25 ` Chaitanya Kulkarni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aPf5gAOlnJtVUV6E@kbusch-mbp \
--to=kbusch@kernel.org \
--cc=hch@infradead.org \
--cc=kbusch@meta.com \
--cc=linux-block@vger.kernel.org \
--cc=shinichiro.kawasaki@wdc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox