/* * Copyright (c) 2001 The Regents of the University of Michigan. * All rights reserved. * * Kendrick Smith <kmsmith@umich.edu> * Andy Adamson <andros@umich.edu> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*/
/* * A core object that represents a "common" stateid. These are generally * embedded within the different (more specific) stateid objects and contain * fields that are of general use to any stateid.
*/ struct nfs4_stid {
refcount_t sc_count;
/* A new stateid is added to the cl_stateids idr early before it * is fully initialised. Its sc_type is then zero. After * initialisation the sc_type it set under cl_lock, and then * never changes.
*/ #define SC_TYPE_OPEN BIT(0) #define SC_TYPE_LOCK BIT(1) #define SC_TYPE_DELEG BIT(2) #define SC_TYPE_LAYOUT BIT(3) unsignedshort sc_type;
/* state_lock protects sc_status for delegation stateids. * ->cl_lock protects sc_status for open and lock stateids. * ->st_mutex also protect sc_status for open stateids. * ->ls_lock protects sc_status for layout stateids.
*/ /* * For an open stateid kept around *only* to process close replays. * For deleg stateid, kept in idr until last reference is dropped.
*/ #define SC_STATUS_CLOSED BIT(0) /* For a deleg stateid kept around only to process free_stateid's: */ #define SC_STATUS_REVOKED BIT(1) #define SC_STATUS_ADMIN_REVOKED BIT(2) #define SC_STATUS_FREEABLE BIT(3) #define SC_STATUS_FREED BIT(4) unsignedshort sc_status;
/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the * parent OPEN/LOCK/DELEG stateid.
*/ struct nfs4_cpntf_state {
copy_stateid_t cp_stateid; struct list_head cp_list; /* per parent nfs4_stid */
stateid_t cp_p_stateid; /* copy of parent's stateid */
clientid_t cp_p_clid; /* copy of parent's clid */
time64_t cpntf_time; /* last time stateid used */
};
/* * RFC 7862 Section 4.8 states: * * | A copy offload stateid will be valid until either (A) the client * | or server restarts or (B) the client returns the resource by * | issuing an OFFLOAD_CANCEL operation or the client replies to a * | CB_OFFLOAD operation. * * Because a client might not reply to a CB_OFFLOAD, or a reply * might get lost due to connection loss, NFSD purges async copy * state after a short period to prevent it from accumulating * over time.
*/ #define NFSD_COPY_INITIAL_TTL 10
/* * Represents a delegation stateid. The nfs4_client holds references to these * and they are put when it is being destroyed or when the delegation is * returned by the client: * * o 1 reference as long as a delegation is still in force (taken when it's * alloc'd, put when it's returned or revoked) * * o 1 reference as long as a recall rpc is in progress (taken when the lease * is broken, put when the rpc exits) * * o 1 more ephemeral reference for each nfsd thread currently doing something * with that delegation without holding the cl_lock * * If the server attempts to recall a delegation and the client doesn't do so * before a timeout, the server may also revoke the delegation. In that case, * the object will either be destroyed (v4.0) or moved to a per-client list of * revoked delegations (v4.1+). * * This object is a superset of the nfs4_stid.
*/ struct nfs4_delegation { struct nfs4_stid dl_stid; /* must be first field */ struct list_head dl_perfile; struct list_head dl_perclnt; struct list_head dl_recall_lru; /* delegation recalled */ struct nfs4_clnt_odstate *dl_clnt_odstate;
time64_t dl_time;
u32 dl_type; /* For recall: */ int dl_retries; struct nfsd4_callback dl_recall; bool dl_recalled;
/* for CB_GETATTR */ struct nfs4_cb_fattr dl_cb_fattr;
/* Maximum number of slots per session. This is for sanity-check only. * It could be increased if we had a mechanism to shutdown misbehaving clients. * A large number can be needed to get good throughput on high-latency servers.
*/ #define NFSD_MAX_SLOTS_PER_SESSION 2048 /* Maximum session per slot cache size */ #define NFSD_SLOT_CACHE_SIZE 2048 /* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */ #define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32 #define NFSD_MAX_MEM_PER_SESSION \
(NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE)
/* Maximum number of slots that nfsd will use in the backchannel */ #define NFSD_BC_SLOT_TABLE_SIZE (sizeof(u32) * 8)
/* * Representation of a v4.1+ session. These are refcounted in a similar fashion * to the nfs4_client. References are only taken when the server is actively * working on the object (primarily during the processing of compounds).
*/ struct nfsd4_session {
atomic_t se_ref;
spinlock_t se_lock;
u32 se_cb_slot_avail; /* bitmap of available slots */
u32 se_cb_highest_slot; /* highest slot client wants */
u32 se_cb_prog; struct list_head se_hash; /* hash by sessionid */ struct list_head se_perclnt; struct list_head se_all_sessions;/* global list of sessions */ struct nfs4_client *se_client; struct nfs4_sessionid se_sessionid; struct nfsd4_channel_attrs se_fchannel; struct nfsd4_cb_sec se_cb_sec; struct list_head se_conns;
u32 se_cb_seq_nr[NFSD_BC_SLOT_TABLE_SIZE]; struct xarray se_slots; /* forward channel slots */
u16 se_slot_gen; bool se_dead;
u32 se_target_maxslots;
};
#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */
/* * State Meaning Where set * -------------------------------------------------------------------------- * | NFSD4_ACTIVE | Confirmed, active | Default | * |------------------- ----------------------------------------------------| * | NFSD4_COURTESY | Courtesy state. | nfs4_get_client_reaplist | * | | Lease/lock/share | | * | | reservation conflict | | * | | can cause Courtesy | | * | | client to be expired | | * |------------------------------------------------------------------------| * | NFSD4_EXPIRABLE | Courtesy client to be| nfs4_laundromat | * | | expired by Laundromat| try_to_expire_client | * | | due to conflict | | * |------------------------------------------------------------------------|
*/ enum {
NFSD4_ACTIVE = 0,
NFSD4_COURTESY,
NFSD4_EXPIRABLE,
};
/* * struct nfs4_client - one per client. Clientids live here. * * The initial object created by an NFS client using SETCLIENTID (for NFSv4.0) * or EXCHANGE_ID (for NFSv4.1+). These objects are refcounted and timestamped. * Each nfsd_net_ns object contains a set of these and they are tracked via * short and long form clientid. They are hashed and searched for under the * per-nfsd_net client_lock spinlock. * * References to it are only held during the processing of compounds, and in * certain other operations. In their "resting state" they have a refcount of * 0. If they are not renewed within a lease period, they become eligible for * destruction by the laundromat. * * These objects can also be destroyed if the client sends certain forms of * SETCLIENTID or EXCHANGE_ID operations. * * Care is taken *not* to do this however when the objects have an elevated * refcount. * * o Each nfs4_client is hashed by clientid * * o Each nfs4_clients is also hashed by name (the opaque quantity initially * sent by the client to identify itself). * * o cl_perclient list is used to ensure no dangling stateowner references * when we expire the nfs4_client
*/ struct nfs4_client { struct list_head cl_idhash; /* hash by cl_clientid.id */ struct rb_node cl_namenode; /* link into by-name trees */ struct list_head *cl_ownerstr_hashtbl; struct list_head cl_openowners; struct idr cl_stateids; /* stateid lookup */ struct list_head cl_delegations; struct list_head cl_revoked; /* unacknowledged, revoked 4.1 state */ struct list_head cl_lru; /* tail queue */ #ifdef CONFIG_NFSD_PNFS struct list_head cl_lo_states; /* outstanding layout states */ #endif struct xdr_netobj cl_name; /* id generated by client */
nfs4_verifier cl_verifier; /* generated by client */
time64_t cl_time; /* time of last lease renewal */ struct sockaddr_storage cl_addr; /* client ipaddress */ bool cl_mach_cred; /* SP4_MACH_CRED in force */ struct svc_cred cl_cred; /* setclientid principal */
clientid_t cl_clientid; /* generated by server */
nfs4_verifier cl_confirm; /* generated by server */
u32 cl_minorversion;
atomic_t cl_admin_revoked; /* count of admin-revoked states */ /* NFSv4.1 client implementation id: */ struct xdr_netobj cl_nii_domain; struct xdr_netobj cl_nii_name; struct timespec64 cl_nii_time;
/* for all client information that callback code might need: */
spinlock_t cl_lock;
/* for nfs41 */ struct list_head cl_sessions; struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */
u32 cl_exchange_flags; /* number of rpc's in progress over an associated session: */
atomic_t cl_rpc_users; struct nfsdfs_client cl_nfsdfs; struct nfs4_op_map cl_spo_must_allow;
/* debugging info directory under nfsd/clients/ : */ struct dentry *cl_nfsd_dentry; /* 'info' file within that directory. Ref is not counted, * but will remain valid iff cl_nfsd_dentry != NULL
*/ struct dentry *cl_nfsd_info_dentry;
struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ /* wait here for slots */ struct net *net; struct list_head async_copies; /* list of async copies */
spinlock_t async_lock; /* lock for async copies */
atomic_t cl_cb_inflight; /* Outstanding callbacks */
/* struct nfs4_client_reset * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl * upon lease reset, or from upcall to state_daemon (to read in state * from non-volitile storage) upon reboot.
*/ struct nfs4_client_reclaim { struct list_head cr_strhash; /* hash by cr_name */ struct nfs4_client *cr_clp; /* pointer to associated clp */ struct xdr_netobj cr_name; /* recovery dir name */ struct xdr_netobj cr_princhash;
};
/* A reasonable value for REPLAY_ISIZE was estimated as follows: * The OPEN response, typically the largest, requires * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) + * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
*/
#define NFSD4_REPLAY_ISIZE 112
/* * Replay buffer, where the result of the last seqid-mutating operation * is cached.
*/ struct nfs4_replay {
__be32 rp_status; unsignedint rp_buflen; char *rp_buf; struct knfsd_fh rp_openfh; int rp_locked; char rp_ibuf[NFSD4_REPLAY_ISIZE];
};
/* * A core object that represents either an open or lock owner. The object and * lock owner objects have one of these embedded within them. Refcounts and * other fields common to both owner types are contained within these * structures.
*/ struct nfs4_stateowner { struct list_head so_strhash; struct list_head so_stateids; struct nfs4_client *so_client; conststruct nfs4_stateowner_operations *so_ops; /* after increment in nfsd4_bump_seqid, represents the next
* sequence id expected from the client: */
atomic_t so_count;
u32 so_seqid; struct xdr_netobj so_owner; /* open owner name */ struct nfs4_replay so_replay; bool so_is_open_owner;
};
/* * When a file is opened, the client provides an open state owner opaque string * that indicates the "owner" of that open. These objects are refcounted. * References to it are held by each open state associated with it. This object * is a superset of the nfs4_stateowner struct.
*/ struct nfs4_openowner { struct nfs4_stateowner oo_owner; /* must be first field */ struct list_head oo_perclient; /* * We keep around openowners a little while after last close, * which saves clients from having to confirm, and allows us to * handle close replays if they come soon enough. The close_lru * is a list of such openowners, to be reaped by the laundromat * thread eventually if they remain unused:
*/ struct list_head oo_close_lru; struct nfs4_ol_stateid *oo_last_closed_stid;
time64_t oo_time; /* time of placement on so_close_lru */ #define NFS4_OO_CONFIRMED 1 unsignedchar oo_flags;
};
/* * Represents a generic "lockowner". Similar to an openowner. References to it * are held by the lock stateids that are created on its behalf. This object is * a superset of the nfs4_stateowner struct.
*/ struct nfs4_lockowner { struct nfs4_stateowner lo_owner; /* must be first element */ struct list_head lo_blocked; /* blocked file_locks */
};
/* * Per-client state indicating no. of opens and outstanding delegations * on a file from a particular client.'od' stands for 'open & delegation'
*/ struct nfs4_clnt_odstate { struct nfs4_client *co_client; struct nfs4_file *co_file; struct list_head co_perfile;
refcount_t co_odcount;
};
/* * nfs4_file: a file opened by some number of (open) nfs4_stateowners. * * These objects are global. nfsd keeps one instance of a nfs4_file per * filehandle (though it may keep multiple file descriptors for each). Each * inode can have multiple filehandles associated with it, so there is * (potentially) a many to one relationship between this struct and struct * inode.
*/ struct nfs4_file {
refcount_t fi_ref; struct inode * fi_inode; bool fi_aliased;
spinlock_t fi_lock; struct rhlist_head fi_rlist; struct list_head fi_stateids; union { struct list_head fi_delegations; struct rcu_head fi_rcu;
}; struct list_head fi_clnt_odstate; /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ struct nfsd_file *fi_fds[3]; /* * Each open or lock stateid contributes 0-4 to the counts * below depending on which bits are set in st_access_bitmap: * 1 to fi_access[O_RDONLY] if NFS4_SHARE_ACCES_READ is set * + 1 to fi_access[O_WRONLY] if NFS4_SHARE_ACCESS_WRITE is set * + 1 to both of the above if NFS4_SHARE_ACCESS_BOTH is set.
*/
atomic_t fi_access[2];
u32 fi_share_deny; struct nfsd_file *fi_deleg_file; struct nfsd_file *fi_rdeleg_file; int fi_delegees; struct knfsd_fh fi_fhandle; bool fi_had_conflict; #ifdef CONFIG_NFSD_PNFS struct list_head fi_lo_states;
atomic_t fi_lo_recalls; #endif
};
/* * A generic struct representing either a open or lock stateid. The nfs4_client * holds a reference to each of these objects, and they in turn hold a * reference to their respective stateowners. The client's reference is * released in response to a close or unlock (depending on whether it's an open * or lock stateid) or when the client is being destroyed. * * In the case of v4.0 open stateids, these objects are preserved for a little * while after close in order to handle CLOSE replays. Those are eventually * reclaimed via a LRU scheme by the laundromat. * * This object is a superset of the nfs4_stid. "ol" stands for "Open or Lock". * Better suggestions welcome.
*/ struct nfs4_ol_stateid { struct nfs4_stid st_stid; struct list_head st_perfile; struct list_head st_perstateowner; struct list_head st_locks; struct nfs4_stateowner *st_stateowner; struct nfs4_clnt_odstate *st_clnt_odstate; /* * These bitmasks use 3 separate bits for READ, ALLOW, and BOTH; see the * comment above bmap_to_share_mode() for explanation:
*/ unsignedchar st_access_bmap; unsignedchar st_deny_bmap; struct nfs4_ol_stateid *st_openstp; struct mutex st_mutex;
};
/* Returns true iff a is later than b: */ staticinlinebool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b)
{ return (s32)(a->si_generation - b->si_generation) > 0;
}
/* * When a client tries to get a lock on a file, we set one of these objects * on the blocking lock. When the lock becomes free, we can then issue a * CB_NOTIFY_LOCK to the server.
*/ struct nfsd4_blocked_lock { struct list_head nbl_list; struct list_head nbl_lru;
time64_t nbl_time; struct file_lock nbl_lock; struct knfsd_fh nbl_fh; struct nfsd4_callback nbl_cb; struct kref nbl_kref;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.