~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfsd/localio.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * NFS server support for local clients to bypass network stack
  4  *
  5  * Copyright (C) 2014 Weston Andros Adamson <dros@primarydata.com>
  6  * Copyright (C) 2019 Trond Myklebust <trond.myklebust@hammerspace.com>
  7  * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com>
  8  * Copyright (C) 2024 NeilBrown <neilb@suse.de>
  9  */
 10 
 11 #include <linux/exportfs.h>
 12 #include <linux/sunrpc/svcauth.h>
 13 #include <linux/sunrpc/clnt.h>
 14 #include <linux/nfs.h>
 15 #include <linux/nfs_common.h>
 16 #include <linux/nfslocalio.h>
 17 #include <linux/nfs_fs.h>
 18 #include <linux/nfs_xdr.h>
 19 #include <linux/string.h>
 20 
 21 #include "nfsd.h"
 22 #include "vfs.h"
 23 #include "netns.h"
 24 #include "filecache.h"
 25 #include "cache.h"
 26 
 27 static const struct nfsd_localio_operations nfsd_localio_ops = {
 28         .nfsd_serv_try_get  = nfsd_serv_try_get,
 29         .nfsd_serv_put  = nfsd_serv_put,
 30         .nfsd_open_local_fh = nfsd_open_local_fh,
 31         .nfsd_file_put_local = nfsd_file_put_local,
 32         .nfsd_file_file = nfsd_file_file,
 33 };
 34 
 35 void nfsd_localio_ops_init(void)
 36 {
 37         nfs_to = &nfsd_localio_ops;
 38 }
 39 
 40 /**
 41  * nfsd_open_local_fh - lookup a local filehandle @nfs_fh and map to nfsd_file
 42  *
 43  * @net: 'struct net' to get the proper nfsd_net required for LOCALIO access
 44  * @dom: 'struct auth_domain' required for LOCALIO access
 45  * @rpc_clnt: rpc_clnt that the client established
 46  * @cred: cred that the client established
 47  * @nfs_fh: filehandle to lookup
 48  * @fmode: fmode_t to use for open
 49  *
 50  * This function maps a local fh to a path on a local filesystem.
 51  * This is useful when the nfs client has the local server mounted - it can
 52  * avoid all the NFS overhead with reads, writes and commits.
 53  *
 54  * On successful return, returned nfsd_file will have its nf_net member
 55  * set. Caller (NFS client) is responsible for calling nfsd_serv_put and
 56  * nfsd_file_put (via nfs_to_nfsd_file_put_local).
 57  */
 58 struct nfsd_file *
 59 nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
 60                    struct rpc_clnt *rpc_clnt, const struct cred *cred,
 61                    const struct nfs_fh *nfs_fh, const fmode_t fmode)
 62 {
 63         int mayflags = NFSD_MAY_LOCALIO;
 64         struct svc_cred rq_cred;
 65         struct svc_fh fh;
 66         struct nfsd_file *localio;
 67         __be32 beres;
 68 
 69         if (nfs_fh->size > NFS4_FHSIZE)
 70                 return ERR_PTR(-EINVAL);
 71 
 72         /* nfs_fh -> svc_fh */
 73         fh_init(&fh, NFS4_FHSIZE);
 74         fh.fh_handle.fh_size = nfs_fh->size;
 75         memcpy(fh.fh_handle.fh_raw, nfs_fh->data, nfs_fh->size);
 76 
 77         if (fmode & FMODE_READ)
 78                 mayflags |= NFSD_MAY_READ;
 79         if (fmode & FMODE_WRITE)
 80                 mayflags |= NFSD_MAY_WRITE;
 81 
 82         svcauth_map_clnt_to_svc_cred_local(rpc_clnt, cred, &rq_cred);
 83 
 84         beres = nfsd_file_acquire_local(net, &rq_cred, dom,
 85                                         &fh, mayflags, &localio);
 86         if (beres)
 87                 localio = ERR_PTR(nfs_stat_to_errno(be32_to_cpu(beres)));
 88 
 89         fh_put(&fh);
 90         if (rq_cred.cr_group_info)
 91                 put_group_info(rq_cred.cr_group_info);
 92 
 93         return localio;
 94 }
 95 EXPORT_SYMBOL_GPL(nfsd_open_local_fh);
 96 
 97 /*
 98  * UUID_IS_LOCAL XDR functions
 99  */
100 
101 static __be32 localio_proc_null(struct svc_rqst *rqstp)
102 {
103         return rpc_success;
104 }
105 
106 struct localio_uuidarg {
107         uuid_t                  uuid;
108 };
109 
110 static __be32 localio_proc_uuid_is_local(struct svc_rqst *rqstp)
111 {
112         struct localio_uuidarg *argp = rqstp->rq_argp;
113         struct net *net = SVC_NET(rqstp);
114         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
115 
116         nfs_uuid_is_local(&argp->uuid, &nn->local_clients,
117                           net, rqstp->rq_client, THIS_MODULE);
118 
119         return rpc_success;
120 }
121 
122 static bool localio_decode_uuidarg(struct svc_rqst *rqstp,
123                                    struct xdr_stream *xdr)
124 {
125         struct localio_uuidarg *argp = rqstp->rq_argp;
126         u8 uuid[UUID_SIZE];
127 
128         if (decode_opaque_fixed(xdr, uuid, UUID_SIZE))
129                 return false;
130         import_uuid(&argp->uuid, uuid);
131 
132         return true;
133 }
134 
135 static const struct svc_procedure localio_procedures1[] = {
136         [LOCALIOPROC_NULL] = {
137                 .pc_func = localio_proc_null,
138                 .pc_decode = nfssvc_decode_voidarg,
139                 .pc_encode = nfssvc_encode_voidres,
140                 .pc_argsize = sizeof(struct nfsd_voidargs),
141                 .pc_ressize = sizeof(struct nfsd_voidres),
142                 .pc_cachetype = RC_NOCACHE,
143                 .pc_xdrressize = 0,
144                 .pc_name = "NULL",
145         },
146         [LOCALIOPROC_UUID_IS_LOCAL] = {
147                 .pc_func = localio_proc_uuid_is_local,
148                 .pc_decode = localio_decode_uuidarg,
149                 .pc_encode = nfssvc_encode_voidres,
150                 .pc_argsize = sizeof(struct localio_uuidarg),
151                 .pc_argzero = sizeof(struct localio_uuidarg),
152                 .pc_ressize = sizeof(struct nfsd_voidres),
153                 .pc_cachetype = RC_NOCACHE,
154                 .pc_name = "UUID_IS_LOCAL",
155         },
156 };
157 
158 #define LOCALIO_NR_PROCEDURES ARRAY_SIZE(localio_procedures1)
159 static DEFINE_PER_CPU_ALIGNED(unsigned long,
160                               localio_count[LOCALIO_NR_PROCEDURES]);
161 const struct svc_version localio_version1 = {
162         .vs_vers        = 1,
163         .vs_nproc       = LOCALIO_NR_PROCEDURES,
164         .vs_proc        = localio_procedures1,
165         .vs_dispatch    = nfsd_dispatch,
166         .vs_count       = localio_count,
167         .vs_xdrsize     = XDR_QUADLEN(UUID_SIZE),
168         .vs_hidden      = true,
169 };
170 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php