162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * per net namespace data structures for nfsd
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2012, Jeff Layton <jlayton@redhat.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef __NFSD_NETNS_H__
962306a36Sopenharmony_ci#define __NFSD_NETNS_H__
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <net/net_namespace.h>
1262306a36Sopenharmony_ci#include <net/netns/generic.h>
1362306a36Sopenharmony_ci#include <linux/filelock.h>
1462306a36Sopenharmony_ci#include <linux/percpu_counter.h>
1562306a36Sopenharmony_ci#include <linux/siphash.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* Hash tables for nfs4_clientid state */
1862306a36Sopenharmony_ci#define CLIENT_HASH_BITS                 4
1962306a36Sopenharmony_ci#define CLIENT_HASH_SIZE                (1 << CLIENT_HASH_BITS)
2062306a36Sopenharmony_ci#define CLIENT_HASH_MASK                (CLIENT_HASH_SIZE - 1)
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define SESSION_HASH_SIZE	512
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct cld_net;
2562306a36Sopenharmony_cistruct nfsd4_client_tracking_ops;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cienum {
2862306a36Sopenharmony_ci	/* cache misses due only to checksum comparison failures */
2962306a36Sopenharmony_ci	NFSD_NET_PAYLOAD_MISSES,
3062306a36Sopenharmony_ci	/* amount of memory (in bytes) currently consumed by the DRC */
3162306a36Sopenharmony_ci	NFSD_NET_DRC_MEM_USAGE,
3262306a36Sopenharmony_ci	NFSD_NET_COUNTERS_NUM
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/*
3662306a36Sopenharmony_ci * Represents a nfsd "container". With respect to nfsv4 state tracking, the
3762306a36Sopenharmony_ci * fields of interest are the *_id_hashtbls and the *_name_tree. These track
3862306a36Sopenharmony_ci * the nfs4_client objects by either short or long form clientid.
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci * Each nfsd_net runs a nfs4_laundromat workqueue job when necessary to clean
4162306a36Sopenharmony_ci * up expired clients and delegations within the container.
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_cistruct nfsd_net {
4462306a36Sopenharmony_ci	struct cld_net *cld_net;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	struct cache_detail *svc_expkey_cache;
4762306a36Sopenharmony_ci	struct cache_detail *svc_export_cache;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	struct cache_detail *idtoname_cache;
5062306a36Sopenharmony_ci	struct cache_detail *nametoid_cache;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	struct lock_manager nfsd4_manager;
5362306a36Sopenharmony_ci	bool grace_ended;
5462306a36Sopenharmony_ci	time64_t boot_time;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	struct dentry *nfsd_client_dir;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	/*
5962306a36Sopenharmony_ci	 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
6062306a36Sopenharmony_ci	 * used in reboot/reset lease grace period processing
6162306a36Sopenharmony_ci	 *
6262306a36Sopenharmony_ci	 * conf_id_hashtbl[], and conf_name_tree hold confirmed
6362306a36Sopenharmony_ci	 * setclientid_confirmed info.
6462306a36Sopenharmony_ci	 *
6562306a36Sopenharmony_ci	 * unconf_str_hastbl[] and unconf_name_tree hold unconfirmed
6662306a36Sopenharmony_ci	 * setclientid info.
6762306a36Sopenharmony_ci	 */
6862306a36Sopenharmony_ci	struct list_head *reclaim_str_hashtbl;
6962306a36Sopenharmony_ci	int reclaim_str_hashtbl_size;
7062306a36Sopenharmony_ci	struct list_head *conf_id_hashtbl;
7162306a36Sopenharmony_ci	struct rb_root conf_name_tree;
7262306a36Sopenharmony_ci	struct list_head *unconf_id_hashtbl;
7362306a36Sopenharmony_ci	struct rb_root unconf_name_tree;
7462306a36Sopenharmony_ci	struct list_head *sessionid_hashtbl;
7562306a36Sopenharmony_ci	/*
7662306a36Sopenharmony_ci	 * client_lru holds client queue ordered by nfs4_client.cl_time
7762306a36Sopenharmony_ci	 * for lease renewal.
7862306a36Sopenharmony_ci	 *
7962306a36Sopenharmony_ci	 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
8062306a36Sopenharmony_ci	 * for last close replay.
8162306a36Sopenharmony_ci	 *
8262306a36Sopenharmony_ci	 * All of the above fields are protected by the client_mutex.
8362306a36Sopenharmony_ci	 */
8462306a36Sopenharmony_ci	struct list_head client_lru;
8562306a36Sopenharmony_ci	struct list_head close_lru;
8662306a36Sopenharmony_ci	struct list_head del_recall_lru;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/* protected by blocked_locks_lock */
8962306a36Sopenharmony_ci	struct list_head blocked_locks_lru;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	struct delayed_work laundromat_work;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* client_lock protects the client lru list and session hash table */
9462306a36Sopenharmony_ci	spinlock_t client_lock;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	/* protects blocked_locks_lru */
9762306a36Sopenharmony_ci	spinlock_t blocked_locks_lock;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	struct file *rec_file;
10062306a36Sopenharmony_ci	bool in_grace;
10162306a36Sopenharmony_ci	const struct nfsd4_client_tracking_ops *client_tracking_ops;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	time64_t nfsd4_lease;
10462306a36Sopenharmony_ci	time64_t nfsd4_grace;
10562306a36Sopenharmony_ci	bool somebody_reclaimed;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	bool track_reclaim_completes;
10862306a36Sopenharmony_ci	atomic_t nr_reclaim_complete;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	bool nfsd_net_up;
11162306a36Sopenharmony_ci	bool lockd_up;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	seqlock_t writeverf_lock;
11462306a36Sopenharmony_ci	unsigned char writeverf[8];
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	/*
11762306a36Sopenharmony_ci	 * Max number of connections this nfsd container will allow. Defaults
11862306a36Sopenharmony_ci	 * to '0' which is means that it bases this on the number of threads.
11962306a36Sopenharmony_ci	 */
12062306a36Sopenharmony_ci	unsigned int max_connections;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	u32 clientid_base;
12362306a36Sopenharmony_ci	u32 clientid_counter;
12462306a36Sopenharmony_ci	u32 clverifier_counter;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	struct svc_serv *nfsd_serv;
12762306a36Sopenharmony_ci	/* When a listening socket is added to nfsd, keep_active is set
12862306a36Sopenharmony_ci	 * and this justifies a reference on nfsd_serv.  This stops
12962306a36Sopenharmony_ci	 * nfsd_serv from being freed.  When the number of threads is
13062306a36Sopenharmony_ci	 * set, keep_active is cleared and the reference is dropped.  So
13162306a36Sopenharmony_ci	 * when the last thread exits, the service will be destroyed.
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci	int keep_active;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/*
13662306a36Sopenharmony_ci	 * clientid and stateid data for construction of net unique COPY
13762306a36Sopenharmony_ci	 * stateids.
13862306a36Sopenharmony_ci	 */
13962306a36Sopenharmony_ci	u32		s2s_cp_cl_id;
14062306a36Sopenharmony_ci	struct idr	s2s_cp_stateids;
14162306a36Sopenharmony_ci	spinlock_t	s2s_cp_lock;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	/*
14462306a36Sopenharmony_ci	 * Version information
14562306a36Sopenharmony_ci	 */
14662306a36Sopenharmony_ci	bool *nfsd_versions;
14762306a36Sopenharmony_ci	bool *nfsd4_minorversions;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	/*
15062306a36Sopenharmony_ci	 * Duplicate reply cache
15162306a36Sopenharmony_ci	 */
15262306a36Sopenharmony_ci	struct nfsd_drc_bucket   *drc_hashtbl;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	/* max number of entries allowed in the cache */
15562306a36Sopenharmony_ci	unsigned int             max_drc_entries;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* number of significant bits in the hash value */
15862306a36Sopenharmony_ci	unsigned int             maskbits;
15962306a36Sopenharmony_ci	unsigned int             drc_hashsize;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	/*
16262306a36Sopenharmony_ci	 * Stats and other tracking of on the duplicate reply cache.
16362306a36Sopenharmony_ci	 * The longest_chain* fields are modified with only the per-bucket
16462306a36Sopenharmony_ci	 * cache lock, which isn't really safe and should be fixed if we want
16562306a36Sopenharmony_ci	 * these statistics to be completely accurate.
16662306a36Sopenharmony_ci	 */
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	/* total number of entries */
16962306a36Sopenharmony_ci	atomic_t                 num_drc_entries;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/* Per-netns stats counters */
17262306a36Sopenharmony_ci	struct percpu_counter    counter[NFSD_NET_COUNTERS_NUM];
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	/* longest hash chain seen */
17562306a36Sopenharmony_ci	unsigned int             longest_chain;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	/* size of cache when we saw the longest hash chain */
17862306a36Sopenharmony_ci	unsigned int             longest_chain_cachesize;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	struct shrinker		nfsd_reply_cache_shrinker;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	/* tracking server-to-server copy mounts */
18362306a36Sopenharmony_ci	spinlock_t              nfsd_ssc_lock;
18462306a36Sopenharmony_ci	struct list_head        nfsd_ssc_mount_list;
18562306a36Sopenharmony_ci	wait_queue_head_t       nfsd_ssc_waitq;
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	/* utsname taken from the process that starts the server */
18862306a36Sopenharmony_ci	char			nfsd_name[UNX_MAXNODENAME+1];
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	struct nfsd_fcache_disposal *fcache_disposal;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	siphash_key_t		siphash_key;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	atomic_t		nfs4_client_count;
19562306a36Sopenharmony_ci	int			nfs4_max_clients;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	atomic_t		nfsd_courtesy_clients;
19862306a36Sopenharmony_ci	struct shrinker		nfsd_client_shrinker;
19962306a36Sopenharmony_ci	struct work_struct	nfsd_shrinker_work;
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* Simple check to find out if a given net was properly initialized */
20362306a36Sopenharmony_ci#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciextern void nfsd_netns_free_versions(struct nfsd_net *nn);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciextern unsigned int nfsd_net_id;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_civoid nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);
21062306a36Sopenharmony_civoid nfsd_reset_write_verifier(struct nfsd_net *nn);
21162306a36Sopenharmony_ci#endif /* __NFSD_NETNS_H__ */
212