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