From: Mike Snitzer <snitzer@kernel.org>
To: Trond Myklebust <trondmy@kernel.org>, Anna Schumaker <anna@kernel.org>
Cc: Tom Haynes <loghyr@hammerspace.com>, Chuck Lever <cel@kernel.org>,
linux-nfs@vger.kernel.org
Subject: [PATCH 4/4] nfs4.2: open UNCACHEABLE_FILE_DATA files with O_DIRECT
Date: Wed, 24 Jun 2026 15:17:06 -0400 [thread overview]
Message-ID: <20260624191706.72544-5-snitzer@kernel.org> (raw)
In-Reply-To: <20260624191706.72544-1-snitzer@kernel.org>
Honor the per-file UNCACHEABLE_FILE_DATA attribute by transparently
opening such regular files with O_DIRECT, so reads and writes bypass the
page cache as the attribute requires, without the application having to
request O_DIRECT itself.
This follows the model the specification describes: the attribute is
"similar in intent to O_DIRECT" and clients "retain flexibility in how
they satisfy the requirements" (draft-ietf-nfsv4-uncacheable-files
Section 4.4, "Relationship to Direct I/O"), and its Implementation
Status (Section 6) describes a prototype Linux client that "treats the
attribute as an indication to use O_DIRECT-like behavior for file
access".
Introduce an NFS_CONTEXT_O_DIRECT open-context flag: nfs4_atomic_open()
sets it when the resolved inode has uncacheable_file_data set (and the
open is not O_APPEND), and the open paths nfs_atomic_open() and
nfs4_file_open() apply O_DIRECT to the file when the flag is set.
The I/O mode is thus selected at open time and is not changed for an
already-open file: a later change to the attribute takes effect on the
next open. The specification permits this -- a client that has already
opened a file MAY continue with its existing caching behavior and apply
the updated attribute to subsequent operations (Section 5).
The delegation interaction in Section 4.3 was considered: it permits read
caching to remain when another NFSv4.2 mechanism, such as a delegation,
already ensures a consistent view of the file. That relaxation is
optional ("may remain appropriate") and read-only -- it does not relax
write-behind suppression (Section 4.1) or the WRITE durability invariant
(Section 4.2). This implementation deliberately does not take it: an
uncacheable file is opened O_DIRECT regardless of any delegation held,
which is compliant (read caching is simply suppressed more aggressively
than the Section 4.3 minimum) and avoids decoupling read vs write caching
behind a single open flag. Relaxing reads under a delegation is left as
a possible future optimization.
Section 6 observes the benefit holds "for applications that issue
well-formed I/O requests". That alignment caveat does not constrain the
Linux NFS client's over-the-wire path: the client readily issues
misaligned I/O using O_DIRECT over SunRPC to the remote NFS server. The
only place a fallback from O_DIRECT to buffered I/O for misaligned I/O
applies is NFS LOCALIO (fs/nfs/localio.c), which detects non-DIO-aligned
I/O and falls back internally; that path is unaffected by this change.
See: https://datatracker.ietf.org/doc/draft-ietf-nfsv4-uncacheable-files/
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Assisted-by: Claude:claude-opus-4-8
---
fs/nfs/dir.c | 4 ++++
fs/nfs/nfs4file.c | 2 ++
fs/nfs/nfs4proc.c | 9 +++++++++
include/linux/nfs_fs.h | 1 +
4 files changed, 16 insertions(+)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c7b723c18620..6b07abf272b1 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2208,6 +2208,10 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
goto out;
}
file->f_mode |= FMODE_CAN_ODIRECT;
+ if (test_bit(NFS_CONTEXT_O_DIRECT, &ctx->flags)) {
+ file->f_flags |= O_DIRECT;
+ open_flags |= O_DIRECT;
+ }
err = nfs_finish_open(ctx, ctx->dentry, file, open_flags);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index be40e126c539..6401f6363f75 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -91,6 +91,8 @@ nfs4_file_open(struct inode *inode, struct file *filp)
nfs_fscache_open_file(inode, filp);
err = 0;
filp->f_mode |= FMODE_CAN_ODIRECT;
+ if (test_bit(NFS_CONTEXT_O_DIRECT, &ctx->flags))
+ filp->f_flags |= O_DIRECT;
out_put_ctx:
put_nfs_open_context(ctx);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 72d809463de7..5bec57a2027c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3854,6 +3854,15 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
if (IS_ERR(state))
return ERR_CAST(state);
+ /*
+ * Use O_DIRECT if file was marked as Uncacheable, see:
+ * https://datatracker.ietf.org/doc/draft-ietf-nfsv4-uncacheable-files/
+ */
+ if (!(open_flags & O_DIRECT) && NFS_I(state->inode)->uncacheable_file_data) {
+ if (!(open_flags & O_APPEND))
+ set_bit(NFS_CONTEXT_O_DIRECT, &ctx->flags);
+ }
+
return state->inode;
}
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index b9228086a1df..0df1d70eee90 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -110,6 +110,7 @@ struct nfs_open_context {
#define NFS_CONTEXT_UNLOCK (3)
#define NFS_CONTEXT_FILE_OPEN (4)
#define NFS_CONTEXT_WRITE_SYNC (5)
+#define NFS_CONTEXT_O_DIRECT (6)
struct nfs4_threshold *mdsthreshold;
struct list_head list;
--
2.47.3
prev parent reply other threads:[~2026-06-24 19:17 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-24 19:17 [PATCH 0/4] nfs: NFSv4.2 client support for UNCACHEABLE_FILE_DATA Mike Snitzer
2026-06-24 19:17 ` [PATCH 1/4] nfs4.2: add nfs4_2.x to generate the UNCACHEABLE_FILE_DATA attribute Mike Snitzer
2026-06-24 19:17 ` [PATCH 2/4] nfs4.2: add UNCACHEABLE_FILE_DATA attribute support Mike Snitzer
2026-06-24 19:17 ` [PATCH 3/4] nfs4.2: request UNCACHEABLE_FILE_DATA only for regular files Mike Snitzer
2026-06-24 19:17 ` Mike Snitzer [this message]
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=20260624191706.72544-5-snitzer@kernel.org \
--to=snitzer@kernel.org \
--cc=anna@kernel.org \
--cc=cel@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=loghyr@hammerspace.com \
--cc=trondmy@kernel.org \
/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.