From: Jeff Layton <jlayton@kernel.org>
To: Mike Snitzer <snitzer@kernel.org>, linux-nfs@vger.kernel.org
Cc: Chuck Lever <chuck.lever@oracle.com>,
Anna Schumaker <anna@kernel.org>,
Trond Myklebust <trondmy@hammerspace.com>,
NeilBrown <neilb@suse.de>,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v14 13/25] SUNRPC: replace program list with program array
Date: Thu, 29 Aug 2024 12:02:21 -0400 [thread overview]
Message-ID: <df287db6d3c6936503c46e124b1011439dc9c9f2.camel@kernel.org> (raw)
In-Reply-To: <20240829010424.83693-14-snitzer@kernel.org>
On Wed, 2024-08-28 at 21:04 -0400, Mike Snitzer wrote:
> From: NeilBrown <neil@brown.name>
>
> A service created with svc_create_pooled() can be given a linked list of
> programs and all of these will be served.
>
> Using a linked list makes it cumbersome when there are several programs
> that can be optionally selected with CONFIG settings.
>
> After this patch is applied, API consumers must use only
> svc_create_pooled() when creating an RPC service that listens for more
> than one RPC program.
>
> Acked-by: Chuck Lever <chuck.lever@oracle.com>
> Signed-off-by: NeilBrown <neil@brown.name>
> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
> ---
> fs/nfsd/nfsctl.c | 2 +-
> fs/nfsd/nfsd.h | 2 +-
> fs/nfsd/nfssvc.c | 38 ++++++++++-----------
> include/linux/sunrpc/svc.h | 7 ++--
> net/sunrpc/svc.c | 68 ++++++++++++++++++++++----------------
> net/sunrpc/svc_xprt.c | 2 +-
> net/sunrpc/svcauth_unix.c | 3 +-
> 7 files changed, 67 insertions(+), 55 deletions(-)
>
> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index 1c9e5b4bcb0a..64c1b4d649bc 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -2246,7 +2246,7 @@ static __net_init int nfsd_net_init(struct net *net)
> if (retval)
> goto out_repcache_error;
> memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
> - nn->nfsd_svcstats.program = &nfsd_program;
> + nn->nfsd_svcstats.program = &nfsd_programs[0];
> for (i = 0; i < sizeof(nn->nfsd_versions); i++)
> nn->nfsd_versions[i] = nfsd_support_version(i);
> for (i = 0; i < sizeof(nn->nfsd4_minorversions); i++)
> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
> index 4ccbf014a2c7..b0d3e82d6dcd 100644
> --- a/fs/nfsd/nfsd.h
> +++ b/fs/nfsd/nfsd.h
> @@ -85,7 +85,7 @@ struct nfsd_genl_rqstp {
> u32 rq_opnum[NFSD_MAX_OPS_PER_COMPOUND];
> };
>
> -extern struct svc_program nfsd_program;
> +extern struct svc_program nfsd_programs[];
> extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
> extern struct mutex nfsd_mutex;
> extern spinlock_t nfsd_drc_lock;
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index e43d440f9f0a..c639fbe4d8c2 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -35,7 +35,6 @@
> #define NFSDDBG_FACILITY NFSDDBG_SVC
>
> atomic_t nfsd_th_cnt = ATOMIC_INIT(0);
> -extern struct svc_program nfsd_program;
> static int nfsd(void *vrqstp);
> #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
> static int nfsd_acl_rpcbind_set(struct net *,
> @@ -90,20 +89,9 @@ static const struct svc_version *nfsd_acl_version[] = {
> # endif
> };
>
> -#define NFSD_ACL_MINVERS 2
> +#define NFSD_ACL_MINVERS 2
> #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version)
>
> -static struct svc_program nfsd_acl_program = {
> - .pg_prog = NFS_ACL_PROGRAM,
> - .pg_nvers = NFSD_ACL_NRVERS,
> - .pg_vers = nfsd_acl_version,
> - .pg_name = "nfsacl",
> - .pg_class = "nfsd",
> - .pg_authenticate = &svc_set_client,
> - .pg_init_request = nfsd_acl_init_request,
> - .pg_rpcbind_set = nfsd_acl_rpcbind_set,
> -};
> -
> #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
>
> static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
> @@ -116,18 +104,29 @@ static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
> #endif
> };
>
> -struct svc_program nfsd_program = {
> -#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
> - .pg_next = &nfsd_acl_program,
> -#endif
> +struct svc_program nfsd_programs[] = {
> + {
> .pg_prog = NFS_PROGRAM, /* program number */
> .pg_nvers = NFSD_MAXVERS+1, /* nr of entries in nfsd_version */
> .pg_vers = nfsd_version, /* version table */
> .pg_name = "nfsd", /* program name */
> .pg_class = "nfsd", /* authentication class */
> - .pg_authenticate = &svc_set_client, /* export authentication */
> + .pg_authenticate = svc_set_client, /* export authentication */
> .pg_init_request = nfsd_init_request,
> .pg_rpcbind_set = nfsd_rpcbind_set,
> + },
> +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
> + {
> + .pg_prog = NFS_ACL_PROGRAM,
> + .pg_nvers = NFSD_ACL_NRVERS,
> + .pg_vers = nfsd_acl_version,
> + .pg_name = "nfsacl",
> + .pg_class = "nfsd",
> + .pg_authenticate = svc_set_client,
> + .pg_init_request = nfsd_acl_init_request,
> + .pg_rpcbind_set = nfsd_acl_rpcbind_set,
> + },
> +#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
> };
>
> bool nfsd_support_version(int vers)
> @@ -637,7 +636,8 @@ int nfsd_create_serv(struct net *net)
> if (nfsd_max_blksize == 0)
> nfsd_max_blksize = nfsd_get_default_max_blksize();
> nfsd_reset_versions(nn);
> - serv = svc_create_pooled(&nfsd_program, &nn->nfsd_svcstats,
> + serv = svc_create_pooled(nfsd_programs, ARRAY_SIZE(nfsd_programs),
> + &nn->nfsd_svcstats,
> nfsd_max_blksize, nfsd);
> if (serv == NULL)
> return -ENOMEM;
> diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
> index 437672bcaa22..c7ad2fb2a155 100644
> --- a/include/linux/sunrpc/svc.h
> +++ b/include/linux/sunrpc/svc.h
> @@ -67,9 +67,10 @@ enum {
> * We currently do not support more than one RPC program per daemon.
> */
> struct svc_serv {
> - struct svc_program * sv_program; /* RPC program */
> + struct svc_program * sv_programs; /* RPC programs */
> struct svc_stat * sv_stats; /* RPC statistics */
> spinlock_t sv_lock;
> + unsigned int sv_nprogs; /* Number of sv_programs */
> unsigned int sv_nrthreads; /* # of server threads */
> unsigned int sv_maxconn; /* max connections allowed or
> * '0' causing max to be based
> @@ -357,10 +358,9 @@ struct svc_process_info {
> };
>
> /*
> - * List of RPC programs on the same transport endpoint
> + * RPC program - an array of these can use the same transport endpoint
> */
> struct svc_program {
> - struct svc_program * pg_next; /* other programs (same xprt) */
> u32 pg_prog; /* program number */
> unsigned int pg_lovers; /* lowest version */
> unsigned int pg_hivers; /* highest version */
> @@ -438,6 +438,7 @@ bool svc_rqst_replace_page(struct svc_rqst *rqstp,
> void svc_rqst_release_pages(struct svc_rqst *rqstp);
> void svc_exit_thread(struct svc_rqst *);
> struct svc_serv * svc_create_pooled(struct svc_program *prog,
> + unsigned int nprog,
> struct svc_stat *stats,
> unsigned int bufsize,
> int (*threadfn)(void *data));
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index ff6f3e35b36d..b33386d249c2 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -440,10 +440,11 @@ EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
>
> static int svc_uses_rpcbind(struct svc_serv *serv)
> {
> - struct svc_program *progp;
> - unsigned int i;
> + unsigned int p, i;
> +
> + for (p = 0; p < serv->sv_nprogs; p++) {
> + struct svc_program *progp = &serv->sv_programs[p];
>
> - for (progp = serv->sv_program; progp; progp = progp->pg_next) {
> for (i = 0; i < progp->pg_nvers; i++) {
> if (progp->pg_vers[i] == NULL)
> continue;
> @@ -480,7 +481,7 @@ __svc_init_bc(struct svc_serv *serv)
> * Create an RPC service
> */
> static struct svc_serv *
> -__svc_create(struct svc_program *prog, struct svc_stat *stats,
> +__svc_create(struct svc_program *prog, int nprogs, struct svc_stat *stats,
> unsigned int bufsize, int npools, int (*threadfn)(void *data))
> {
> struct svc_serv *serv;
> @@ -491,7 +492,8 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
> if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
> return NULL;
> serv->sv_name = prog->pg_name;
> - serv->sv_program = prog;
> + serv->sv_programs = prog;
> + serv->sv_nprogs = nprogs;
> serv->sv_stats = stats;
> if (bufsize > RPCSVC_MAXPAYLOAD)
> bufsize = RPCSVC_MAXPAYLOAD;
> @@ -499,17 +501,18 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
> serv->sv_max_mesg = roundup(serv->sv_max_payload + PAGE_SIZE, PAGE_SIZE);
> serv->sv_threadfn = threadfn;
> xdrsize = 0;
> - while (prog) {
> - prog->pg_lovers = prog->pg_nvers-1;
> - for (vers=0; vers<prog->pg_nvers ; vers++)
> - if (prog->pg_vers[vers]) {
> - prog->pg_hivers = vers;
> - if (prog->pg_lovers > vers)
> - prog->pg_lovers = vers;
> - if (prog->pg_vers[vers]->vs_xdrsize > xdrsize)
> - xdrsize = prog->pg_vers[vers]->vs_xdrsize;
> + for (i = 0; i < nprogs; i++) {
> + struct svc_program *progp = &prog[i];
> +
> + progp->pg_lovers = progp->pg_nvers-1;
> + for (vers = 0; vers < progp->pg_nvers ; vers++)
> + if (progp->pg_vers[vers]) {
> + progp->pg_hivers = vers;
> + if (progp->pg_lovers > vers)
> + progp->pg_lovers = vers;
> + if (progp->pg_vers[vers]->vs_xdrsize > xdrsize)
> + xdrsize = progp->pg_vers[vers]->vs_xdrsize;
> }
> - prog = prog->pg_next;
> }
> serv->sv_xdrsize = xdrsize;
> INIT_LIST_HEAD(&serv->sv_tempsocks);
> @@ -558,13 +561,14 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
> struct svc_serv *svc_create(struct svc_program *prog, unsigned int bufsize,
> int (*threadfn)(void *data))
> {
> - return __svc_create(prog, NULL, bufsize, 1, threadfn);
> + return __svc_create(prog, 1, NULL, bufsize, 1, threadfn);
> }
> EXPORT_SYMBOL_GPL(svc_create);
>
> /**
> * svc_create_pooled - Create an RPC service with pooled threads
> - * @prog: the RPC program the new service will handle
> + * @prog: Array of RPC programs the new service will handle
> + * @nprogs: Number of programs in the array
> * @stats: the stats struct if desired
> * @bufsize: maximum message size for @prog
> * @threadfn: a function to service RPC requests for @prog
> @@ -572,6 +576,7 @@ EXPORT_SYMBOL_GPL(svc_create);
> * Returns an instantiated struct svc_serv object or NULL.
> */
> struct svc_serv *svc_create_pooled(struct svc_program *prog,
> + unsigned int nprogs,
> struct svc_stat *stats,
> unsigned int bufsize,
> int (*threadfn)(void *data))
> @@ -579,7 +584,7 @@ struct svc_serv *svc_create_pooled(struct svc_program *prog,
> struct svc_serv *serv;
> unsigned int npools = svc_pool_map_get();
>
> - serv = __svc_create(prog, stats, bufsize, npools, threadfn);
> + serv = __svc_create(prog, nprogs, stats, bufsize, npools, threadfn);
> if (!serv)
> goto out_err;
> serv->sv_is_pooled = true;
> @@ -602,16 +607,16 @@ svc_destroy(struct svc_serv **servp)
>
> *servp = NULL;
>
> - dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name);
> + dprintk("svc: svc_destroy(%s)\n", serv->sv_programs->pg_name);
> timer_shutdown_sync(&serv->sv_temptimer);
>
> /*
> * Remaining transports at this point are not expected.
> */
> WARN_ONCE(!list_empty(&serv->sv_permsocks),
> - "SVC: permsocks remain for %s\n", serv->sv_program->pg_name);
> + "SVC: permsocks remain for %s\n", serv->sv_programs->pg_name);
> WARN_ONCE(!list_empty(&serv->sv_tempsocks),
> - "SVC: tempsocks remain for %s\n", serv->sv_program->pg_name);
> + "SVC: tempsocks remain for %s\n", serv->sv_programs->pg_name);
>
> cache_clean_deferred(serv);
>
> @@ -1149,15 +1154,16 @@ int svc_register(const struct svc_serv *serv, struct net *net,
> const int family, const unsigned short proto,
> const unsigned short port)
> {
> - struct svc_program *progp;
> - unsigned int i;
> + unsigned int p, i;
> int error = 0;
>
> WARN_ON_ONCE(proto == 0 && port == 0);
> if (proto == 0 && port == 0)
> return -EINVAL;
>
> - for (progp = serv->sv_program; progp; progp = progp->pg_next) {
> + for (p = 0; p < serv->sv_nprogs; p++) {
> + struct svc_program *progp = &serv->sv_programs[p];
> +
> for (i = 0; i < progp->pg_nvers; i++) {
>
> error = progp->pg_rpcbind_set(net, progp, i,
> @@ -1209,13 +1215,14 @@ static void __svc_unregister(struct net *net, const u32 program, const u32 versi
> static void svc_unregister(const struct svc_serv *serv, struct net *net)
> {
> struct sighand_struct *sighand;
> - struct svc_program *progp;
> unsigned long flags;
> - unsigned int i;
> + unsigned int p, i;
>
> clear_thread_flag(TIF_SIGPENDING);
>
> - for (progp = serv->sv_program; progp; progp = progp->pg_next) {
> + for (p = 0; p < serv->sv_nprogs; p++) {
> + struct svc_program *progp = &serv->sv_programs[p];
> +
> for (i = 0; i < progp->pg_nvers; i++) {
> if (progp->pg_vers[i] == NULL)
> continue;
> @@ -1321,7 +1328,7 @@ svc_process_common(struct svc_rqst *rqstp)
> struct svc_process_info process;
> enum svc_auth_status auth_res;
> unsigned int aoffset;
> - int rc;
> + int pr, rc;
> __be32 *p;
>
> /* Will be turned off only when NFSv4 Sessions are used */
> @@ -1345,9 +1352,12 @@ svc_process_common(struct svc_rqst *rqstp)
> rqstp->rq_vers = be32_to_cpup(p++);
> rqstp->rq_proc = be32_to_cpup(p);
>
> - for (progp = serv->sv_program; progp; progp = progp->pg_next)
> + for (pr = 0; pr < serv->sv_nprogs; pr++) {
> + progp = &serv->sv_programs[pr];
> +
> if (rqstp->rq_prog == progp->pg_prog)
> break;
> + }
>
> /*
> * Decode auth data, and add verifier to reply buffer.
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index 53ebc719ff5a..43c57124de52 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -268,7 +268,7 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
> spin_unlock(&svc_xprt_class_lock);
> newxprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
> if (IS_ERR(newxprt)) {
> - trace_svc_xprt_create_err(serv->sv_program->pg_name,
> + trace_svc_xprt_create_err(serv->sv_programs->pg_name,
> xcl->xcl_name, sap, len,
> newxprt);
> module_put(xcl->xcl_owner);
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index 04b45588ae6f..8ca98b146ec8 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -697,7 +697,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
> rqstp->rq_auth_stat = rpc_autherr_badcred;
> ipm = ip_map_cached_get(xprt);
> if (ipm == NULL)
> - ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
> + ipm = __ip_map_lookup(sn->ip_map_cache,
> + rqstp->rq_server->sv_programs->pg_class,
> &sin6->sin6_addr);
>
> if (ipm == NULL)
Reviewed-by: Jeff Layton <jlayton@kernel.org>
next prev parent reply other threads:[~2024-08-29 16:02 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-29 1:03 [PATCH v14 00/25] nfs/nfsd: add support for LOCALIO Mike Snitzer
2024-08-29 1:03 ` [PATCH v14 01/25] nfs_common: factor out nfs_errtbl and nfs_stat_to_errno Mike Snitzer
2024-08-29 14:17 ` Jeff Layton
2024-08-29 1:03 ` [PATCH v14 02/25] nfs_common: factor out nfs4_errtbl and nfs4_stat_to_errno Mike Snitzer
2024-08-29 14:17 ` Jeff Layton
2024-08-29 1:03 ` [PATCH v14 03/25] nfs: factor out {encode,decode}_opaque_fixed to nfs_xdr.h Mike Snitzer
2024-08-29 14:19 ` Jeff Layton
2024-08-29 1:03 ` [PATCH v14 04/25] NFSD: Handle @rqstp == NULL in check_nfsd_access() Mike Snitzer
2024-08-29 14:20 ` Jeff Layton
2024-08-29 1:04 ` [PATCH v14 05/25] NFSD: Refactor nfsd_setuser_and_check_port() Mike Snitzer
2024-08-29 14:23 ` Jeff Layton
2024-08-29 1:04 ` [PATCH v14 06/25] NFSD: Avoid using rqstp->rq_vers in nfsd_set_fh_dentry() Mike Snitzer
2024-08-29 1:45 ` [PATCH v14.5 " Mike Snitzer
2024-08-29 16:52 ` Jeff Layton
2024-08-29 14:28 ` [PATCH v14 " Jeff Layton
2024-08-29 15:28 ` Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 07/25] NFSD: Short-circuit fh_verify tracepoints for LOCALIO Mike Snitzer
2024-08-29 14:33 ` Jeff Layton
2024-08-29 14:35 ` Chuck Lever
2024-08-29 1:04 ` [PATCH v14 08/25] nfsd: factor out __fh_verify to allow NULL rqstp to be passed Mike Snitzer
2024-08-29 14:39 ` Jeff Layton
2024-08-29 15:35 ` Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 09/25] nfsd: add nfsd_file_acquire_local() Mike Snitzer
2024-08-29 14:49 ` Jeff Layton
2024-08-29 15:47 ` Chuck Lever
2024-08-29 15:59 ` Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 10/25] nfsd: add nfsd_serv_try_get and nfsd_serv_put Mike Snitzer
2024-08-29 15:49 ` Chuck Lever
2024-08-29 15:57 ` Jeff Layton
2024-08-29 16:01 ` Mike Snitzer
2024-08-29 16:04 ` Chuck Lever
2024-08-29 1:04 ` [PATCH v14 11/25] SUNRPC: remove call_allocate() BUG_ONs Mike Snitzer
2024-08-29 15:58 ` Jeff Layton
2024-08-29 1:04 ` [PATCH v14 12/25] SUNRPC: add svcauth_map_clnt_to_svc_cred_local Mike Snitzer
2024-08-29 15:50 ` Chuck Lever
2024-08-29 16:01 ` Jeff Layton
2024-08-29 1:04 ` [PATCH v14 13/25] SUNRPC: replace program list with program array Mike Snitzer
2024-08-29 16:02 ` Jeff Layton [this message]
2024-08-29 1:04 ` [PATCH v14 14/25] nfs_common: add NFS LOCALIO auxiliary protocol enablement Mike Snitzer
2024-08-29 16:07 ` Jeff Layton
2024-08-29 16:22 ` Mike Snitzer
2024-08-29 23:39 ` NeilBrown
2024-08-30 1:45 ` Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 15/25] nfs_common: introduce nfs_localio_ctx struct and interfaces Mike Snitzer
2024-08-29 16:40 ` Jeff Layton
2024-08-29 16:52 ` Mike Snitzer
2024-08-29 17:48 ` Jeff Layton
2024-08-30 4:36 ` NeilBrown
2024-08-30 5:01 ` Mike Snitzer
2024-08-30 5:08 ` Mike Snitzer
2024-08-30 5:12 ` Mike Snitzer
2024-08-30 5:34 ` NeilBrown
2024-08-30 6:02 ` Mike Snitzer
2024-08-30 5:46 ` NeilBrown
2024-08-30 5:56 ` Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 16/25] nfsd: add localio support Mike Snitzer
2024-08-29 16:01 ` Chuck Lever
2024-08-29 16:15 ` Mike Snitzer
2024-08-29 23:10 ` NeilBrown
2024-08-29 16:49 ` Jeff Layton
2024-08-29 16:59 ` Mike Snitzer
2024-08-29 17:18 ` Chuck Lever
2024-08-29 1:04 ` [PATCH v14 17/25] nfsd: implement server support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-08-29 16:50 ` Jeff Layton
2024-08-29 1:04 ` [PATCH v14 18/25] nfs: pass struct nfs_localio_ctx to nfs_init_pgio and nfs_init_commit Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 19/25] nfs: add localio support Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 20/25] nfs: enable localio for non-pNFS IO Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 21/25] pnfs/flexfiles: enable localio support Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 22/25] nfs/localio: use dedicated workqueues for filesystem read and write Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 23/25] nfs: implement client support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 24/25] nfs: add Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-08-29 1:04 ` [PATCH v14 25/25] nfs: add FAQ section to Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-08-29 1:47 ` [PATCH v14.5 " Mike Snitzer
2024-08-29 1:42 ` [PATCH v14 00/25] nfs/nfsd: add support for LOCALIO Mike Snitzer
2024-08-29 1:50 ` Mike Snitzer
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=df287db6d3c6936503c46e124b1011439dc9c9f2.camel@kernel.org \
--to=jlayton@kernel.org \
--cc=anna@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
--cc=snitzer@kernel.org \
--cc=trondmy@hammerspace.com \
/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;
as well as URLs for NNTP newsgroup(s).