at v6.19-rc7 123 lines 3.6 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com> 4 * Copyright (C) 2024 NeilBrown <neilb@suse.de> 5 */ 6#ifndef __LINUX_NFSLOCALIO_H 7#define __LINUX_NFSLOCALIO_H 8 9#if IS_ENABLED(CONFIG_NFS_LOCALIO) 10 11#include <linux/module.h> 12#include <linux/list.h> 13#include <linux/uuid.h> 14#include <linux/sunrpc/clnt.h> 15#include <linux/sunrpc/svcauth.h> 16#include <linux/nfs.h> 17#include <net/net_namespace.h> 18 19struct nfs_client; 20struct nfs_file_localio; 21 22/* 23 * Useful to allow a client to negotiate if localio 24 * possible with its server. 25 * 26 * See Documentation/filesystems/nfs/localio.rst for more detail. 27 */ 28typedef struct { 29 uuid_t uuid; 30 unsigned nfs3_localio_probe_count; 31 /* this struct is over a cacheline, avoid bouncing */ 32 spinlock_t ____cacheline_aligned lock; 33 struct list_head list; 34 spinlock_t *list_lock; /* nn->local_clients_lock */ 35 struct net __rcu *net; /* nfsd's network namespace */ 36 struct auth_domain *dom; /* auth_domain for localio */ 37 /* Local files to close when net is shut down or exports change */ 38 struct list_head files; 39} nfs_uuid_t; 40 41void nfs_uuid_init(nfs_uuid_t *); 42bool nfs_uuid_begin(nfs_uuid_t *); 43void nfs_uuid_end(nfs_uuid_t *); 44void nfs_uuid_is_local(const uuid_t *, struct list_head *, spinlock_t *, 45 struct net *, struct auth_domain *, struct module *); 46 47void nfs_localio_enable_client(struct nfs_client *clp); 48void nfs_localio_disable_client(struct nfs_client *clp); 49void nfs_localio_invalidate_clients(struct list_head *nn_local_clients, 50 spinlock_t *nn_local_clients_lock); 51 52/* localio needs to map filehandle -> struct nfsd_file */ 53void nfs_close_local_fh(struct nfs_file_localio *); 54 55struct nfsd_localio_operations { 56 bool (*nfsd_net_try_get)(struct net *); 57 void (*nfsd_net_put)(struct net *); 58 struct nfsd_file *(*nfsd_open_local_fh)(struct net *, 59 struct auth_domain *, 60 struct rpc_clnt *, 61 const struct cred *, 62 const struct nfs_fh *, 63 struct nfsd_file __rcu **pnf, 64 const fmode_t); 65 struct net *(*nfsd_file_put_local)(struct nfsd_file __rcu **); 66 struct file *(*nfsd_file_file)(struct nfsd_file *); 67 void (*nfsd_file_dio_alignment)(struct nfsd_file *, 68 u32 *, u32 *, u32 *); 69} ____cacheline_aligned; 70 71extern void nfsd_localio_ops_init(void); 72extern const struct nfsd_localio_operations *nfs_to; 73 74struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *, 75 struct rpc_clnt *, const struct cred *, 76 const struct nfs_fh *, struct nfs_file_localio *, 77 struct nfsd_file __rcu **pnf, 78 const fmode_t); 79 80static inline void nfs_to_nfsd_net_put(struct net *net) 81{ 82 /* 83 * Once reference to net (and associated nfsd_serv) is dropped, NFSD 84 * could be unloaded, so ensure safe return from nfsd_net_put() by 85 * always taking RCU. 86 */ 87 rcu_read_lock(); 88 nfs_to->nfsd_net_put(net); 89 rcu_read_unlock(); 90} 91 92static inline void nfs_to_nfsd_file_put_local(struct nfsd_file __rcu **localio) 93{ 94 /* 95 * Either *localio must be guaranteed to be non-NULL, or caller 96 * must prevent nfsd shutdown from completing as nfs_close_local_fh() 97 * does by blocking the nfs_uuid from being finally put. 98 */ 99 struct net *net; 100 101 net = nfs_to->nfsd_file_put_local(localio); 102 103 if (net) 104 nfs_to_nfsd_net_put(net); 105} 106 107#else /* CONFIG_NFS_LOCALIO */ 108 109struct nfs_file_localio; 110static inline void nfs_close_local_fh(struct nfs_file_localio *nfl) 111{ 112} 113static inline void nfsd_localio_ops_init(void) 114{ 115} 116struct nfs_client; 117static inline void nfs_localio_disable_client(struct nfs_client *clp) 118{ 119} 120 121#endif /* CONFIG_NFS_LOCALIO */ 122 123#endif /* __LINUX_NFSLOCALIO_H */