From 14958516bf45f92a8609cb6ad504e92550b416d7 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 7 Jul 2025 11:00:34 -0400 Subject: [PATCH] nfsd: add a NFSD_IO_FADVISE setting to io_cache_write Signed-off-by: Jeff Layton --- fs/nfsd/debugfs.c | 2 ++ fs/nfsd/nfs3proc.c | 24 +++++++++++++++++++----- fs/nfsd/nfsd.h | 3 ++- fs/nfsd/vfs.c | 4 ++++ fs/nfsd/xdr3.h | 1 + 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/debugfs.c b/fs/nfsd/debugfs.c index fadf1d88f640..d0f7dfe6d621 100644 --- a/fs/nfsd/debugfs.c +++ b/fs/nfsd/debugfs.c @@ -89,6 +89,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_read_fops, nfsd_io_cache_read_get, * %0: NFS WRITE will use buffered IO (default) * %1: NFS WRITE will use dontcache (buffered IO w/ dropbehind) * %2: NFS WRITE will use direct IO + * %3: NFS stable WRITE will use dontcache + fadvise DONTNEED after COMMIT * * The default value of this setting is zero (buffered IO is * used). This setting takes immediate effect for all NFS @@ -107,6 +108,7 @@ static int nfsd_io_cache_write_set(void *data, u64 val) case NFSD_IO_BUFFERED: case NFSD_IO_DONTCACHE: case NFSD_IO_DIRECT: + case NFSD_IO_FADVISE: nfsd_io_cache_write = val; break; default: diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index b6d03e1ef5f7..6737d22c001d 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "cache.h" #include "xdr3.h" @@ -748,7 +749,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) { struct nfsd3_commitargs *argp = rqstp->rq_argp; struct nfsd3_commitres *resp = rqstp->rq_resp; - struct nfsd_file *nf; dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", SVCFH_fmt(&argp->fh), @@ -757,17 +757,31 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) fh_copy(&resp->fh, &argp->fh); resp->status = nfsd_file_acquire_gc(rqstp, &resp->fh, NFSD_MAY_WRITE | - NFSD_MAY_NOT_BREAK_LEASE, &nf); + NFSD_MAY_NOT_BREAK_LEASE, &resp->nf); if (resp->status) goto out; - resp->status = nfsd_commit(rqstp, &resp->fh, nf, argp->offset, + resp->status = nfsd_commit(rqstp, &resp->fh, resp->nf, argp->offset, argp->count, resp->verf); - nfsd_file_put(nf); out: resp->status = nfsd3_map_status(resp->status); return rpc_success; } +static void +nfsd3_release_commit(struct svc_rqst *rqstp) +{ + struct nfsd3_commitargs *argp = rqstp->rq_argp; + struct nfsd3_commitres *resp = rqstp->rq_resp; + + fh_put(&resp->fh); + if (resp->nf) { + if (nfsd_io_cache_write == NFSD_IO_FADVISE) + vfs_fadvise(nfsd_file_file(resp->nf), argp->offset, + argp->count, POSIX_FADV_DONTNEED); + nfsd_file_put(resp->nf); + } +} + /* * NFSv3 Server procedures. @@ -1039,7 +1053,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_func = nfsd3_proc_commit, .pc_decode = nfs3svc_decode_commitargs, .pc_encode = nfs3svc_encode_commitres, - .pc_release = nfs3svc_release_fhandle, + .pc_release = nfsd3_release_commit, .pc_argsize = sizeof(struct nfsd3_commitargs), .pc_argzero = sizeof(struct nfsd3_commitargs), .pc_ressize = sizeof(struct nfsd3_commitres), diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 1ae38c5557c4..b21902e02982 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -156,7 +156,8 @@ extern bool nfsd_disable_splice_read __read_mostly; enum { NFSD_IO_BUFFERED = 0, NFSD_IO_DONTCACHE, - NFSD_IO_DIRECT + NFSD_IO_DIRECT, + NFSD_IO_FADVISE }; extern u64 nfsd_io_cache_read __read_mostly; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 08350070e083..5d4588a106b2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1271,6 +1271,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, case NFSD_IO_DONTCACHE: kiocb.ki_flags = IOCB_DONTCACHE; break; + case NFSD_IO_FADVISE: + if (stable) + kiocb.ki_flags = IOCB_DONTCACHE; + break; case NFSD_IO_BUFFERED: break; } diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h index 522067b7fd75..ec91a24e651a 100644 --- a/fs/nfsd/xdr3.h +++ b/fs/nfsd/xdr3.h @@ -217,6 +217,7 @@ struct nfsd3_commitres { __be32 status; struct svc_fh fh; __be32 verf[2]; + struct nfsd_file *nf; }; struct nfsd3_getaclres { -- 2.50.0