162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci *  Copyright (c) 2001 The Regents of the University of Michigan.
362306a36Sopenharmony_ci *  All rights reserved.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Kendrick Smith <kmsmith@umich.edu>
662306a36Sopenharmony_ci *  Andy Adamson <andros@umich.edu>
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *  Redistribution and use in source and binary forms, with or without
962306a36Sopenharmony_ci *  modification, are permitted provided that the following conditions
1062306a36Sopenharmony_ci *  are met:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *  1. Redistributions of source code must retain the above copyright
1362306a36Sopenharmony_ci *     notice, this list of conditions and the following disclaimer.
1462306a36Sopenharmony_ci *  2. Redistributions in binary form must reproduce the above copyright
1562306a36Sopenharmony_ci *     notice, this list of conditions and the following disclaimer in the
1662306a36Sopenharmony_ci *     documentation and/or other materials provided with the distribution.
1762306a36Sopenharmony_ci *  3. Neither the name of the University nor the names of its
1862306a36Sopenharmony_ci *     contributors may be used to endorse or promote products derived
1962306a36Sopenharmony_ci *     from this software without specific prior written permission.
2062306a36Sopenharmony_ci *
2162306a36Sopenharmony_ci *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2262306a36Sopenharmony_ci *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2362306a36Sopenharmony_ci *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2462306a36Sopenharmony_ci *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2562306a36Sopenharmony_ci *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2662306a36Sopenharmony_ci *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2762306a36Sopenharmony_ci *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2862306a36Sopenharmony_ci *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2962306a36Sopenharmony_ci *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3062306a36Sopenharmony_ci *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3162306a36Sopenharmony_ci *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#ifndef _NFSD4_STATE_H
3662306a36Sopenharmony_ci#define _NFSD4_STATE_H
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#include <linux/idr.h>
3962306a36Sopenharmony_ci#include <linux/refcount.h>
4062306a36Sopenharmony_ci#include <linux/sunrpc/svc_xprt.h>
4162306a36Sopenharmony_ci#include "nfsfh.h"
4262306a36Sopenharmony_ci#include "nfsd.h"
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_citypedef struct {
4562306a36Sopenharmony_ci	u32             cl_boot;
4662306a36Sopenharmony_ci	u32             cl_id;
4762306a36Sopenharmony_ci} clientid_t;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_citypedef struct {
5062306a36Sopenharmony_ci	clientid_t	so_clid;
5162306a36Sopenharmony_ci	u32		so_id;
5262306a36Sopenharmony_ci} stateid_opaque_t;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_citypedef struct {
5562306a36Sopenharmony_ci	u32                     si_generation;
5662306a36Sopenharmony_ci	stateid_opaque_t        si_opaque;
5762306a36Sopenharmony_ci} stateid_t;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_citypedef struct {
6062306a36Sopenharmony_ci	stateid_t		cs_stid;
6162306a36Sopenharmony_ci#define NFS4_COPY_STID 1
6262306a36Sopenharmony_ci#define NFS4_COPYNOTIFY_STID 2
6362306a36Sopenharmony_ci	unsigned char		cs_type;
6462306a36Sopenharmony_ci	refcount_t		cs_count;
6562306a36Sopenharmony_ci} copy_stateid_t;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistruct nfsd4_callback {
6862306a36Sopenharmony_ci	struct nfs4_client *cb_clp;
6962306a36Sopenharmony_ci	struct rpc_message cb_msg;
7062306a36Sopenharmony_ci	const struct nfsd4_callback_ops *cb_ops;
7162306a36Sopenharmony_ci	struct work_struct cb_work;
7262306a36Sopenharmony_ci	int cb_seq_status;
7362306a36Sopenharmony_ci	int cb_status;
7462306a36Sopenharmony_ci	bool cb_need_restart;
7562306a36Sopenharmony_ci	bool cb_holds_slot;
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistruct nfsd4_callback_ops {
7962306a36Sopenharmony_ci	void (*prepare)(struct nfsd4_callback *);
8062306a36Sopenharmony_ci	int (*done)(struct nfsd4_callback *, struct rpc_task *);
8162306a36Sopenharmony_ci	void (*release)(struct nfsd4_callback *);
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/*
8562306a36Sopenharmony_ci * A core object that represents a "common" stateid. These are generally
8662306a36Sopenharmony_ci * embedded within the different (more specific) stateid objects and contain
8762306a36Sopenharmony_ci * fields that are of general use to any stateid.
8862306a36Sopenharmony_ci */
8962306a36Sopenharmony_cistruct nfs4_stid {
9062306a36Sopenharmony_ci	refcount_t		sc_count;
9162306a36Sopenharmony_ci#define NFS4_OPEN_STID 1
9262306a36Sopenharmony_ci#define NFS4_LOCK_STID 2
9362306a36Sopenharmony_ci#define NFS4_DELEG_STID 4
9462306a36Sopenharmony_ci/* For an open stateid kept around *only* to process close replays: */
9562306a36Sopenharmony_ci#define NFS4_CLOSED_STID 8
9662306a36Sopenharmony_ci/* For a deleg stateid kept around only to process free_stateid's: */
9762306a36Sopenharmony_ci#define NFS4_REVOKED_DELEG_STID 16
9862306a36Sopenharmony_ci#define NFS4_CLOSED_DELEG_STID 32
9962306a36Sopenharmony_ci#define NFS4_LAYOUT_STID 64
10062306a36Sopenharmony_ci	struct list_head	sc_cp_list;
10162306a36Sopenharmony_ci	unsigned char		sc_type;
10262306a36Sopenharmony_ci	stateid_t		sc_stateid;
10362306a36Sopenharmony_ci	spinlock_t		sc_lock;
10462306a36Sopenharmony_ci	struct nfs4_client	*sc_client;
10562306a36Sopenharmony_ci	struct nfs4_file	*sc_file;
10662306a36Sopenharmony_ci	void			(*sc_free)(struct nfs4_stid *);
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the
11062306a36Sopenharmony_ci * parent OPEN/LOCK/DELEG stateid.
11162306a36Sopenharmony_ci */
11262306a36Sopenharmony_cistruct nfs4_cpntf_state {
11362306a36Sopenharmony_ci	copy_stateid_t		cp_stateid;
11462306a36Sopenharmony_ci	struct list_head	cp_list;	/* per parent nfs4_stid */
11562306a36Sopenharmony_ci	stateid_t		cp_p_stateid;	/* copy of parent's stateid */
11662306a36Sopenharmony_ci	clientid_t		cp_p_clid;	/* copy of parent's clid */
11762306a36Sopenharmony_ci	time64_t		cpntf_time;	/* last time stateid used */
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/*
12162306a36Sopenharmony_ci * Represents a delegation stateid. The nfs4_client holds references to these
12262306a36Sopenharmony_ci * and they are put when it is being destroyed or when the delegation is
12362306a36Sopenharmony_ci * returned by the client:
12462306a36Sopenharmony_ci *
12562306a36Sopenharmony_ci * o 1 reference as long as a delegation is still in force (taken when it's
12662306a36Sopenharmony_ci *   alloc'd, put when it's returned or revoked)
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * o 1 reference as long as a recall rpc is in progress (taken when the lease
12962306a36Sopenharmony_ci *   is broken, put when the rpc exits)
13062306a36Sopenharmony_ci *
13162306a36Sopenharmony_ci * o 1 more ephemeral reference for each nfsd thread currently doing something
13262306a36Sopenharmony_ci *   with that delegation without holding the cl_lock
13362306a36Sopenharmony_ci *
13462306a36Sopenharmony_ci * If the server attempts to recall a delegation and the client doesn't do so
13562306a36Sopenharmony_ci * before a timeout, the server may also revoke the delegation. In that case,
13662306a36Sopenharmony_ci * the object will either be destroyed (v4.0) or moved to a per-client list of
13762306a36Sopenharmony_ci * revoked delegations (v4.1+).
13862306a36Sopenharmony_ci *
13962306a36Sopenharmony_ci * This object is a superset of the nfs4_stid.
14062306a36Sopenharmony_ci */
14162306a36Sopenharmony_cistruct nfs4_delegation {
14262306a36Sopenharmony_ci	struct nfs4_stid	dl_stid; /* must be first field */
14362306a36Sopenharmony_ci	struct list_head	dl_perfile;
14462306a36Sopenharmony_ci	struct list_head	dl_perclnt;
14562306a36Sopenharmony_ci	struct list_head	dl_recall_lru;  /* delegation recalled */
14662306a36Sopenharmony_ci	struct nfs4_clnt_odstate *dl_clnt_odstate;
14762306a36Sopenharmony_ci	u32			dl_type;
14862306a36Sopenharmony_ci	time64_t		dl_time;
14962306a36Sopenharmony_ci/* For recall: */
15062306a36Sopenharmony_ci	int			dl_retries;
15162306a36Sopenharmony_ci	struct nfsd4_callback	dl_recall;
15262306a36Sopenharmony_ci	bool			dl_recalled;
15362306a36Sopenharmony_ci};
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci#define cb_to_delegation(cb) \
15662306a36Sopenharmony_ci	container_of(cb, struct nfs4_delegation, dl_recall)
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/* client delegation callback info */
15962306a36Sopenharmony_cistruct nfs4_cb_conn {
16062306a36Sopenharmony_ci	/* SETCLIENTID info */
16162306a36Sopenharmony_ci	struct sockaddr_storage	cb_addr;
16262306a36Sopenharmony_ci	struct sockaddr_storage	cb_saddr;
16362306a36Sopenharmony_ci	size_t			cb_addrlen;
16462306a36Sopenharmony_ci	u32                     cb_prog; /* used only in 4.0 case;
16562306a36Sopenharmony_ci					    per-session otherwise */
16662306a36Sopenharmony_ci	u32                     cb_ident;	/* minorversion 0 only */
16762306a36Sopenharmony_ci	struct svc_xprt		*cb_xprt;	/* minorversion 1 only */
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistatic inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
17162306a36Sopenharmony_ci{
17262306a36Sopenharmony_ci	return container_of(s, struct nfs4_delegation, dl_stid);
17362306a36Sopenharmony_ci}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/* Maximum number of slots per session. 160 is useful for long haul TCP */
17662306a36Sopenharmony_ci#define NFSD_MAX_SLOTS_PER_SESSION     160
17762306a36Sopenharmony_ci/* Maximum number of operations per session compound */
17862306a36Sopenharmony_ci#define NFSD_MAX_OPS_PER_COMPOUND	50
17962306a36Sopenharmony_ci/* Maximum  session per slot cache size */
18062306a36Sopenharmony_ci#define NFSD_SLOT_CACHE_SIZE		2048
18162306a36Sopenharmony_ci/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */
18262306a36Sopenharmony_ci#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION	32
18362306a36Sopenharmony_ci#define NFSD_MAX_MEM_PER_SESSION  \
18462306a36Sopenharmony_ci		(NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE)
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistruct nfsd4_slot {
18762306a36Sopenharmony_ci	u32	sl_seqid;
18862306a36Sopenharmony_ci	__be32	sl_status;
18962306a36Sopenharmony_ci	struct svc_cred sl_cred;
19062306a36Sopenharmony_ci	u32	sl_datalen;
19162306a36Sopenharmony_ci	u16	sl_opcnt;
19262306a36Sopenharmony_ci#define NFSD4_SLOT_INUSE	(1 << 0)
19362306a36Sopenharmony_ci#define NFSD4_SLOT_CACHETHIS	(1 << 1)
19462306a36Sopenharmony_ci#define NFSD4_SLOT_INITIALIZED	(1 << 2)
19562306a36Sopenharmony_ci#define NFSD4_SLOT_CACHED	(1 << 3)
19662306a36Sopenharmony_ci	u8	sl_flags;
19762306a36Sopenharmony_ci	char	sl_data[];
19862306a36Sopenharmony_ci};
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistruct nfsd4_channel_attrs {
20162306a36Sopenharmony_ci	u32		headerpadsz;
20262306a36Sopenharmony_ci	u32		maxreq_sz;
20362306a36Sopenharmony_ci	u32		maxresp_sz;
20462306a36Sopenharmony_ci	u32		maxresp_cached;
20562306a36Sopenharmony_ci	u32		maxops;
20662306a36Sopenharmony_ci	u32		maxreqs;
20762306a36Sopenharmony_ci	u32		nr_rdma_attrs;
20862306a36Sopenharmony_ci	u32		rdma_attrs;
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistruct nfsd4_cb_sec {
21262306a36Sopenharmony_ci	u32	flavor; /* (u32)(-1) used to mean "no valid flavor" */
21362306a36Sopenharmony_ci	kuid_t	uid;
21462306a36Sopenharmony_ci	kgid_t	gid;
21562306a36Sopenharmony_ci};
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistruct nfsd4_create_session {
21862306a36Sopenharmony_ci	clientid_t			clientid;
21962306a36Sopenharmony_ci	struct nfs4_sessionid		sessionid;
22062306a36Sopenharmony_ci	u32				seqid;
22162306a36Sopenharmony_ci	u32				flags;
22262306a36Sopenharmony_ci	struct nfsd4_channel_attrs	fore_channel;
22362306a36Sopenharmony_ci	struct nfsd4_channel_attrs	back_channel;
22462306a36Sopenharmony_ci	u32				callback_prog;
22562306a36Sopenharmony_ci	struct nfsd4_cb_sec		cb_sec;
22662306a36Sopenharmony_ci};
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cistruct nfsd4_backchannel_ctl {
22962306a36Sopenharmony_ci	u32	bc_cb_program;
23062306a36Sopenharmony_ci	struct nfsd4_cb_sec		bc_cb_sec;
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistruct nfsd4_bind_conn_to_session {
23462306a36Sopenharmony_ci	struct nfs4_sessionid		sessionid;
23562306a36Sopenharmony_ci	u32				dir;
23662306a36Sopenharmony_ci};
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci/* The single slot clientid cache structure */
23962306a36Sopenharmony_cistruct nfsd4_clid_slot {
24062306a36Sopenharmony_ci	u32				sl_seqid;
24162306a36Sopenharmony_ci	__be32				sl_status;
24262306a36Sopenharmony_ci	struct nfsd4_create_session	sl_cr_ses;
24362306a36Sopenharmony_ci};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistruct nfsd4_conn {
24662306a36Sopenharmony_ci	struct list_head cn_persession;
24762306a36Sopenharmony_ci	struct svc_xprt *cn_xprt;
24862306a36Sopenharmony_ci	struct svc_xpt_user cn_xpt_user;
24962306a36Sopenharmony_ci	struct nfsd4_session *cn_session;
25062306a36Sopenharmony_ci/* CDFC4_FORE, CDFC4_BACK: */
25162306a36Sopenharmony_ci	unsigned char cn_flags;
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci/*
25562306a36Sopenharmony_ci * Representation of a v4.1+ session. These are refcounted in a similar fashion
25662306a36Sopenharmony_ci * to the nfs4_client. References are only taken when the server is actively
25762306a36Sopenharmony_ci * working on the object (primarily during the processing of compounds).
25862306a36Sopenharmony_ci */
25962306a36Sopenharmony_cistruct nfsd4_session {
26062306a36Sopenharmony_ci	atomic_t		se_ref;
26162306a36Sopenharmony_ci	struct list_head	se_hash;	/* hash by sessionid */
26262306a36Sopenharmony_ci	struct list_head	se_perclnt;
26362306a36Sopenharmony_ci/* See SESSION4_PERSIST, etc. for standard flags; this is internal-only: */
26462306a36Sopenharmony_ci#define NFS4_SESSION_DEAD	0x010
26562306a36Sopenharmony_ci	u32			se_flags;
26662306a36Sopenharmony_ci	struct nfs4_client	*se_client;
26762306a36Sopenharmony_ci	struct nfs4_sessionid	se_sessionid;
26862306a36Sopenharmony_ci	struct nfsd4_channel_attrs se_fchannel;
26962306a36Sopenharmony_ci	struct nfsd4_channel_attrs se_bchannel;
27062306a36Sopenharmony_ci	struct nfsd4_cb_sec	se_cb_sec;
27162306a36Sopenharmony_ci	struct list_head	se_conns;
27262306a36Sopenharmony_ci	u32			se_cb_prog;
27362306a36Sopenharmony_ci	u32			se_cb_seq_nr;
27462306a36Sopenharmony_ci	struct nfsd4_slot	*se_slots[];	/* forward channel slots */
27562306a36Sopenharmony_ci};
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci/* formatted contents of nfs4_sessionid */
27862306a36Sopenharmony_cistruct nfsd4_sessionid {
27962306a36Sopenharmony_ci	clientid_t	clientid;
28062306a36Sopenharmony_ci	u32		sequence;
28162306a36Sopenharmony_ci	u32		reserved;
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci#define HEXDIR_LEN     33 /* hex version of 16 byte md5 of cl_name plus '\0' */
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci/*
28762306a36Sopenharmony_ci *       State                Meaning                  Where set
28862306a36Sopenharmony_ci * --------------------------------------------------------------------------
28962306a36Sopenharmony_ci * | NFSD4_ACTIVE      | Confirmed, active    | Default                     |
29062306a36Sopenharmony_ci * |------------------- ----------------------------------------------------|
29162306a36Sopenharmony_ci * | NFSD4_COURTESY    | Courtesy state.      | nfs4_get_client_reaplist    |
29262306a36Sopenharmony_ci * |                   | Lease/lock/share     |                             |
29362306a36Sopenharmony_ci * |                   | reservation conflict |                             |
29462306a36Sopenharmony_ci * |                   | can cause Courtesy   |                             |
29562306a36Sopenharmony_ci * |                   | client to be expired |                             |
29662306a36Sopenharmony_ci * |------------------------------------------------------------------------|
29762306a36Sopenharmony_ci * | NFSD4_EXPIRABLE   | Courtesy client to be| nfs4_laundromat             |
29862306a36Sopenharmony_ci * |                   | expired by Laundromat| try_to_expire_client        |
29962306a36Sopenharmony_ci * |                   | due to conflict      |                             |
30062306a36Sopenharmony_ci * |------------------------------------------------------------------------|
30162306a36Sopenharmony_ci */
30262306a36Sopenharmony_cienum {
30362306a36Sopenharmony_ci	NFSD4_ACTIVE = 0,
30462306a36Sopenharmony_ci	NFSD4_COURTESY,
30562306a36Sopenharmony_ci	NFSD4_EXPIRABLE,
30662306a36Sopenharmony_ci};
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci/*
30962306a36Sopenharmony_ci * struct nfs4_client - one per client.  Clientids live here.
31062306a36Sopenharmony_ci *
31162306a36Sopenharmony_ci * The initial object created by an NFS client using SETCLIENTID (for NFSv4.0)
31262306a36Sopenharmony_ci * or EXCHANGE_ID (for NFSv4.1+). These objects are refcounted and timestamped.
31362306a36Sopenharmony_ci * Each nfsd_net_ns object contains a set of these and they are tracked via
31462306a36Sopenharmony_ci * short and long form clientid. They are hashed and searched for under the
31562306a36Sopenharmony_ci * per-nfsd_net client_lock spinlock.
31662306a36Sopenharmony_ci *
31762306a36Sopenharmony_ci * References to it are only held during the processing of compounds, and in
31862306a36Sopenharmony_ci * certain other operations. In their "resting state" they have a refcount of
31962306a36Sopenharmony_ci * 0. If they are not renewed within a lease period, they become eligible for
32062306a36Sopenharmony_ci * destruction by the laundromat.
32162306a36Sopenharmony_ci *
32262306a36Sopenharmony_ci * These objects can also be destroyed prematurely by the fault injection code,
32362306a36Sopenharmony_ci * or if the client sends certain forms of SETCLIENTID or EXCHANGE_ID updates.
32462306a36Sopenharmony_ci * Care is taken *not* to do this however when the objects have an elevated
32562306a36Sopenharmony_ci * refcount.
32662306a36Sopenharmony_ci *
32762306a36Sopenharmony_ci * o Each nfs4_client is hashed by clientid
32862306a36Sopenharmony_ci *
32962306a36Sopenharmony_ci * o Each nfs4_clients is also hashed by name (the opaque quantity initially
33062306a36Sopenharmony_ci *   sent by the client to identify itself).
33162306a36Sopenharmony_ci *
33262306a36Sopenharmony_ci * o cl_perclient list is used to ensure no dangling stateowner references
33362306a36Sopenharmony_ci *   when we expire the nfs4_client
33462306a36Sopenharmony_ci */
33562306a36Sopenharmony_cistruct nfs4_client {
33662306a36Sopenharmony_ci	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
33762306a36Sopenharmony_ci	struct rb_node		cl_namenode;	/* link into by-name trees */
33862306a36Sopenharmony_ci	struct list_head	*cl_ownerstr_hashtbl;
33962306a36Sopenharmony_ci	struct list_head	cl_openowners;
34062306a36Sopenharmony_ci	struct idr		cl_stateids;	/* stateid lookup */
34162306a36Sopenharmony_ci	struct list_head	cl_delegations;
34262306a36Sopenharmony_ci	struct list_head	cl_revoked;	/* unacknowledged, revoked 4.1 state */
34362306a36Sopenharmony_ci	struct list_head        cl_lru;         /* tail queue */
34462306a36Sopenharmony_ci#ifdef CONFIG_NFSD_PNFS
34562306a36Sopenharmony_ci	struct list_head	cl_lo_states;	/* outstanding layout states */
34662306a36Sopenharmony_ci#endif
34762306a36Sopenharmony_ci	struct xdr_netobj	cl_name; 	/* id generated by client */
34862306a36Sopenharmony_ci	nfs4_verifier		cl_verifier; 	/* generated by client */
34962306a36Sopenharmony_ci	time64_t		cl_time;	/* time of last lease renewal */
35062306a36Sopenharmony_ci	struct sockaddr_storage	cl_addr; 	/* client ipaddress */
35162306a36Sopenharmony_ci	bool			cl_mach_cred;	/* SP4_MACH_CRED in force */
35262306a36Sopenharmony_ci	struct svc_cred		cl_cred; 	/* setclientid principal */
35362306a36Sopenharmony_ci	clientid_t		cl_clientid;	/* generated by server */
35462306a36Sopenharmony_ci	nfs4_verifier		cl_confirm;	/* generated by server */
35562306a36Sopenharmony_ci	u32			cl_minorversion;
35662306a36Sopenharmony_ci	/* NFSv4.1 client implementation id: */
35762306a36Sopenharmony_ci	struct xdr_netobj	cl_nii_domain;
35862306a36Sopenharmony_ci	struct xdr_netobj	cl_nii_name;
35962306a36Sopenharmony_ci	struct timespec64	cl_nii_time;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	/* for v4.0 and v4.1 callbacks: */
36262306a36Sopenharmony_ci	struct nfs4_cb_conn	cl_cb_conn;
36362306a36Sopenharmony_ci#define NFSD4_CLIENT_CB_UPDATE		(0)
36462306a36Sopenharmony_ci#define NFSD4_CLIENT_CB_KILL		(1)
36562306a36Sopenharmony_ci#define NFSD4_CLIENT_STABLE		(2)	/* client on stable storage */
36662306a36Sopenharmony_ci#define NFSD4_CLIENT_RECLAIM_COMPLETE	(3)	/* reclaim_complete done */
36762306a36Sopenharmony_ci#define NFSD4_CLIENT_CONFIRMED		(4)	/* client is confirmed */
36862306a36Sopenharmony_ci#define NFSD4_CLIENT_UPCALL_LOCK	(5)	/* upcall serialization */
36962306a36Sopenharmony_ci#define NFSD4_CLIENT_CB_FLAG_MASK	(1 << NFSD4_CLIENT_CB_UPDATE | \
37062306a36Sopenharmony_ci					 1 << NFSD4_CLIENT_CB_KILL)
37162306a36Sopenharmony_ci#define NFSD4_CLIENT_CB_RECALL_ANY	(6)
37262306a36Sopenharmony_ci	unsigned long		cl_flags;
37362306a36Sopenharmony_ci	const struct cred	*cl_cb_cred;
37462306a36Sopenharmony_ci	struct rpc_clnt		*cl_cb_client;
37562306a36Sopenharmony_ci	u32			cl_cb_ident;
37662306a36Sopenharmony_ci#define NFSD4_CB_UP		0
37762306a36Sopenharmony_ci#define NFSD4_CB_UNKNOWN	1
37862306a36Sopenharmony_ci#define NFSD4_CB_DOWN		2
37962306a36Sopenharmony_ci#define NFSD4_CB_FAULT		3
38062306a36Sopenharmony_ci	int			cl_cb_state;
38162306a36Sopenharmony_ci	struct nfsd4_callback	cl_cb_null;
38262306a36Sopenharmony_ci	struct nfsd4_session	*cl_cb_session;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	/* for all client information that callback code might need: */
38562306a36Sopenharmony_ci	spinlock_t		cl_lock;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	/* for nfs41 */
38862306a36Sopenharmony_ci	struct list_head	cl_sessions;
38962306a36Sopenharmony_ci	struct nfsd4_clid_slot	cl_cs_slot;	/* create_session slot */
39062306a36Sopenharmony_ci	u32			cl_exchange_flags;
39162306a36Sopenharmony_ci	/* number of rpc's in progress over an associated session: */
39262306a36Sopenharmony_ci	atomic_t		cl_rpc_users;
39362306a36Sopenharmony_ci	struct nfsdfs_client	cl_nfsdfs;
39462306a36Sopenharmony_ci	struct nfs4_op_map      cl_spo_must_allow;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	/* debugging info directory under nfsd/clients/ : */
39762306a36Sopenharmony_ci	struct dentry		*cl_nfsd_dentry;
39862306a36Sopenharmony_ci	/* 'info' file within that directory. Ref is not counted,
39962306a36Sopenharmony_ci	 * but will remain valid iff cl_nfsd_dentry != NULL
40062306a36Sopenharmony_ci	 */
40162306a36Sopenharmony_ci	struct dentry		*cl_nfsd_info_dentry;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	/* for nfs41 callbacks */
40462306a36Sopenharmony_ci	/* We currently support a single back channel with a single slot */
40562306a36Sopenharmony_ci	unsigned long		cl_cb_slot_busy;
40662306a36Sopenharmony_ci	struct rpc_wait_queue	cl_cb_waitq;	/* backchannel callers may */
40762306a36Sopenharmony_ci						/* wait here for slots */
40862306a36Sopenharmony_ci	struct net		*net;
40962306a36Sopenharmony_ci	struct list_head	async_copies;	/* list of async copies */
41062306a36Sopenharmony_ci	spinlock_t		async_lock;	/* lock for async copies */
41162306a36Sopenharmony_ci	atomic_t		cl_cb_inflight;	/* Outstanding callbacks */
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	unsigned int		cl_state;
41462306a36Sopenharmony_ci	atomic_t		cl_delegs_in_recall;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	struct nfsd4_cb_recall_any	*cl_ra;
41762306a36Sopenharmony_ci	time64_t		cl_ra_time;
41862306a36Sopenharmony_ci	struct list_head	cl_ra_cblist;
41962306a36Sopenharmony_ci};
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci/* struct nfs4_client_reset
42262306a36Sopenharmony_ci * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl
42362306a36Sopenharmony_ci * upon lease reset, or from upcall to state_daemon (to read in state
42462306a36Sopenharmony_ci * from non-volitile storage) upon reboot.
42562306a36Sopenharmony_ci */
42662306a36Sopenharmony_cistruct nfs4_client_reclaim {
42762306a36Sopenharmony_ci	struct list_head	cr_strhash;	/* hash by cr_name */
42862306a36Sopenharmony_ci	struct nfs4_client	*cr_clp;	/* pointer to associated clp */
42962306a36Sopenharmony_ci	struct xdr_netobj	cr_name;	/* recovery dir name */
43062306a36Sopenharmony_ci	struct xdr_netobj	cr_princhash;
43162306a36Sopenharmony_ci};
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci/* A reasonable value for REPLAY_ISIZE was estimated as follows:
43462306a36Sopenharmony_ci * The OPEN response, typically the largest, requires
43562306a36Sopenharmony_ci *   4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +  8(verifier) +
43662306a36Sopenharmony_ci *   4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
43762306a36Sopenharmony_ci *   20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
43862306a36Sopenharmony_ci */
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci#define NFSD4_REPLAY_ISIZE       112
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci/*
44362306a36Sopenharmony_ci * Replay buffer, where the result of the last seqid-mutating operation
44462306a36Sopenharmony_ci * is cached.
44562306a36Sopenharmony_ci */
44662306a36Sopenharmony_cistruct nfs4_replay {
44762306a36Sopenharmony_ci	__be32			rp_status;
44862306a36Sopenharmony_ci	unsigned int		rp_buflen;
44962306a36Sopenharmony_ci	char			*rp_buf;
45062306a36Sopenharmony_ci	struct knfsd_fh		rp_openfh;
45162306a36Sopenharmony_ci	struct mutex		rp_mutex;
45262306a36Sopenharmony_ci	char			rp_ibuf[NFSD4_REPLAY_ISIZE];
45362306a36Sopenharmony_ci};
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_cistruct nfs4_stateowner;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistruct nfs4_stateowner_operations {
45862306a36Sopenharmony_ci	void (*so_unhash)(struct nfs4_stateowner *);
45962306a36Sopenharmony_ci	void (*so_free)(struct nfs4_stateowner *);
46062306a36Sopenharmony_ci};
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci/*
46362306a36Sopenharmony_ci * A core object that represents either an open or lock owner. The object and
46462306a36Sopenharmony_ci * lock owner objects have one of these embedded within them. Refcounts and
46562306a36Sopenharmony_ci * other fields common to both owner types are contained within these
46662306a36Sopenharmony_ci * structures.
46762306a36Sopenharmony_ci */
46862306a36Sopenharmony_cistruct nfs4_stateowner {
46962306a36Sopenharmony_ci	struct list_head			so_strhash;
47062306a36Sopenharmony_ci	struct list_head			so_stateids;
47162306a36Sopenharmony_ci	struct nfs4_client			*so_client;
47262306a36Sopenharmony_ci	const struct nfs4_stateowner_operations	*so_ops;
47362306a36Sopenharmony_ci	/* after increment in nfsd4_bump_seqid, represents the next
47462306a36Sopenharmony_ci	 * sequence id expected from the client: */
47562306a36Sopenharmony_ci	atomic_t				so_count;
47662306a36Sopenharmony_ci	u32					so_seqid;
47762306a36Sopenharmony_ci	struct xdr_netobj			so_owner; /* open owner name */
47862306a36Sopenharmony_ci	struct nfs4_replay			so_replay;
47962306a36Sopenharmony_ci	bool					so_is_open_owner;
48062306a36Sopenharmony_ci};
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci/*
48362306a36Sopenharmony_ci * When a file is opened, the client provides an open state owner opaque string
48462306a36Sopenharmony_ci * that indicates the "owner" of that open. These objects are refcounted.
48562306a36Sopenharmony_ci * References to it are held by each open state associated with it. This object
48662306a36Sopenharmony_ci * is a superset of the nfs4_stateowner struct.
48762306a36Sopenharmony_ci */
48862306a36Sopenharmony_cistruct nfs4_openowner {
48962306a36Sopenharmony_ci	struct nfs4_stateowner	oo_owner; /* must be first field */
49062306a36Sopenharmony_ci	struct list_head        oo_perclient;
49162306a36Sopenharmony_ci	/*
49262306a36Sopenharmony_ci	 * We keep around openowners a little while after last close,
49362306a36Sopenharmony_ci	 * which saves clients from having to confirm, and allows us to
49462306a36Sopenharmony_ci	 * handle close replays if they come soon enough.  The close_lru
49562306a36Sopenharmony_ci	 * is a list of such openowners, to be reaped by the laundromat
49662306a36Sopenharmony_ci	 * thread eventually if they remain unused:
49762306a36Sopenharmony_ci	 */
49862306a36Sopenharmony_ci	struct list_head	oo_close_lru;
49962306a36Sopenharmony_ci	struct nfs4_ol_stateid *oo_last_closed_stid;
50062306a36Sopenharmony_ci	time64_t		oo_time; /* time of placement on so_close_lru */
50162306a36Sopenharmony_ci#define NFS4_OO_CONFIRMED   1
50262306a36Sopenharmony_ci	unsigned char		oo_flags;
50362306a36Sopenharmony_ci};
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci/*
50662306a36Sopenharmony_ci * Represents a generic "lockowner". Similar to an openowner. References to it
50762306a36Sopenharmony_ci * are held by the lock stateids that are created on its behalf. This object is
50862306a36Sopenharmony_ci * a superset of the nfs4_stateowner struct.
50962306a36Sopenharmony_ci */
51062306a36Sopenharmony_cistruct nfs4_lockowner {
51162306a36Sopenharmony_ci	struct nfs4_stateowner	lo_owner;	/* must be first element */
51262306a36Sopenharmony_ci	struct list_head	lo_blocked;	/* blocked file_locks */
51362306a36Sopenharmony_ci};
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_cistatic inline struct nfs4_openowner * openowner(struct nfs4_stateowner *so)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	return container_of(so, struct nfs4_openowner, oo_owner);
51862306a36Sopenharmony_ci}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
52162306a36Sopenharmony_ci{
52262306a36Sopenharmony_ci	return container_of(so, struct nfs4_lockowner, lo_owner);
52362306a36Sopenharmony_ci}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci/*
52662306a36Sopenharmony_ci * Per-client state indicating no. of opens and outstanding delegations
52762306a36Sopenharmony_ci * on a file from a particular client.'od' stands for 'open & delegation'
52862306a36Sopenharmony_ci */
52962306a36Sopenharmony_cistruct nfs4_clnt_odstate {
53062306a36Sopenharmony_ci	struct nfs4_client	*co_client;
53162306a36Sopenharmony_ci	struct nfs4_file	*co_file;
53262306a36Sopenharmony_ci	struct list_head	co_perfile;
53362306a36Sopenharmony_ci	refcount_t		co_odcount;
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci/*
53762306a36Sopenharmony_ci * nfs4_file: a file opened by some number of (open) nfs4_stateowners.
53862306a36Sopenharmony_ci *
53962306a36Sopenharmony_ci * These objects are global. nfsd keeps one instance of a nfs4_file per
54062306a36Sopenharmony_ci * filehandle (though it may keep multiple file descriptors for each). Each
54162306a36Sopenharmony_ci * inode can have multiple filehandles associated with it, so there is
54262306a36Sopenharmony_ci * (potentially) a many to one relationship between this struct and struct
54362306a36Sopenharmony_ci * inode.
54462306a36Sopenharmony_ci */
54562306a36Sopenharmony_cistruct nfs4_file {
54662306a36Sopenharmony_ci	refcount_t		fi_ref;
54762306a36Sopenharmony_ci	struct inode *		fi_inode;
54862306a36Sopenharmony_ci	bool			fi_aliased;
54962306a36Sopenharmony_ci	spinlock_t		fi_lock;
55062306a36Sopenharmony_ci	struct rhlist_head	fi_rlist;
55162306a36Sopenharmony_ci	struct list_head        fi_stateids;
55262306a36Sopenharmony_ci	union {
55362306a36Sopenharmony_ci		struct list_head	fi_delegations;
55462306a36Sopenharmony_ci		struct rcu_head		fi_rcu;
55562306a36Sopenharmony_ci	};
55662306a36Sopenharmony_ci	struct list_head	fi_clnt_odstate;
55762306a36Sopenharmony_ci	/* One each for O_RDONLY, O_WRONLY, O_RDWR: */
55862306a36Sopenharmony_ci	struct nfsd_file	*fi_fds[3];
55962306a36Sopenharmony_ci	/*
56062306a36Sopenharmony_ci	 * Each open or lock stateid contributes 0-4 to the counts
56162306a36Sopenharmony_ci	 * below depending on which bits are set in st_access_bitmap:
56262306a36Sopenharmony_ci	 *     1 to fi_access[O_RDONLY] if NFS4_SHARE_ACCES_READ is set
56362306a36Sopenharmony_ci	 *   + 1 to fi_access[O_WRONLY] if NFS4_SHARE_ACCESS_WRITE is set
56462306a36Sopenharmony_ci	 *   + 1 to both of the above if NFS4_SHARE_ACCESS_BOTH is set.
56562306a36Sopenharmony_ci	 */
56662306a36Sopenharmony_ci	atomic_t		fi_access[2];
56762306a36Sopenharmony_ci	u32			fi_share_deny;
56862306a36Sopenharmony_ci	struct nfsd_file	*fi_deleg_file;
56962306a36Sopenharmony_ci	int			fi_delegees;
57062306a36Sopenharmony_ci	struct knfsd_fh		fi_fhandle;
57162306a36Sopenharmony_ci	bool			fi_had_conflict;
57262306a36Sopenharmony_ci#ifdef CONFIG_NFSD_PNFS
57362306a36Sopenharmony_ci	struct list_head	fi_lo_states;
57462306a36Sopenharmony_ci	atomic_t		fi_lo_recalls;
57562306a36Sopenharmony_ci#endif
57662306a36Sopenharmony_ci};
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci/*
57962306a36Sopenharmony_ci * A generic struct representing either a open or lock stateid. The nfs4_client
58062306a36Sopenharmony_ci * holds a reference to each of these objects, and they in turn hold a
58162306a36Sopenharmony_ci * reference to their respective stateowners. The client's reference is
58262306a36Sopenharmony_ci * released in response to a close or unlock (depending on whether it's an open
58362306a36Sopenharmony_ci * or lock stateid) or when the client is being destroyed.
58462306a36Sopenharmony_ci *
58562306a36Sopenharmony_ci * In the case of v4.0 open stateids, these objects are preserved for a little
58662306a36Sopenharmony_ci * while after close in order to handle CLOSE replays. Those are eventually
58762306a36Sopenharmony_ci * reclaimed via a LRU scheme by the laundromat.
58862306a36Sopenharmony_ci *
58962306a36Sopenharmony_ci * This object is a superset of the nfs4_stid. "ol" stands for "Open or Lock".
59062306a36Sopenharmony_ci * Better suggestions welcome.
59162306a36Sopenharmony_ci */
59262306a36Sopenharmony_cistruct nfs4_ol_stateid {
59362306a36Sopenharmony_ci	struct nfs4_stid		st_stid;
59462306a36Sopenharmony_ci	struct list_head		st_perfile;
59562306a36Sopenharmony_ci	struct list_head		st_perstateowner;
59662306a36Sopenharmony_ci	struct list_head		st_locks;
59762306a36Sopenharmony_ci	struct nfs4_stateowner		*st_stateowner;
59862306a36Sopenharmony_ci	struct nfs4_clnt_odstate	*st_clnt_odstate;
59962306a36Sopenharmony_ci/*
60062306a36Sopenharmony_ci * These bitmasks use 3 separate bits for READ, ALLOW, and BOTH; see the
60162306a36Sopenharmony_ci * comment above bmap_to_share_mode() for explanation:
60262306a36Sopenharmony_ci */
60362306a36Sopenharmony_ci	unsigned char			st_access_bmap;
60462306a36Sopenharmony_ci	unsigned char			st_deny_bmap;
60562306a36Sopenharmony_ci	struct nfs4_ol_stateid		*st_openstp;
60662306a36Sopenharmony_ci	struct mutex			st_mutex;
60762306a36Sopenharmony_ci};
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_cistatic inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
61062306a36Sopenharmony_ci{
61162306a36Sopenharmony_ci	return container_of(s, struct nfs4_ol_stateid, st_stid);
61262306a36Sopenharmony_ci}
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_cistruct nfs4_layout_stateid {
61562306a36Sopenharmony_ci	struct nfs4_stid		ls_stid;
61662306a36Sopenharmony_ci	struct list_head		ls_perclnt;
61762306a36Sopenharmony_ci	struct list_head		ls_perfile;
61862306a36Sopenharmony_ci	spinlock_t			ls_lock;
61962306a36Sopenharmony_ci	struct list_head		ls_layouts;
62062306a36Sopenharmony_ci	u32				ls_layout_type;
62162306a36Sopenharmony_ci	struct nfsd_file		*ls_file;
62262306a36Sopenharmony_ci	struct nfsd4_callback		ls_recall;
62362306a36Sopenharmony_ci	stateid_t			ls_recall_sid;
62462306a36Sopenharmony_ci	bool				ls_recalled;
62562306a36Sopenharmony_ci	struct mutex			ls_mutex;
62662306a36Sopenharmony_ci};
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_cistatic inline struct nfs4_layout_stateid *layoutstateid(struct nfs4_stid *s)
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	return container_of(s, struct nfs4_layout_stateid, ls_stid);
63162306a36Sopenharmony_ci}
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci/* flags for preprocess_seqid_op() */
63462306a36Sopenharmony_ci#define RD_STATE	        0x00000010
63562306a36Sopenharmony_ci#define WR_STATE	        0x00000020
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cienum nfsd4_cb_op {
63862306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_NULL = 0,
63962306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_RECALL,
64062306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_LAYOUT,
64162306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_OFFLOAD,
64262306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_SEQUENCE,
64362306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_NOTIFY_LOCK,
64462306a36Sopenharmony_ci	NFSPROC4_CLNT_CB_RECALL_ANY,
64562306a36Sopenharmony_ci};
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci/* Returns true iff a is later than b: */
64862306a36Sopenharmony_cistatic inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b)
64962306a36Sopenharmony_ci{
65062306a36Sopenharmony_ci	return (s32)(a->si_generation - b->si_generation) > 0;
65162306a36Sopenharmony_ci}
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci/*
65462306a36Sopenharmony_ci * When a client tries to get a lock on a file, we set one of these objects
65562306a36Sopenharmony_ci * on the blocking lock. When the lock becomes free, we can then issue a
65662306a36Sopenharmony_ci * CB_NOTIFY_LOCK to the server.
65762306a36Sopenharmony_ci */
65862306a36Sopenharmony_cistruct nfsd4_blocked_lock {
65962306a36Sopenharmony_ci	struct list_head	nbl_list;
66062306a36Sopenharmony_ci	struct list_head	nbl_lru;
66162306a36Sopenharmony_ci	time64_t		nbl_time;
66262306a36Sopenharmony_ci	struct file_lock	nbl_lock;
66362306a36Sopenharmony_ci	struct knfsd_fh		nbl_fh;
66462306a36Sopenharmony_ci	struct nfsd4_callback	nbl_cb;
66562306a36Sopenharmony_ci	struct kref		nbl_kref;
66662306a36Sopenharmony_ci};
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_cistruct nfsd4_compound_state;
66962306a36Sopenharmony_cistruct nfsd_net;
67062306a36Sopenharmony_cistruct nfsd4_copy;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ciextern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
67362306a36Sopenharmony_ci		struct nfsd4_compound_state *cstate, struct svc_fh *fhp,
67462306a36Sopenharmony_ci		stateid_t *stateid, int flags, struct nfsd_file **filp,
67562306a36Sopenharmony_ci		struct nfs4_stid **cstid);
67662306a36Sopenharmony_ci__be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
67762306a36Sopenharmony_ci		     stateid_t *stateid, unsigned char typemask,
67862306a36Sopenharmony_ci		     struct nfs4_stid **s, struct nfsd_net *nn);
67962306a36Sopenharmony_cistruct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab,
68062306a36Sopenharmony_ci				  void (*sc_free)(struct nfs4_stid *));
68162306a36Sopenharmony_ciint nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy);
68262306a36Sopenharmony_civoid nfs4_free_copy_state(struct nfsd4_copy *copy);
68362306a36Sopenharmony_cistruct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn,
68462306a36Sopenharmony_ci			struct nfs4_stid *p_stid);
68562306a36Sopenharmony_civoid nfs4_unhash_stid(struct nfs4_stid *s);
68662306a36Sopenharmony_civoid nfs4_put_stid(struct nfs4_stid *s);
68762306a36Sopenharmony_civoid nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
68862306a36Sopenharmony_civoid nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
68962306a36Sopenharmony_ciextern void nfs4_release_reclaim(struct nfsd_net *);
69062306a36Sopenharmony_ciextern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(struct xdr_netobj name,
69162306a36Sopenharmony_ci							struct nfsd_net *nn);
69262306a36Sopenharmony_ciextern __be32 nfs4_check_open_reclaim(struct nfs4_client *);
69362306a36Sopenharmony_ciextern void nfsd4_probe_callback(struct nfs4_client *clp);
69462306a36Sopenharmony_ciextern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
69562306a36Sopenharmony_ciextern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
69662306a36Sopenharmony_ciextern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
69762306a36Sopenharmony_ci		const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
69862306a36Sopenharmony_ciextern bool nfsd4_run_cb(struct nfsd4_callback *cb);
69962306a36Sopenharmony_ciextern int nfsd4_create_callback_queue(void);
70062306a36Sopenharmony_ciextern void nfsd4_destroy_callback_queue(void);
70162306a36Sopenharmony_ciextern void nfsd4_shutdown_callback(struct nfs4_client *);
70262306a36Sopenharmony_ciextern void nfsd4_shutdown_copy(struct nfs4_client *clp);
70362306a36Sopenharmony_ciextern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,
70462306a36Sopenharmony_ci				struct xdr_netobj princhash, struct nfsd_net *nn);
70562306a36Sopenharmony_ciextern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_civoid put_nfs4_file(struct nfs4_file *fi);
70862306a36Sopenharmony_ciextern void nfs4_put_cpntf_state(struct nfsd_net *nn,
70962306a36Sopenharmony_ci				 struct nfs4_cpntf_state *cps);
71062306a36Sopenharmony_ciextern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st,
71162306a36Sopenharmony_ci				 struct nfs4_client *clp,
71262306a36Sopenharmony_ci				 struct nfs4_cpntf_state **cps);
71362306a36Sopenharmony_cistatic inline void get_nfs4_file(struct nfs4_file *fi)
71462306a36Sopenharmony_ci{
71562306a36Sopenharmony_ci	refcount_inc(&fi->fi_ref);
71662306a36Sopenharmony_ci}
71762306a36Sopenharmony_cistruct nfsd_file *find_any_file(struct nfs4_file *f);
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci/* grace period management */
72062306a36Sopenharmony_civoid nfsd4_end_grace(struct nfsd_net *nn);
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci/* nfs4recover operations */
72362306a36Sopenharmony_ciextern int nfsd4_client_tracking_init(struct net *net);
72462306a36Sopenharmony_ciextern void nfsd4_client_tracking_exit(struct net *net);
72562306a36Sopenharmony_ciextern void nfsd4_client_record_create(struct nfs4_client *clp);
72662306a36Sopenharmony_ciextern void nfsd4_client_record_remove(struct nfs4_client *clp);
72762306a36Sopenharmony_ciextern int nfsd4_client_record_check(struct nfs4_client *clp);
72862306a36Sopenharmony_ciextern void nfsd4_record_grace_done(struct nfsd_net *nn);
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cistatic inline bool try_to_expire_client(struct nfs4_client *clp)
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci	cmpxchg(&clp->cl_state, NFSD4_COURTESY, NFSD4_EXPIRABLE);
73362306a36Sopenharmony_ci	return clp->cl_state == NFSD4_EXPIRABLE;
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ciextern __be32 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,
73762306a36Sopenharmony_ci				struct inode *inode);
73862306a36Sopenharmony_ci#endif   /* NFSD4_STATE_H */
739