// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2024 Mike Snitzer <[email protected]> * Copyright (C) 2024 NeilBrown <[email protected]> */ #include <linux/module.h> #include <linux/rculist.h> #include <linux/nfslocalio.h> #include <net/netns/generic.h> MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …; static DEFINE_SPINLOCK(nfs_uuid_lock); /* * Global list of nfs_uuid_t instances * that is protected by nfs_uuid_lock. */ static LIST_HEAD(nfs_uuids); void nfs_uuid_begin(nfs_uuid_t *nfs_uuid) { … } EXPORT_SYMBOL_GPL(…); void nfs_uuid_end(nfs_uuid_t *nfs_uuid) { … } EXPORT_SYMBOL_GPL(…); static nfs_uuid_t * nfs_uuid_lookup_locked(const uuid_t *uuid) { … } static struct module *nfsd_mod; void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list, struct net *net, struct auth_domain *dom, struct module *mod) { … } EXPORT_SYMBOL_GPL(…); static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid) { … } void nfs_uuid_invalidate_clients(struct list_head *list) { … } EXPORT_SYMBOL_GPL(…); void nfs_uuid_invalidate_one_client(nfs_uuid_t *nfs_uuid) { … } EXPORT_SYMBOL_GPL(…); struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, struct rpc_clnt *rpc_clnt, const struct cred *cred, const struct nfs_fh *nfs_fh, const fmode_t fmode) { … } EXPORT_SYMBOL_GPL(…); /* * The NFS LOCALIO code needs to call into NFSD using various symbols, * but cannot be statically linked, because that will make the NFS * module always depend on the NFSD module. * * 'nfs_to' provides NFS access to NFSD functions needed for LOCALIO, * its lifetime is tightly coupled to the NFSD module and will always * be available to NFS LOCALIO because any successful client<->server * LOCALIO handshake results in a reference on the NFSD module (above), * so NFS implicitly holds a reference to the NFSD module and its * functions in the 'nfs_to' nfsd_localio_operations cannot disappear. * * If the last NFS client using LOCALIO disconnects (and its reference * on NFSD dropped) then NFSD could be unloaded, resulting in 'nfs_to' * functions being invalid pointers. But if NFSD isn't loaded then NFS * will not be able to handshake with NFSD and will have no cause to * try to call 'nfs_to' function pointers. If/when NFSD is reloaded it * will reinitialize the 'nfs_to' function pointers and make LOCALIO * possible. */ const struct nfsd_localio_operations *nfs_to; EXPORT_SYMBOL_GPL(…);