* Re: [PATCH] fs: report direct io constraints through file_getattr
[not found] <20260708011843.1036846-1-kbusch@meta.com>
@ 2026-07-09 7:13 ` Christoph Hellwig
2026-07-09 8:51 ` Andrey Albershteyn
` (2 more replies)
2026-07-10 21:25 ` [f2fs-dev] " Eric Biggers
1 sibling, 3 replies; 9+ messages in thread
From: Christoph Hellwig @ 2026-07-09 7:13 UTC (permalink / raw)
To: Keith Busch
Cc: linux-block, linux-ext4, linux-f2fs-devel, linux-fsdevel,
linux-xfs, axboe, jack, brauner, cem, jaegeuk, aalbersh, tytso,
Keith Busch, Christoph Hellwig
On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
>
> Memory alignment constraints for direct io can vary depending on the
> backing storage hardware. Provide support through file_getattr to report
> the attributes necessary for applications to know how to construct valid
> read and write requests.
This probably wants to be split in one patch for the new UAPI,
one for the helper and one for each user.
And especially the UAPI one needs a much more detailed commit log
explaining it, including why this duplicates some of the informastion
already in statx and documenting the semantics for all the fields.
Andrey, is there a man page or other official documentation for
file_setattr/file_getattr?
> +/*
> + * Handle DIO alignment for block devices via fileattr.
> + */
Maybe note that this purely about the block device constraints,
and file systems may expose additional ones?
> +void bdev_fileattr(const struct inode *inode, struct file_kattr *fa)
> +{
> + struct block_device *bdev;
> +
> + memset(fa, 0, sizeof(*fa));
> + fa->fsx_valid = true;
> + fa->flags_valid = true;
Doing the basic file_kattr initialization here feels dangerous
if we want to be able to call this from file system implementations.
I'd rather leave the initialization to the caller.
> +
> + bdev = blkdev_get_no_open(inode->i_rdev, false);
> + if (!bdev)
> + return;
.. and explicitly pass in the block device. ->i_rdev always is
i_sb->s_dev, which might not be the relevant backing device, e.g. for XFS
it could be that or the block device in m_rtdev_targp.
If i_rdev is i_sb->s_dev we can just use sb->s_bdev without needing a new
open.
> + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> + fa->fsx_dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
> + fa->fsx_max_segments = bdev_max_segments(bdev);
How is the max_segments value defined in a way that is meaningful to
userspace?
> @@ -1005,6 +1006,27 @@ int ext4_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
> if (ext4_has_feature_project(inode->i_sb))
> fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid);
>
> + if (S_ISREG(inode->i_mode)) {
You'll probably want to split this into a helper to keep it easily
readable.
> + u32 dio_align = ext4_dio_alignment(inode);
> +
> + if (dio_align != 0) {
> + struct block_device *bdev = inode->i_sb->s_bdev;
> +
> + if (dio_align == 1) {
> + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> + } else {
> + fa->fsx_dio_mem_align = dio_align;
> + fa->fsx_dio_offset_align = dio_align;
> + fa->fsx_dio_read_offset_align = dio_align;
> + }
Call bdev_fileattr and override the relevant field as needed?
Question to the ext4 maintainers: why does ext4_dio_alignment
affect the in-memory alignment? If it does so, it should probably
also affect the virt boundry alignment..
> + if (S_ISREG(inode->i_mode)) {
> + unsigned int bsize = i_blocksize(inode);
> + struct block_device *bdev = inode->i_sb->s_bdev;
> +
> + if (!f2fs_force_buffered_io(inode, WRITE)) {
Same comments as for ext4. Also f2fs does support multiple devices,
but I'm not sure how data is placed on them, or if a file can be
on multiple devices. We'll need input from the f2fs
maintainers/contributors here.
> @@ -88,8 +89,12 @@ int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
> struct inode *inode = d_inode(dentry);
> int error;
>
> - if (!inode->i_op->fileattr_get)
> - return -ENOIOCTLCMD;
> + if (!inode->i_op->fileattr_get) {
> + if (!S_ISBLK(inode->i_mode))
> + return -ENOIOCTLCMD;
> + bdev_fileattr(inode, fa);
> + return 0;
Don't we also want to fill out the attributes for block devices
on file systems that provide a ->fileattr_get?. Also if we fill
out something, we need the security_inode_file_getattr as well.
> /**
> @@ -145,6 +155,8 @@ static int file_attr_to_fileattr(const struct file_attr *fattr,
>
> if (fattr->fa_xflags & ~mask)
> return -EINVAL;
> + if (fattr->fa_pad)
> + return -EINVAL;
How is this related?
> + if (whichfork == XFS_DATA_FORK && S_ISREG(VFS_I(ip)->i_mode)) {
This probably wants a separate helper.
> + struct xfs_buftarg *target = xfs_inode_buftarg(ip);
> + struct block_device *bdev = target->bt_bdev;
.. and if the generic helpers gets an explicitl bdev we can use it
here and just override one value for for xfs_is_cow_inode().
> +static inline unsigned int bdev_virt_boundary_alignment(struct block_device *bdev)
Overly long line.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 7:13 ` [PATCH] fs: report direct io constraints through file_getattr Christoph Hellwig
@ 2026-07-09 8:51 ` Andrey Albershteyn
2026-07-10 21:28 ` [f2fs-dev] " Eric Biggers
2026-07-09 9:14 ` Jan Kara
2026-07-09 13:46 ` Keith Busch
2 siblings, 1 reply; 9+ messages in thread
From: Andrey Albershteyn @ 2026-07-09 8:51 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Keith Busch, linux-block, linux-ext4, linux-f2fs-devel,
linux-fsdevel, linux-xfs, axboe, jack, brauner, cem, jaegeuk,
aalbersh, tytso, Keith Busch
On 2026-07-09 09:13:52, Christoph Hellwig wrote:
> On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> > From: Keith Busch <kbusch@kernel.org>
> >
> > Memory alignment constraints for direct io can vary depending on the
> > backing storage hardware. Provide support through file_getattr to report
> > the attributes necessary for applications to know how to construct valid
> > read and write requests.
>
> This probably wants to be split in one patch for the new UAPI,
> one for the helper and one for each user.
>
> And especially the UAPI one needs a much more detailed commit log
> explaining it, including why this duplicates some of the informastion
> already in statx and documenting the semantics for all the fields.
>
> Andrey, is there a man page or other official documentation for
> file_setattr/file_getattr?
No, I had a draft in cover letter but haven't got to sending it to
man-pages. I will prepare a man page.
--
- Andrey
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 7:13 ` [PATCH] fs: report direct io constraints through file_getattr Christoph Hellwig
2026-07-09 8:51 ` Andrey Albershteyn
@ 2026-07-09 9:14 ` Jan Kara
2026-07-10 21:20 ` Eric Biggers
2026-07-09 13:46 ` Keith Busch
2 siblings, 1 reply; 9+ messages in thread
From: Jan Kara @ 2026-07-09 9:14 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Keith Busch, linux-block, linux-ext4, linux-f2fs-devel,
linux-fsdevel, linux-xfs, axboe, jack, brauner, cem, jaegeuk,
aalbersh, tytso, Keith Busch, Eric Biggers
On Thu 09-07-26 09:13:52, Christoph Hellwig wrote:
> On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> > + u32 dio_align = ext4_dio_alignment(inode);
> > +
> > + if (dio_align != 0) {
>
>
> > + struct block_device *bdev = inode->i_sb->s_bdev;
> > +
> > + if (dio_align == 1) {
> > + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> > + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> > + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> > + } else {
> > + fa->fsx_dio_mem_align = dio_align;
> > + fa->fsx_dio_offset_align = dio_align;
> > + fa->fsx_dio_read_offset_align = dio_align;
> > + }
>
> Call bdev_fileattr and override the relevant field as needed?
>
> Question to the ext4 maintainers: why does ext4_dio_alignment
> affect the in-memory alignment? If it does so, it should probably
> also affect the virt boundry alignment..
I guess that is mostly a historical accident. ext4_dio_alignment() returns
1 (iomap alignment is used and that's different for memory and file offset
alignment), 0 (dio not supported, memory and file offset alignment is
indeed the same), and blocksize (a special case which can happen for
fscrypt if it supports dio and where I believe memory alignment
requirements may be in fact different). I'm adding Eric to CC to answer
what actual requirements fscrypt has for memory buffers for direct IO. I'd
expect with inline encryption we would have the same requirements as
ordinary iomap direct IO and for other code paths I'm not sure... Eric?
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 7:13 ` [PATCH] fs: report direct io constraints through file_getattr Christoph Hellwig
2026-07-09 8:51 ` Andrey Albershteyn
2026-07-09 9:14 ` Jan Kara
@ 2026-07-09 13:46 ` Keith Busch
2026-07-10 4:35 ` Christoph Hellwig
2 siblings, 1 reply; 9+ messages in thread
From: Keith Busch @ 2026-07-09 13:46 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Keith Busch, linux-block, linux-ext4, linux-f2fs-devel,
linux-fsdevel, linux-xfs, axboe, jack, brauner, cem, jaegeuk,
aalbersh, tytso
On Thu, Jul 09, 2026 at 09:13:52AM +0200, Christoph Hellwig wrote:
> On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
>
> > + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> > + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> > + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> > + fa->fsx_dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
> > + fa->fsx_max_segments = bdev_max_segments(bdev);
>
> How is the max_segments value defined in a way that is meaningful to
> userspace?
It tells you how many sub-sector vectors you can submit in your
readv/writev before it needs to add up to a logical block size.
Ex: 4k logical block size, 4 byte DMA, 256 max segments. You can define
4-byte iov's in your command, but you'll hit the max segment count
before you have a valid IO if they're all that small.
> > @@ -145,6 +155,8 @@ static int file_attr_to_fileattr(const struct file_attr *fattr,
> >
> > if (fattr->fa_xflags & ~mask)
> > return -EINVAL;
> > + if (fattr->fa_pad)
> > + return -EINVAL;
>
> How is this related?
I had to add a padding field to the struct to account for the implicit
hole in 64-bit and to ensure the struct is the same size for 32-bit.
It's a reserved field, so we have to ensure the current kernel doesn't
support any value here in case we define this field for something else
in the future.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 13:46 ` Keith Busch
@ 2026-07-10 4:35 ` Christoph Hellwig
2026-07-10 15:22 ` Keith Busch
0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2026-07-10 4:35 UTC (permalink / raw)
To: Keith Busch
Cc: Christoph Hellwig, Keith Busch, linux-block, linux-ext4,
linux-f2fs-devel, linux-fsdevel, linux-xfs, axboe, jack, brauner,
cem, jaegeuk, aalbersh, tytso
On Thu, Jul 09, 2026 at 07:46:42AM -0600, Keith Busch wrote:
> On Thu, Jul 09, 2026 at 09:13:52AM +0200, Christoph Hellwig wrote:
> > On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> >
> > > + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> > > + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> > > + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> > > + fa->fsx_dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
> > > + fa->fsx_max_segments = bdev_max_segments(bdev);
> >
> > How is the max_segments value defined in a way that is meaningful to
> > userspace?
>
> It tells you how many sub-sector vectors you can submit in your
> readv/writev before it needs to add up to a logical block size.
>
> Ex: 4k logical block size, 4 byte DMA, 256 max segments. You can define
> 4-byte iov's in your command, but you'll hit the max segment count
> before you have a valid IO if they're all that small.
Ah, makes sense. But besides the missing documentation I think
max_segments is a bit of a misleading name for that.
Something like max_vecs_per_block (although we don't expose blocks
in the UAPI) or max_vecs_per_granularity (I think grammar wants a word
with me for that, though...) might be a bit more suitable.
> > > @@ -145,6 +155,8 @@ static int file_attr_to_fileattr(const struct file_attr *fattr,
> > >
> > > if (fattr->fa_xflags & ~mask)
> > > return -EINVAL;
> > > + if (fattr->fa_pad)
> > > + return -EINVAL;
> >
> > How is this related?
>
> I had to add a padding field to the struct to account for the implicit
> hole in 64-bit and to ensure the struct is the same size for 32-bit.
> It's a reserved field, so we have to ensure the current kernel doesn't
> support any value here in case we define this field for something else
> in the future.
Ah, right.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-10 4:35 ` Christoph Hellwig
@ 2026-07-10 15:22 ` Keith Busch
0 siblings, 0 replies; 9+ messages in thread
From: Keith Busch @ 2026-07-10 15:22 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Keith Busch, linux-block, linux-ext4, linux-f2fs-devel,
linux-fsdevel, linux-xfs, axboe, jack, brauner, cem, jaegeuk,
aalbersh, tytso
On Fri, Jul 10, 2026 at 06:35:19AM +0200, Christoph Hellwig wrote:
> On Thu, Jul 09, 2026 at 07:46:42AM -0600, Keith Busch wrote:
> > On Thu, Jul 09, 2026 at 09:13:52AM +0200, Christoph Hellwig wrote:
> > > On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> > >
> > > > + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> > > > + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> > > > + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> > > > + fa->fsx_dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
> > > > + fa->fsx_max_segments = bdev_max_segments(bdev);
> > >
> > > How is the max_segments value defined in a way that is meaningful to
> > > userspace?
> >
> > It tells you how many sub-sector vectors you can submit in your
> > readv/writev before it needs to add up to a logical block size.
> >
> > Ex: 4k logical block size, 4 byte DMA, 256 max segments. You can define
> > 4-byte iov's in your command, but you'll hit the max segment count
> > before you have a valid IO if they're all that small.
>
> Ah, makes sense. But besides the missing documentation I think
> max_segments is a bit of a misleading name for that.
>
> Something like max_vecs_per_block (although we don't expose blocks
> in the UAPI) or max_vecs_per_granularity (I think grammar wants a word
> with me for that, though...) might be a bit more suitable.
The granularity it has to add up to is defined by the
fsx_dio_offset_align attribute. This is a bit long, but to make that
relationship clear, how about:
fsx_dio_max_vecs_per_offset_align
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 9:14 ` Jan Kara
@ 2026-07-10 21:20 ` Eric Biggers
0 siblings, 0 replies; 9+ messages in thread
From: Eric Biggers @ 2026-07-10 21:20 UTC (permalink / raw)
To: Jan Kara
Cc: Christoph Hellwig, Keith Busch, linux-block, linux-ext4,
linux-f2fs-devel, linux-fsdevel, linux-xfs, axboe, brauner, cem,
jaegeuk, aalbersh, tytso, Keith Busch
On Thu, Jul 09, 2026 at 11:14:47AM +0200, Jan Kara wrote:
> On Thu 09-07-26 09:13:52, Christoph Hellwig wrote:
> > On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch wrote:
> > > + u32 dio_align = ext4_dio_alignment(inode);
> > > +
> > > + if (dio_align != 0) {
> >
> >
> > > + struct block_device *bdev = inode->i_sb->s_bdev;
> > > +
> > > + if (dio_align == 1) {
> > > + fa->fsx_dio_mem_align = bdev_dma_alignment(bdev) + 1;
> > > + fa->fsx_dio_offset_align = bdev_logical_block_size(bdev);
> > > + fa->fsx_dio_read_offset_align = bdev_logical_block_size(bdev);
> > > + } else {
> > > + fa->fsx_dio_mem_align = dio_align;
> > > + fa->fsx_dio_offset_align = dio_align;
> > > + fa->fsx_dio_read_offset_align = dio_align;
> > > + }
> >
> > Call bdev_fileattr and override the relevant field as needed?
> >
> > Question to the ext4 maintainers: why does ext4_dio_alignment
> > affect the in-memory alignment? If it does so, it should probably
> > also affect the virt boundry alignment..
>
> I guess that is mostly a historical accident. ext4_dio_alignment() returns
> 1 (iomap alignment is used and that's different for memory and file offset
> alignment), 0 (dio not supported, memory and file offset alignment is
> indeed the same), and blocksize (a special case which can happen for
> fscrypt if it supports dio and where I believe memory alignment
> requirements may be in fact different). I'm adding Eric to CC to answer
> what actual requirements fscrypt has for memory buffers for direct IO. I'd
> expect with inline encryption we would have the same requirements as
> ordinary iomap direct IO and for other code paths I'm not sure... Eric?
Please see Documentation/filesystems/fscrypt.rst:
The I/O request must be fully aligned to the filesystem block size.
This means that the file position the I/O is targeting, the lengths
of all I/O segments, and the memory addresses of all I/O buffers
must be multiples of this value. Note that the filesystem block
size may be greater than the logical block size of the block device.
We go over this about once a year, whenever someone suggests that the
memory alignment requirement is not needed. blk-crypto-fallback needs
it, the block layer itself needs it, and at least some storage drivers
need it.
To support less memory alignment, we'd need to:
- Make some fairly complex updates to blk-crypto-fallback to support
en/decrypting data units split across pages. Note that there's no
way to do this with zero overhead on other requests.
- Update the block layer to not split crypto data units across bvecs,
regardless of memory alignment. This also would add more overhead
to all requests.
- Test the hardware support on each eMMC and UFS host controller
individually and opt in the ones that actually correctly handle
crypto data units split across DMA segments. We already know it
does *not* work on at least one.
- And finally update the filesystems as the last step, not the first.
So far I haven't seen the point. Yes, applications can benefit from the
lower alignment in theory. But especially with encryption/decryption,
it isn't at all easy to support. This has apparently been getting
learned the hard way, as (for example) alignment was initially relaxed
for dm-crypt without testing it, and it had to be reverted
(https://lore.kernel.org/dm-devel/20221103152559.1909328-1-kbusch@meta.com/).
- Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [f2fs-dev] [PATCH] fs: report direct io constraints through file_getattr
[not found] <20260708011843.1036846-1-kbusch@meta.com>
2026-07-09 7:13 ` [PATCH] fs: report direct io constraints through file_getattr Christoph Hellwig
@ 2026-07-10 21:25 ` Eric Biggers
1 sibling, 0 replies; 9+ messages in thread
From: Eric Biggers @ 2026-07-10 21:25 UTC (permalink / raw)
To: Keith Busch
Cc: linux-block, linux-ext4, linux-f2fs-devel, linux-fsdevel,
linux-xfs, axboe, brauner, aalbersh, jack, Christoph Hellwig,
tytso, Keith Busch, jaegeuk, cem
On Tue, Jul 07, 2026 at 06:18:43PM -0700, Keith Busch via Linux-f2fs-devel wrote:
> From: Keith Busch <kbusch@kernel.org>
>
> Memory alignment constraints for direct io can vary depending on the
> backing storage hardware. Provide support through file_getattr to report
> the attributes necessary for applications to know how to construct valid
> read and write requests.
>
> Suggested-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Keith Busch <kbusch@kernel.org>
This seems to be reinventing STATX_DIOALIGN and STATX_DIO_READ_ALIGN.
Any reason for this?
- Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [f2fs-dev] [PATCH] fs: report direct io constraints through file_getattr
2026-07-09 8:51 ` Andrey Albershteyn
@ 2026-07-10 21:28 ` Eric Biggers
0 siblings, 0 replies; 9+ messages in thread
From: Eric Biggers @ 2026-07-10 21:28 UTC (permalink / raw)
To: Andrey Albershteyn
Cc: Christoph Hellwig, axboe, linux-xfs, brauner, jack, Keith Busch,
cem, aalbersh, linux-f2fs-devel, linux-block, Keith Busch, tytso,
linux-fsdevel, jaegeuk, linux-ext4
On Thu, Jul 09, 2026 at 10:51:39AM +0200, Andrey Albershteyn via Linux-f2fs-devel wrote:
> > Andrey, is there a man page or other official documentation for
> > file_setattr/file_getattr?
>
> No, I had a draft in cover letter but haven't got to sending it to
> man-pages. I will prepare a man page.
Or just abandon this series, and read the statx(2) man page which
documents the already-existing UAPI for getting the DIO alignments?
- Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-10 21:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260708011843.1036846-1-kbusch@meta.com>
2026-07-09 7:13 ` [PATCH] fs: report direct io constraints through file_getattr Christoph Hellwig
2026-07-09 8:51 ` Andrey Albershteyn
2026-07-10 21:28 ` [f2fs-dev] " Eric Biggers
2026-07-09 9:14 ` Jan Kara
2026-07-10 21:20 ` Eric Biggers
2026-07-09 13:46 ` Keith Busch
2026-07-10 4:35 ` Christoph Hellwig
2026-07-10 15:22 ` Keith Busch
2026-07-10 21:25 ` [f2fs-dev] " Eric Biggers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox