* [PATCH] fs: add RWF_DIRECT for preadv2/pwritev2/io_uring to set IOCB_DIRECT per io
@ 2026-10-12 18:46 Stefan Metzmacher
0 siblings, 0 replies; only message in thread
From: Stefan Metzmacher @ 2026-10-12 18:46 UTC (permalink / raw)
To: linux-fsdevel
Cc: metze, Alexander Viro, Christian Brauner, Jan Kara, io-uring,
linux-api
It's useful to control this per io request instead of using O_DIRECT
for the file descriptor.
E.g. the SMB2_READFLAG_READ_UNBUFFERED and SMB2_WRITEFLAG_WRITE_UNBUFFERED
are also available per io request and this allows Samba to map then
to RWF_DIRECT.
kiocb_set_rw_flags() requires FMODE_CAN_ODIRECT (same check open()
does for O_DIRECT) and returns -EOPNOTSUPP otherwise, matching the
convention already used by RWF_NOWAIT/RWF_ATOMIC/RWF_DONTCACHE just
above it in the same function for "this flag isn't supported on this file".
IOCB_DIRECT predates RWF_DIRECT used a kernel-internal value,
but now IOCB_DIRECT is aligned with RWF_DIRECT the same way
commit ce71bfea207b ("fs: align IOCB_* flags with RWF_* flags")
already aligned the other shared flags.
The man-page.git will get something like this for man/man2/readv.2:
RWF_DIRECT (since Linux XXX)
Provide a per-I/O equivalent of the O_DIRECT open(2) flag.
This allows a single preadv2() or pwritev2() call to bypass the
page cache without the file descriptor having been opened with
O_DIRECT. Unlike enabling O_DIRECT with the fcntl(2) F_SETFL
operation, this does not change the file status flags of
the open file description, so other I/O on the same file
descriptor, or on any file descriptor referring to the same
open file description (see dup(2)), is not affected.
If the underlying file or block device does not support
O_DIRECT, the call fails; see ERRORS. As with O_DIRECT open(2),
the memory buffer, the file offset, and the I/O length
generally need to be aligned to the logical block size of
the underlying storage.
man/man2/io_submit.2 will also get updated and liburing
in man/io_uring_prep_readv2.3 and man/io_uring_prep_writev2.3
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Cc: io-uring@vger.kernel.org
Cc: linux-api@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/fs.h | 10 ++++++++--
include/uapi/linux/fs.h | 5 ++++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 83d41d9f1130..40d013a49378 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -344,10 +344,11 @@ struct readahead_control;
#define IOCB_ATOMIC (__force int) RWF_ATOMIC
#define IOCB_DONTCACHE (__force int) RWF_DONTCACHE
#define IOCB_NOSIGNAL (__force int) RWF_NOSIGNAL
+#define IOCB_DIRECT (__force int) RWF_DIRECT
/* non-RWF related bits - start at 16 */
+#define IOCB_NON_RWF_MASK (~0xffff)
#define IOCB_EVENTFD (1 << 16)
-#define IOCB_DIRECT (1 << 17)
#define IOCB_WRITE (1 << 18)
/* iocb->ki_waitq is valid */
#define IOCB_WAITQ (1 << 19)
@@ -3453,7 +3454,7 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags,
int kiocb_flags = 0;
/* make sure there's no overlap between RWF and private IOCB flags */
- BUILD_BUG_ON((__force int) RWF_SUPPORTED & IOCB_EVENTFD);
+ BUILD_BUG_ON((__force int) RWF_SUPPORTED & IOCB_NON_RWF_MASK);
if (!flags)
return 0;
@@ -3480,6 +3481,11 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags,
if (IS_DAX(ki->ki_filp->f_mapping->host))
return -EOPNOTSUPP;
}
+ if (flags & RWF_DIRECT) {
+ /* file system must support it, same as O_DIRECT */
+ if (!(ki->ki_filp->f_mode & FMODE_CAN_ODIRECT))
+ return -EOPNOTSUPP;
+ }
kiocb_flags |= (__force int) (flags & RWF_SUPPORTED);
if (flags & RWF_SYNC)
kiocb_flags |= IOCB_DSYNC;
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index a46c33692aa2..3aa5fd73d391 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -451,10 +451,13 @@ typedef int __bitwise __kernel_rwf_t;
/* prevent pipe and socket writes from raising SIGPIPE */
#define RWF_NOSIGNAL ((__force __kernel_rwf_t)0x00000100)
+/* per-IO O_DIRECT */
+#define RWF_DIRECT ((__force __kernel_rwf_t)0x00000200)
+
/* mask of flags supported by the kernel */
#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\
RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC |\
- RWF_DONTCACHE | RWF_NOSIGNAL)
+ RWF_DONTCACHE | RWF_NOSIGNAL | RWF_DIRECT)
#define PROCFS_IOCTL_MAGIC 'f'
--
2.43.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-12 18:47 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-12 18:46 [PATCH] fs: add RWF_DIRECT for preadv2/pwritev2/io_uring to set IOCB_DIRECT per io Stefan Metzmacher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox