1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com>
4 * Copyright (C) 2024 NeilBrown <neilb@suse.de>
6 #ifndef __LINUX_NFSLOCALIO_H
7 #define __LINUX_NFSLOCALIO_H
9 /* nfsd_file structure is purposely kept opaque to NFS client */
12 #if IS_ENABLED(CONFIG_NFS_LOCALIO)
14 #include <linux/module.h>
15 #include <linux/list.h>
16 #include <linux/uuid.h>
17 #include <linux/sunrpc/clnt.h>
18 #include <linux/sunrpc/svcauth.h>
19 #include <linux/nfs.h>
20 #include <net/net_namespace.h>
23 * Useful to allow a client to negotiate if localio
24 * possible with its server.
26 * See Documentation/filesystems/nfs/localio.rst for more detail.
30 struct list_head list
;
31 struct net __rcu
*net
; /* nfsd's network namespace */
32 struct auth_domain
*dom
; /* auth_domain for localio */
35 void nfs_uuid_init(nfs_uuid_t
*);
36 bool nfs_uuid_begin(nfs_uuid_t
*);
37 void nfs_uuid_end(nfs_uuid_t
*);
38 void nfs_uuid_is_local(const uuid_t
*, struct list_head
*,
39 struct net
*, struct auth_domain
*, struct module
*);
40 void nfs_uuid_invalidate_clients(struct list_head
*list
);
41 void nfs_uuid_invalidate_one_client(nfs_uuid_t
*nfs_uuid
);
43 /* localio needs to map filehandle -> struct nfsd_file */
44 extern struct nfsd_file
*
45 nfsd_open_local_fh(struct net
*, struct auth_domain
*, struct rpc_clnt
*,
46 const struct cred
*, const struct nfs_fh
*,
47 const fmode_t
) __must_hold(rcu
);
49 struct nfsd_localio_operations
{
50 bool (*nfsd_serv_try_get
)(struct net
*);
51 void (*nfsd_serv_put
)(struct net
*);
52 struct nfsd_file
*(*nfsd_open_local_fh
)(struct net
*,
56 const struct nfs_fh
*,
58 struct net
*(*nfsd_file_put_local
)(struct nfsd_file
*);
59 struct file
*(*nfsd_file_file
)(struct nfsd_file
*);
60 } ____cacheline_aligned
;
62 extern void nfsd_localio_ops_init(void);
63 extern const struct nfsd_localio_operations
*nfs_to
;
65 struct nfsd_file
*nfs_open_local_fh(nfs_uuid_t
*,
66 struct rpc_clnt
*, const struct cred
*,
67 const struct nfs_fh
*, const fmode_t
);
69 static inline void nfs_to_nfsd_net_put(struct net
*net
)
72 * Once reference to nfsd_serv is dropped, NFSD could be
73 * unloaded, so ensure safe return from nfsd_file_put_local()
74 * by always taking RCU.
77 nfs_to
->nfsd_serv_put(net
);
81 static inline void nfs_to_nfsd_file_put_local(struct nfsd_file
*localio
)
84 * Must not hold RCU otherwise nfsd_file_put() can easily trigger:
85 * "Voluntary context switch within RCU read-side critical section!"
86 * by scheduling deep in underlying filesystem (e.g. XFS).
88 struct net
*net
= nfs_to
->nfsd_file_put_local(localio
);
90 nfs_to_nfsd_net_put(net
);
93 #else /* CONFIG_NFS_LOCALIO */
94 static inline void nfsd_localio_ops_init(void)
97 static inline void nfs_to_nfsd_file_put_local(struct nfsd_file
*localio
)
100 #endif /* CONFIG_NFS_LOCALIO */
102 #endif /* __LINUX_NFSLOCALIO_H */