From: Keith Busch <kbusch@kernel.org>
To: Christoph Hellwig <hch@infradead.org>
Cc: Keith Busch <kbusch@meta.com>,
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
Subject: Re: [PATCHv2 3/5] xfs: report direct io attributes through file_getattr
Date: Tue, 14 Jul 2026 15:09:57 -0600 [thread overview]
Message-ID: <alalpRYxjqtdJhVR@kbusch-mbp> (raw)
In-Reply-To: <alTTRoOEglwuf4vg@infradead.org>
On Mon, Jul 13, 2026 at 05:00:06AM -0700, Christoph Hellwig wrote:
> Or maybe using the file attr for this isn't actually a good idea,
> and we should do an ioctl instead which automatically gets routed to
> the block device fops?
Something like this instead?
---
diff --git a/block/ioctl.c b/block/ioctl.c
index 3d4ea1537457d..6de2f87bcb8bd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -642,6 +642,21 @@ static int blkdev_bszset(struct file *file, blk_mode_t mode,
return ret;
}
+void bdev_dio_align(struct block_device *bdev, struct fs_dio_align *align)
+{
+ align->dio_mem_align = bdev_dma_alignment(bdev) + 1;
+ align->dio_offset_align = bdev_logical_block_size(bdev);
+ align->dio_read_offset_align = bdev_logical_block_size(bdev);
+ align->dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
+ align->dio_offset_align_max_vecs = bdev_max_segments(bdev);
+}
+EXPORT_SYMBOL_GPL(bdev_dio_align);
+
/*
* Common commands that are handled the same way on native and compat
* user space. Note the separate arg/argp parameters that are needed
@@ -690,6 +705,12 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
return put_uint(argp, bdev_io_opt(bdev));
case BLKALIGNOFF:
return put_int(argp, bdev_alignment_offset(bdev));
+ case FS_IOC_GETDIOALIGN: {
+ struct fs_dio_align align = {};
+
+ bdev_dio_align(bdev, &align);
+ return copy_to_user(argp, &align, sizeof(align)) ? -EFAULT : 0;
+ }
case BLKDISCARDZEROES:
return put_uint(argp, 0);
case BLKSECTGET:
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 1b53701bebea1..e980522fa7539 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -49,6 +49,7 @@
#include <linux/mount.h>
#include <linux/fileattr.h>
+#include <linux/blkdev.h>
/* Return 0 on success or positive error */
int
@@ -1244,6 +1245,23 @@ xfs_file_ioctl(
"%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
current->comm);
return -ENOTTY;
+ case FS_IOC_GETDIOALIGN: {
+ struct fs_dio_align align = {};
+
+ if (!S_ISREG(inode->i_mode))
+ return -ENOTTY;
+ bdev_dio_align(xfs_inode_buftarg(ip)->bt_bdev, &align);
+ if (xfs_is_cow_inode(ip))
+ align.dio_offset_align = xfs_inode_alloc_unitsize(ip);
+ if (copy_to_user(arg, &align, sizeof(align)))
+ return -EFAULT;
+ return 0;
+ }
case XFS_IOC_DIOINFO: {
struct kstat st;
struct dioattr da;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 9213a5716f95a..dc32acf696e40 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1607,6 +1607,17 @@ static inline unsigned int bdev_dma_alignment(struct block_device *bdev)
return queue_dma_alignment(bdev_get_queue(bdev));
}
+static inline unsigned long bdev_virt_boundary_mask(struct block_device *bdev)
+{
+ return bdev_get_queue(bdev)->limits.virt_boundary_mask;
+}
+
+static inline unsigned int
+bdev_virt_boundary_alignment(struct block_device *bdev)
+{
+ return bdev_virt_boundary_mask(bdev) + 1;
+}
+
static inline unsigned int
blk_lim_dma_alignment_and_pad(struct queue_limits *lim)
{
@@ -1805,6 +1816,8 @@ int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend);
int sync_blockdev_nowait(struct block_device *bdev);
void sync_bdevs(bool wait);
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask);
+struct fs_dio_align;
+void bdev_dio_align(struct block_device *bdev, struct fs_dio_align *align);
void printk_all_partitions(void);
int __init early_lookup_bdev(const char *pathname, dev_t *dev);
#else
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index bd87262f2e349..81b0c81e17282 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -234,6 +234,21 @@ struct file_attr {
#define FILE_ATTR_SIZE_VER0 24
#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0
+struct fs_dio_align {
+ __u32 dio_mem_align; /* buffer alignment */
+ __u32 dio_offset_align; /* write offset alignment */
+ __u32 dio_read_offset_align; /* read offset alignment */
+ __u32 dio_virt_boundary_align; /* segment boundary */
+ __u32 dio_offset_align_max_vecs; /* max vecs per unit */
+ __u32 dio_reserved[3]; /* must be zero */
+};
+
/*
* Flags for the fsx_xflags field
*/
@@ -344,6 +359,8 @@ struct file_attr {
#define FS_IOC_GETFSSYSFSPATH _IOR(0x15, 1, struct fs_sysfs_path)
/* Get logical block metadata capability details */
#define FS_IOC_GETLBMD_CAP _IOWR(0x15, 2, struct logical_block_metadata_cap)
+/* Get direct I/O alignment and layout constraints */
+#define FS_IOC_GETDIOALIGN _IOR(0x15, 3, struct fs_dio_align)
/*
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
--
WARNING: multiple messages have this Message-ID (diff)
From: Keith Busch via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Christoph Hellwig <hch@infradead.org>
Cc: axboe@kernel.dk, linux-xfs@vger.kernel.org, brauner@kernel.org,
jack@suse.cz, Keith Busch <kbusch@meta.com>,
cem@kernel.org, aalbersh@kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
linux-block@vger.kernel.org, tytso@mit.edu,
linux-fsdevel@vger.kernel.org, jaegeuk@kernel.org,
linux-ext4@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCHv2 3/5] xfs: report direct io attributes through file_getattr
Date: Tue, 14 Jul 2026 15:09:57 -0600 [thread overview]
Message-ID: <alalpRYxjqtdJhVR@kbusch-mbp> (raw)
In-Reply-To: <alTTRoOEglwuf4vg@infradead.org>
On Mon, Jul 13, 2026 at 05:00:06AM -0700, Christoph Hellwig wrote:
> Or maybe using the file attr for this isn't actually a good idea,
> and we should do an ioctl instead which automatically gets routed to
> the block device fops?
Something like this instead?
---
diff --git a/block/ioctl.c b/block/ioctl.c
index 3d4ea1537457d..6de2f87bcb8bd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -642,6 +642,21 @@ static int blkdev_bszset(struct file *file, blk_mode_t mode,
return ret;
}
+void bdev_dio_align(struct block_device *bdev, struct fs_dio_align *align)
+{
+ align->dio_mem_align = bdev_dma_alignment(bdev) + 1;
+ align->dio_offset_align = bdev_logical_block_size(bdev);
+ align->dio_read_offset_align = bdev_logical_block_size(bdev);
+ align->dio_virt_boundary_align = bdev_virt_boundary_alignment(bdev);
+ align->dio_offset_align_max_vecs = bdev_max_segments(bdev);
+}
+EXPORT_SYMBOL_GPL(bdev_dio_align);
+
/*
* Common commands that are handled the same way on native and compat
* user space. Note the separate arg/argp parameters that are needed
@@ -690,6 +705,12 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
return put_uint(argp, bdev_io_opt(bdev));
case BLKALIGNOFF:
return put_int(argp, bdev_alignment_offset(bdev));
+ case FS_IOC_GETDIOALIGN: {
+ struct fs_dio_align align = {};
+
+ bdev_dio_align(bdev, &align);
+ return copy_to_user(argp, &align, sizeof(align)) ? -EFAULT : 0;
+ }
case BLKDISCARDZEROES:
return put_uint(argp, 0);
case BLKSECTGET:
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 1b53701bebea1..e980522fa7539 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -49,6 +49,7 @@
#include <linux/mount.h>
#include <linux/fileattr.h>
+#include <linux/blkdev.h>
/* Return 0 on success or positive error */
int
@@ -1244,6 +1245,23 @@ xfs_file_ioctl(
"%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
current->comm);
return -ENOTTY;
+ case FS_IOC_GETDIOALIGN: {
+ struct fs_dio_align align = {};
+
+ if (!S_ISREG(inode->i_mode))
+ return -ENOTTY;
+ bdev_dio_align(xfs_inode_buftarg(ip)->bt_bdev, &align);
+ if (xfs_is_cow_inode(ip))
+ align.dio_offset_align = xfs_inode_alloc_unitsize(ip);
+ if (copy_to_user(arg, &align, sizeof(align)))
+ return -EFAULT;
+ return 0;
+ }
case XFS_IOC_DIOINFO: {
struct kstat st;
struct dioattr da;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 9213a5716f95a..dc32acf696e40 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1607,6 +1607,17 @@ static inline unsigned int bdev_dma_alignment(struct block_device *bdev)
return queue_dma_alignment(bdev_get_queue(bdev));
}
+static inline unsigned long bdev_virt_boundary_mask(struct block_device *bdev)
+{
+ return bdev_get_queue(bdev)->limits.virt_boundary_mask;
+}
+
+static inline unsigned int
+bdev_virt_boundary_alignment(struct block_device *bdev)
+{
+ return bdev_virt_boundary_mask(bdev) + 1;
+}
+
static inline unsigned int
blk_lim_dma_alignment_and_pad(struct queue_limits *lim)
{
@@ -1805,6 +1816,8 @@ int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend);
int sync_blockdev_nowait(struct block_device *bdev);
void sync_bdevs(bool wait);
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask);
+struct fs_dio_align;
+void bdev_dio_align(struct block_device *bdev, struct fs_dio_align *align);
void printk_all_partitions(void);
int __init early_lookup_bdev(const char *pathname, dev_t *dev);
#else
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index bd87262f2e349..81b0c81e17282 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -234,6 +234,21 @@ struct file_attr {
#define FILE_ATTR_SIZE_VER0 24
#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0
+struct fs_dio_align {
+ __u32 dio_mem_align; /* buffer alignment */
+ __u32 dio_offset_align; /* write offset alignment */
+ __u32 dio_read_offset_align; /* read offset alignment */
+ __u32 dio_virt_boundary_align; /* segment boundary */
+ __u32 dio_offset_align_max_vecs; /* max vecs per unit */
+ __u32 dio_reserved[3]; /* must be zero */
+};
+
/*
* Flags for the fsx_xflags field
*/
@@ -344,6 +359,8 @@ struct file_attr {
#define FS_IOC_GETFSSYSFSPATH _IOR(0x15, 1, struct fs_sysfs_path)
/* Get logical block metadata capability details */
#define FS_IOC_GETLBMD_CAP _IOWR(0x15, 2, struct logical_block_metadata_cap)
+/* Get direct I/O alignment and layout constraints */
+#define FS_IOC_GETDIOALIGN _IOR(0x15, 3, struct fs_dio_align)
/*
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
--
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
next prev parent reply other threads:[~2026-07-14 21:09 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 21:06 [PATCHv2 0/5] direct-io file extended attributes Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-10 21:06 ` [PATCHv2 1/5] fs: add direct io attributes to file_getattr Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-13 10:14 ` Christoph Hellwig
2026-07-13 10:14 ` Christoph Hellwig
2026-07-10 21:06 ` [PATCHv2 2/5] block: report direct io attributes through file_getattr Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-13 11:57 ` Christoph Hellwig
2026-07-13 11:57 ` Christoph Hellwig
2026-07-10 21:06 ` [PATCHv2 3/5] xfs: " Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-13 12:00 ` Christoph Hellwig
2026-07-13 12:00 ` [f2fs-dev] " Christoph Hellwig
2026-07-14 21:09 ` Keith Busch [this message]
2026-07-14 21:09 ` Keith Busch via Linux-f2fs-devel
2026-07-15 4:37 ` Christoph Hellwig
2026-07-15 4:37 ` [f2fs-dev] " Christoph Hellwig
2026-07-10 21:06 ` [PATCHv2 4/5] ext4: " Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-10 21:06 ` [PATCHv2 5/5] f2fs: " Keith Busch
2026-07-10 21:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
2026-07-10 21:53 ` [f2fs-dev] [PATCHv2 0/5] direct-io file extended attributes Eric Biggers
2026-07-10 21:53 ` Eric Biggers via Linux-f2fs-devel
2026-07-10 22:58 ` Keith Busch
2026-07-10 22:58 ` Keith Busch via Linux-f2fs-devel
2026-07-11 0:24 ` Eric Biggers
2026-07-11 0:24 ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-07-11 1:06 ` Keith Busch
2026-07-11 1:06 ` [f2fs-dev] " Keith Busch via Linux-f2fs-devel
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=alalpRYxjqtdJhVR@kbusch-mbp \
--to=kbusch@kernel.org \
--cc=aalbersh@kernel.org \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--cc=jaegeuk@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.