From: Christoph Hellwig <hch@lst.de>
To: Keith Busch <kbusch@meta.com>
Cc: linux-block@vger.kernel.org, linux-ext4@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org,
axboe@kernel.dk, jack@suse.cz, brauner@kernel.org,
cem@kernel.org, jaegeuk@kernel.org, aalbersh@kernel.org,
tytso@mit.edu, Keith Busch <kbusch@kernel.org>,
Christoph Hellwig <hch@lst.de>
Subject: Re: [PATCH] fs: report direct io constraints through file_getattr
Date: Thu, 9 Jul 2026 09:13:52 +0200 [thread overview]
Message-ID: <20260709071352.GA20180@lst.de> (raw)
In-Reply-To: <20260708011843.1036846-1-kbusch@meta.com>
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.
next parent reply other threads:[~2026-07-09 7:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260708011843.1036846-1-kbusch@meta.com>
2026-07-09 7:13 ` Christoph Hellwig [this message]
2026-07-09 8:51 ` [PATCH] fs: report direct io constraints through file_getattr Andrey Albershteyn
2026-07-09 9:14 ` Jan Kara
2026-07-09 13:46 ` Keith Busch
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=20260709071352.GA20180@lst.de \
--to=hch@lst.de \
--cc=aalbersh@kernel.org \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=jack@suse.cz \
--cc=jaegeuk@kernel.org \
--cc=kbusch@kernel.org \
--cc=kbusch@meta.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=tytso@mit.edu \
/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