From: Keith Busch <kbusch@meta.com>
To: <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>
Cc: <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>
Subject: [PATCHv2 1/5] fs: add direct io attributes to file_getattr
Date: Fri, 10 Jul 2026 14:06:42 -0700 [thread overview]
Message-ID: <20260710210646.3576365-2-kbusch@meta.com> (raw)
In-Reply-To: <20260710210646.3576365-1-kbusch@meta.com>
From: Keith Busch <kbusch@kernel.org>
Direct I/O imposes alignment and layout constraints that come from both
the filesystem and its backing storage. statx() reports some of these,
but not all, and it can no longer be extended. Report the complete set
through file_getattr() in new struct file_attr fields so applications
can know the constraints they have to work with.
The fields are valid only when FS_XFLAG_DIO is set in fa_xflags. When it
is clear the file does not report direct I/O geometry, for example,
because the filesystem configuration does not allow direct I/O, does not
support file_getatter, or is using the legacy block sized alignment
constraints.
The new fields are defined as follows:
- fa_dio_mem_align: byte alignment required for each I/O memory
buffer. The starting address and length of each buffer vector must
be a multiple of this value.
- fa_dio_offset_align: alignment required for the file offset and
total length of a write.
- fa_dio_read_offset_align: the same, but for reads. It may be
smaller than the write alignment allowing reads at a finer
granularity, but will be at most the same as writes.
- fa_dio_virt_boundary_align: alignment required at the boundary
between adjacent memory segments of a multi-segment transfer. The
previous segment must end on that boundary and the next must start
on it; otherwise, the kernel will split the command at that vector
if possible, or return an error if not (the accumulated length
is shorter than "offset_align"). A value of 1 means there is no such
constraint.
- fa_dio_offset_align_max_vecs: the maximum number of io vectors that
may compose a single fa_dio_offset_align unit. Buffers too small to
reach that unit within this many vectors can not form a valid I/O
and will be rejected by the kernel.
The fields are read only; file_setattr() ignores them.
The fa_pad field is introduced as a reserved field to account for an
implicit padding on 64-bit architectures and to make the struct the same
size for 32-bit. It must be zero to keep the space available for future
use.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
fs/file_attr.c | 7 +++++++
include/linux/fileattr.h | 10 ++++++++--
include/uapi/linux/fs.h | 10 +++++++++-
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/fs/file_attr.c b/fs/file_attr.c
index bfb00d256dd56..b37a55f54a449 100644
--- a/fs/file_attr.c
+++ b/fs/file_attr.c
@@ -110,6 +110,11 @@ static void fileattr_to_file_attr(const struct file_kattr *fa,
fattr->fa_nextents = fa->fsx_nextents;
fattr->fa_projid = fa->fsx_projid;
fattr->fa_cowextsize = fa->fsx_cowextsize;
+ fattr->fa_dio_mem_align = fa->fsx_dio_mem_align;
+ fattr->fa_dio_offset_align = fa->fsx_dio_offset_align;
+ fattr->fa_dio_read_offset_align = fa->fsx_dio_read_offset_align;
+ fattr->fa_dio_virt_boundary_align = fa->fsx_dio_virt_boundary_align;
+ fattr->fa_dio_offset_align_max_vecs = fa->fsx_dio_offset_align_max_vecs;
}
/**
@@ -145,6 +150,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;
fileattr_fill_xflags(fa, fattr->fa_xflags & ~FS_XFLAG_RDONLY_MASK);
fa->fsx_extsize = fattr->fa_extsize;
diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
index 58044b5980162..3d5384c79398e 100644
--- a/include/linux/fileattr.h
+++ b/include/linux/fileattr.h
@@ -17,11 +17,11 @@
/* Read-only inode flags */
#define FS_XFLAG_RDONLY_MASK \
(FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY | \
- FS_XFLAG_CASEFOLD | FS_XFLAG_CASENONPRESERVING)
+ FS_XFLAG_CASEFOLD | FS_XFLAG_CASENONPRESERVING | FS_XFLAG_DIO)
/* Flags to indicate valid value of fsx_ fields */
#define FS_XFLAG_VALUES_MASK \
- (FS_XFLAG_EXTSIZE | FS_XFLAG_COWEXTSIZE)
+ (FS_XFLAG_EXTSIZE | FS_XFLAG_COWEXTSIZE | FS_XFLAG_DIO)
/* Flags for directories */
#define FS_XFLAG_DIRONLY_MASK \
@@ -49,6 +49,12 @@ struct file_kattr {
u32 fsx_nextents; /* nextents field value (get) */
u32 fsx_projid; /* project identifier (get/set) */
u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
+ /* struct file_attr dio alignment: */
+ u32 fsx_dio_mem_align;
+ u32 fsx_dio_offset_align;
+ u32 fsx_dio_read_offset_align;
+ u32 fsx_dio_virt_boundary_align;
+ u32 fsx_dio_offset_align_max_vecs;
/* selectors: */
bool flags_valid:1;
bool fsx_valid:1;
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index bd87262f2e349..a49572fab3726 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -229,10 +229,17 @@ struct file_attr {
__u32 fa_nextents; /* nextents field value (get) */
__u32 fa_projid; /* project identifier (get/set) */
__u32 fa_cowextsize; /* CoW extsize field value (get/set) */
+ __u32 fa_dio_mem_align; /* DIO memory buffer align (get) */
+ __u32 fa_dio_offset_align; /* DIO file offset align (get) */
+ __u32 fa_dio_read_offset_align; /* DIO read offset align (get) */
+ __u32 fa_dio_virt_boundary_align; /* DIO virt boundary (get) */
+ __u32 fa_dio_offset_align_max_vecs; /* DIO vecs per unit (get) */
+ __u32 fa_pad; /* alignment padding, reserved for future use */
};
#define FILE_ATTR_SIZE_VER0 24
-#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0
+#define FILE_ATTR_SIZE_VER1 48
+#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER1
/*
* Flags for the fsx_xflags field
@@ -261,6 +268,7 @@ struct file_attr {
*/
#define FS_XFLAG_CASEFOLD 0x00040000 /* case-insensitive lookups */
#define FS_XFLAG_CASENONPRESERVING 0x00080000 /* case not preserved */
+#define FS_XFLAG_DIO 0x00100000 /* DIO alignment info valid */
#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
/* the read-only stuff doesn't really belong here, but any other place is
--
2.53.0-Meta
next prev parent reply other threads:[~2026-07-10 21:28 UTC|newest]
Thread overview: 8+ 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 ` Keith Busch [this message]
2026-07-10 21:06 ` [PATCHv2 2/5] block: report direct io attributes through file_getattr Keith Busch
2026-07-10 21:06 ` [PATCHv2 3/5] xfs: " Keith Busch
2026-07-10 21:06 ` [PATCHv2 4/5] ext4: " Keith Busch
2026-07-10 21:06 ` [PATCHv2 5/5] f2fs: " Keith Busch
2026-07-10 21:53 ` [f2fs-dev] [PATCHv2 0/5] direct-io file extended attributes Eric Biggers
2026-07-10 22:58 ` 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=20260710210646.3576365-2-kbusch@meta.com \
--to=kbusch@meta.com \
--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=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