1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _NFS4_H 28*7c478bd9Sstevel@tonic-gate #define _NFS4_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/fem.h> 35*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 36*7c478bd9Sstevel@tonic-gate #include <nfs/nfs.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 39*7c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 40*7c478bd9Sstevel@tonic-gate #else 41*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nfs4_prot.h> 42*7c478bd9Sstevel@tonic-gate #endif 43*7c478bd9Sstevel@tonic-gate #include <nfs/nfs4_attr.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/acl.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 47*7c478bd9Sstevel@tonic-gate extern "C" { 48*7c478bd9Sstevel@tonic-gate #endif 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #define NFS4_MAX_UTF8STRING 65536 51*7c478bd9Sstevel@tonic-gate #define NFS4_MAX_PATHNAME4 65536 52*7c478bd9Sstevel@tonic-gate #define NFS4_MAX_SECOID4 65536 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate typedef struct nfs4_fhandle { 57*7c478bd9Sstevel@tonic-gate int fh_len; 58*7c478bd9Sstevel@tonic-gate char fh_buf[NFS4_FHSIZE]; 59*7c478bd9Sstevel@tonic-gate } nfs4_fhandle_t; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate #define NFS4_MINORVERSION 0 62*7c478bd9Sstevel@tonic-gate #define CB4_MINORVERSION 0 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* 65*7c478bd9Sstevel@tonic-gate * Set the fattr4_change variable using a time struct. Note that change 66*7c478bd9Sstevel@tonic-gate * is 64 bits, but timestruc_t is 128 bits in a 64-bit kernel. 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate #define NFS4_SET_FATTR4_CHANGE(change, ts) \ 69*7c478bd9Sstevel@tonic-gate { \ 70*7c478bd9Sstevel@tonic-gate change = (ts).tv_sec; \ 71*7c478bd9Sstevel@tonic-gate change <<= 32; \ 72*7c478bd9Sstevel@tonic-gate change |= (uint32_t)((ts).tv_nsec); \ 73*7c478bd9Sstevel@tonic-gate } 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate /* 76*7c478bd9Sstevel@tonic-gate * Server lease period. Value is in seconds; Also used for grace period 77*7c478bd9Sstevel@tonic-gate */ 78*7c478bd9Sstevel@tonic-gate extern time_t rfs4_lease_time; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* 81*7c478bd9Sstevel@tonic-gate * This set of typedefs and interfaces represent the core or base set 82*7c478bd9Sstevel@tonic-gate * of functionality that backs the NFSv4 server's state related data 83*7c478bd9Sstevel@tonic-gate * structures. Since the NFSv4 server needs inter-RPC state to be 84*7c478bd9Sstevel@tonic-gate * available that is unrelated to the filesystem (in other words, 85*7c478bd9Sstevel@tonic-gate * soft-state), this functionality is needed to maintain that and is 86*7c478bd9Sstevel@tonic-gate * written to be somewhat flexible to adapt to the various types of 87*7c478bd9Sstevel@tonic-gate * data structures contained within the server. 88*7c478bd9Sstevel@tonic-gate * 89*7c478bd9Sstevel@tonic-gate * The basic structure at this level is that the server maintains a 90*7c478bd9Sstevel@tonic-gate * global "database" which consists of a set of tables. Each table 91*7c478bd9Sstevel@tonic-gate * contains a set of like data structures. Each table is indexed by 92*7c478bd9Sstevel@tonic-gate * at least one hash function and in most cases two hashes. Each 93*7c478bd9Sstevel@tonic-gate * table's characteristics is set when it is created at run-time via 94*7c478bd9Sstevel@tonic-gate * rfs4_table_create(). All table creation and related functions are 95*7c478bd9Sstevel@tonic-gate * located in nfs4_state.c. The generic database functionality is 96*7c478bd9Sstevel@tonic-gate * located in nfs4_db.c. 97*7c478bd9Sstevel@tonic-gate */ 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate typedef struct rfs4_dbe rfs4_dbe_t; /* basic opaque db entry */ 100*7c478bd9Sstevel@tonic-gate typedef struct rfs4_table rfs4_table_t; /* basic table type */ 101*7c478bd9Sstevel@tonic-gate typedef struct rfs4_index rfs4_index_t; /* index */ 102*7c478bd9Sstevel@tonic-gate typedef struct rfs4_database rfs4_database_t; /* and database */ 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate typedef struct { /* opaque entry type for later use */ 105*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 106*7c478bd9Sstevel@tonic-gate } *rfs4_entry_t; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate extern rfs4_table_t *rfs4_client_tab; 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* database, table, index creation entry points */ 111*7c478bd9Sstevel@tonic-gate extern rfs4_database_t *rfs4_database_create(uint32_t); 112*7c478bd9Sstevel@tonic-gate extern void rfs4_database_shutdown(rfs4_database_t *); 113*7c478bd9Sstevel@tonic-gate extern void rfs4_database_destroy(rfs4_database_t *); 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate extern void rfs4_database_destroy(rfs4_database_t *); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate extern rfs4_table_t *rfs4_table_create(rfs4_database_t *, char *, 118*7c478bd9Sstevel@tonic-gate time_t, uint32_t, 119*7c478bd9Sstevel@tonic-gate bool_t (*create)(rfs4_entry_t, void *), 120*7c478bd9Sstevel@tonic-gate void (*destroy)(rfs4_entry_t), 121*7c478bd9Sstevel@tonic-gate bool_t (*expiry)(rfs4_entry_t), 122*7c478bd9Sstevel@tonic-gate uint32_t, uint32_t, uint32_t, id_t); 123*7c478bd9Sstevel@tonic-gate extern void rfs4_table_destroy(rfs4_database_t *, rfs4_table_t *); 124*7c478bd9Sstevel@tonic-gate extern rfs4_index_t *rfs4_index_create(rfs4_table_t *, char *, 125*7c478bd9Sstevel@tonic-gate uint32_t (*hash)(void *), 126*7c478bd9Sstevel@tonic-gate bool_t (compare)(rfs4_entry_t, void *), 127*7c478bd9Sstevel@tonic-gate void *(*mkkey)(rfs4_entry_t), bool_t); 128*7c478bd9Sstevel@tonic-gate extern void rfs4_index_destroy(rfs4_index_t *); 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* Type used to direct rfs4_dbsearch() in what types of records to inspect */ 131*7c478bd9Sstevel@tonic-gate typedef enum {RFS4_DBS_VALID, RFS4_DBS_INVALID} rfs4_dbsearch_type_t; 132*7c478bd9Sstevel@tonic-gate /* search and db entry manipulation entry points */ 133*7c478bd9Sstevel@tonic-gate extern rfs4_entry_t rfs4_dbsearch(rfs4_index_t *, void *, 134*7c478bd9Sstevel@tonic-gate bool_t *, void *, rfs4_dbsearch_type_t); 135*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_lock(rfs4_dbe_t *); 136*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_unlock(rfs4_dbe_t *); 137*7c478bd9Sstevel@tonic-gate extern clock_t rfs4_dbe_twait(rfs4_dbe_t *, clock_t); 138*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_cv_broadcast(rfs4_dbe_t *); 139*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hold(rfs4_dbe_t *); 140*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hold_nolock(rfs4_dbe_t *); 141*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_rele_nolock(rfs4_dbe_t *); 142*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_rele(rfs4_dbe_t *); 143*7c478bd9Sstevel@tonic-gate extern uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *); 144*7c478bd9Sstevel@tonic-gate extern id_t rfs4_dbe_getid(rfs4_dbe_t *); 145*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_invalidate(rfs4_dbe_t *); 146*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_dbe_is_invalid(rfs4_dbe_t *); 147*7c478bd9Sstevel@tonic-gate extern time_t rfs4_dbe_get_timerele(rfs4_dbe_t *); 148*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hide(rfs4_dbe_t *); 149*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_unhide(rfs4_dbe_t *); 150*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 151*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_dbe_islocked(rfs4_dbe_t *); 152*7c478bd9Sstevel@tonic-gate #endif 153*7c478bd9Sstevel@tonic-gate extern void rfs4_dbe_walk(rfs4_table_t *, 154*7c478bd9Sstevel@tonic-gate void (*callout)(rfs4_entry_t, void *), void *); 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * Minimal server stable storage. 158*7c478bd9Sstevel@tonic-gate * 159*7c478bd9Sstevel@tonic-gate * Currently the NFSv4 server will only save the client 160*7c478bd9Sstevel@tonic-gate * ID (the long version) so that it will be able to 161*7c478bd9Sstevel@tonic-gate * grant possible reclaim requests during the infamous 162*7c478bd9Sstevel@tonic-gate * grace_period. 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate #define RFS4_SS_DIRSIZE 64 * 1024 166*7c478bd9Sstevel@tonic-gate #define NFS4_SS_VERSION 1 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate /* handy pathname structure */ 169*7c478bd9Sstevel@tonic-gate typedef struct ss_pn { 170*7c478bd9Sstevel@tonic-gate char *leaf; 171*7c478bd9Sstevel@tonic-gate char pn[MAXPATHLEN]; 172*7c478bd9Sstevel@tonic-gate } rfs4_ss_pn_t; 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate /* 175*7c478bd9Sstevel@tonic-gate * The server will build this link list on startup. It represents the 176*7c478bd9Sstevel@tonic-gate * clients that have had valid state on the server in a prior instance. 177*7c478bd9Sstevel@tonic-gate * 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate typedef struct rfs4_oldstate { 180*7c478bd9Sstevel@tonic-gate struct rfs4_oldstate *next; 181*7c478bd9Sstevel@tonic-gate struct rfs4_oldstate *prev; 182*7c478bd9Sstevel@tonic-gate rfs4_ss_pn_t *ss_pn; 183*7c478bd9Sstevel@tonic-gate nfs_client_id4 cl_id4; 184*7c478bd9Sstevel@tonic-gate } rfs4_oldstate_t; 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* 187*7c478bd9Sstevel@tonic-gate * This union is used to overlay the server's internal treatment of 188*7c478bd9Sstevel@tonic-gate * the protocols stateid4 datatype. Therefore, "bits" must not exceed 189*7c478bd9Sstevel@tonic-gate * the size of stateid4 and more importantly should match the size of 190*7c478bd9Sstevel@tonic-gate * stateid4. The chgseq field must the first entry since it overlays 191*7c478bd9Sstevel@tonic-gate * stateid4.seqid. 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate typedef union { 194*7c478bd9Sstevel@tonic-gate stateid4 stateid; 195*7c478bd9Sstevel@tonic-gate struct { 196*7c478bd9Sstevel@tonic-gate uint32_t chgseq; /* State changes / protocol's seqid */ 197*7c478bd9Sstevel@tonic-gate uint32_t boottime; /* boot time */ 198*7c478bd9Sstevel@tonic-gate uint32_t type:2; /* stateid_type_t as define below */ 199*7c478bd9Sstevel@tonic-gate uint32_t clnodeid:8; /* cluster server nodeid */ 200*7c478bd9Sstevel@tonic-gate uint32_t ident:22; /* 2^22-1 openowner x fhs */ 201*7c478bd9Sstevel@tonic-gate pid_t pid; /* pid of corresponding lock owner */ 202*7c478bd9Sstevel@tonic-gate } bits; 203*7c478bd9Sstevel@tonic-gate } stateid_t; 204*7c478bd9Sstevel@tonic-gate /* 205*7c478bd9Sstevel@tonic-gate * Note that the way the type field above is defined, this enum must 206*7c478bd9Sstevel@tonic-gate * not have more than 4 members. 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate typedef enum {OPENID, LOCKID, DELEGID} stateid_type_t; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate /* 212*7c478bd9Sstevel@tonic-gate * Set of RPC credentials used for a particular operation. 213*7c478bd9Sstevel@tonic-gate * Used for operations like SETCLIENTID_CONFIRM where the 214*7c478bd9Sstevel@tonic-gate * credentials needs to match those used at SETCLIENTID. 215*7c478bd9Sstevel@tonic-gate */ 216*7c478bd9Sstevel@tonic-gate typedef void *cred_set_t; /* For now XXX */ 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate /* 219*7c478bd9Sstevel@tonic-gate * "wait" struct for use in the open open and lock owner state 220*7c478bd9Sstevel@tonic-gate * structures to provide serialization between server threads that are 221*7c478bd9Sstevel@tonic-gate * handling requests for the same open owner or lock stateid. This 222*7c478bd9Sstevel@tonic-gate * way only one thread will be updating things like sequence ids, 223*7c478bd9Sstevel@tonic-gate * replay cache and stateid at a time. 224*7c478bd9Sstevel@tonic-gate */ 225*7c478bd9Sstevel@tonic-gate typedef struct rfs4_state_wait { 226*7c478bd9Sstevel@tonic-gate uint32_t sw_active; 227*7c478bd9Sstevel@tonic-gate uint32_t sw_wait_count; 228*7c478bd9Sstevel@tonic-gate kmutex_t sw_cv_lock[1]; 229*7c478bd9Sstevel@tonic-gate kcondvar_t sw_cv[1]; 230*7c478bd9Sstevel@tonic-gate } rfs4_state_wait_t; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate extern void rfs4_sw_enter(rfs4_state_wait_t *); 233*7c478bd9Sstevel@tonic-gate extern void rfs4_sw_exit(rfs4_state_wait_t *); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* 236*7c478bd9Sstevel@tonic-gate * This enum and the following rfs4_cbinfo_t struct are used to 237*7c478bd9Sstevel@tonic-gate * maintain information about the callback path used from the server 238*7c478bd9Sstevel@tonic-gate * to client for operations like CB_GETATTR and CB_RECALL. The 239*7c478bd9Sstevel@tonic-gate * rfs4_cbinfo_t struct is meant to be encompassed in the client 240*7c478bd9Sstevel@tonic-gate * struct and managed within that structure's locking scheme. 241*7c478bd9Sstevel@tonic-gate * 242*7c478bd9Sstevel@tonic-gate * The various states of the callback path are used by the server to 243*7c478bd9Sstevel@tonic-gate * determine if delegations should initially be provided to a client 244*7c478bd9Sstevel@tonic-gate * and then later on if connectivity has been lost and delegations 245*7c478bd9Sstevel@tonic-gate * should be revoked. 246*7c478bd9Sstevel@tonic-gate */ 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * CB_NOCHANGE - Special value used for interfaces within the delegation 250*7c478bd9Sstevel@tonic-gate * code to signify that "no change" has occurred to the 251*7c478bd9Sstevel@tonic-gate * callback path 252*7c478bd9Sstevel@tonic-gate * CB_UNINIT - No callback info provided by the client 253*7c478bd9Sstevel@tonic-gate * CB_NONE - Callback info provided but CB_NULL call 254*7c478bd9Sstevel@tonic-gate * has yet to be attempted 255*7c478bd9Sstevel@tonic-gate * CB_OK - Callback path tested with CB_NULL with success 256*7c478bd9Sstevel@tonic-gate * CB_INPROG - Callback path currently being tested with CB_NULL 257*7c478bd9Sstevel@tonic-gate * CB_FAILED - Callback path was == CB_OK but has failed 258*7c478bd9Sstevel@tonic-gate * with timeout/rpc error 259*7c478bd9Sstevel@tonic-gate * CB_BAD - Callback info provided but CB_NULL failed 260*7c478bd9Sstevel@tonic-gate */ 261*7c478bd9Sstevel@tonic-gate typedef enum { 262*7c478bd9Sstevel@tonic-gate CB_NOCHANGE = 0, 263*7c478bd9Sstevel@tonic-gate CB_UNINIT = 1, 264*7c478bd9Sstevel@tonic-gate CB_NONE = 2, 265*7c478bd9Sstevel@tonic-gate CB_OK = 3, 266*7c478bd9Sstevel@tonic-gate CB_INPROG = 4, 267*7c478bd9Sstevel@tonic-gate CB_FAILED = 5, 268*7c478bd9Sstevel@tonic-gate CB_BAD = 6 269*7c478bd9Sstevel@tonic-gate } rfs4_cbstate_t; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate #define RFS4_CBCH_MAX 10 /* size callback client handle cache */ 272*7c478bd9Sstevel@tonic-gate /* 273*7c478bd9Sstevel@tonic-gate * Callback info for a client. 274*7c478bd9Sstevel@tonic-gate * Client only provides: cb_client4 and cb_ident 275*7c478bd9Sstevel@tonic-gate * The rest of the information is used to track callback path status 276*7c478bd9Sstevel@tonic-gate * and usage. 277*7c478bd9Sstevel@tonic-gate * 278*7c478bd9Sstevel@tonic-gate * cb_state - used as comments for the rfs4_cbstate_t enum indicate 279*7c478bd9Sstevel@tonic-gate * cb_notified_of_cb_path_down - if the callback path was once CB_OK and 280*7c478bd9Sstevel@tonic-gate * has hence CB_FAILED, the client needs to be notified via RENEW. 281*7c478bd9Sstevel@tonic-gate * cb_timefailed - current time when cb_state transitioned from 282*7c478bd9Sstevel@tonic-gate * CB_OK -> CB_FAILED. Meant for observability. When did that happen? 283*7c478bd9Sstevel@tonic-gate * cb_chc_free/cb_chc - cache of client handles for the callback path 284*7c478bd9Sstevel@tonic-gate * cb_ident - SETCLIENTID provided callback_ident value 285*7c478bd9Sstevel@tonic-gate * callback - SETCLIENTID provided cb_client4 value 286*7c478bd9Sstevel@tonic-gate * cb_refcnt - current number of users of this structure's content 287*7c478bd9Sstevel@tonic-gate * protected by cb_lock 288*7c478bd9Sstevel@tonic-gate * cb_badbehavior - how many times did a client do something we didn't like? 289*7c478bd9Sstevel@tonic-gate * cb_lock - lock for contents of cbinfo 290*7c478bd9Sstevel@tonic-gate * cb_cv - used to allow threads to wait on CB_NULL completion 291*7c478bd9Sstevel@tonic-gate * cb_nullcaller - is there a thread currently taking care of 292*7c478bd9Sstevel@tonic-gate * new callback information? 293*7c478bd9Sstevel@tonic-gate * cb_cv_nullcaller - used by the thread doing CB_NULL to wait on 294*7c478bd9Sstevel@tonic-gate * threads that may be using client handles of the current 295*7c478bd9Sstevel@tonic-gate * client handle cache. 296*7c478bd9Sstevel@tonic-gate * newer - new callback info provided by a client and awaiting 297*7c478bd9Sstevel@tonic-gate * CB_NULL testing and move to regular cbinfo. 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate typedef struct { 300*7c478bd9Sstevel@tonic-gate rfs4_cbstate_t cb_state; 301*7c478bd9Sstevel@tonic-gate unsigned cb_notified_of_cb_path_down:1; 302*7c478bd9Sstevel@tonic-gate time_t cb_timefailed; 303*7c478bd9Sstevel@tonic-gate int cb_chc_free; 304*7c478bd9Sstevel@tonic-gate CLIENT *cb_chc[RFS4_CBCH_MAX]; 305*7c478bd9Sstevel@tonic-gate uint32_t cb_ident; 306*7c478bd9Sstevel@tonic-gate cb_client4 cb_callback; 307*7c478bd9Sstevel@tonic-gate uint32_t cb_refcnt; 308*7c478bd9Sstevel@tonic-gate uint32_t cb_badbehavior; 309*7c478bd9Sstevel@tonic-gate kmutex_t cb_lock[1]; 310*7c478bd9Sstevel@tonic-gate kcondvar_t cb_cv[1]; 311*7c478bd9Sstevel@tonic-gate bool_t cb_nullcaller; 312*7c478bd9Sstevel@tonic-gate kcondvar_t cb_cv_nullcaller[1]; 313*7c478bd9Sstevel@tonic-gate struct { 314*7c478bd9Sstevel@tonic-gate bool_t cb_new; 315*7c478bd9Sstevel@tonic-gate bool_t cb_confirmed; 316*7c478bd9Sstevel@tonic-gate uint32_t cb_ident; 317*7c478bd9Sstevel@tonic-gate cb_client4 cb_callback; 318*7c478bd9Sstevel@tonic-gate } cb_newer; 319*7c478bd9Sstevel@tonic-gate } rfs4_cbinfo_t; 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate /* 322*7c478bd9Sstevel@tonic-gate * A server instance. We can associate sets of clients - via a pointer in 323*7c478bd9Sstevel@tonic-gate * rfs4_client_t - with a given server instance, allowing us to treat clients 324*7c478bd9Sstevel@tonic-gate * in the set differently to clients in other sets. 325*7c478bd9Sstevel@tonic-gate * 326*7c478bd9Sstevel@tonic-gate * Currently used only for Sun Cluster HA-NFS support, to group clients 327*7c478bd9Sstevel@tonic-gate * on NFS resource failover so each set of clients gets its own dedicated 328*7c478bd9Sstevel@tonic-gate * grace period. 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate typedef struct rfs4_servinst { 331*7c478bd9Sstevel@tonic-gate krwlock_t rwlock; 332*7c478bd9Sstevel@tonic-gate time_t start_time; 333*7c478bd9Sstevel@tonic-gate time_t grace_period; 334*7c478bd9Sstevel@tonic-gate struct rfs4_servinst *next; 335*7c478bd9Sstevel@tonic-gate struct rfs4_servinst *prev; 336*7c478bd9Sstevel@tonic-gate } rfs4_servinst_t; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * List declarations (suitable for insque/remque) used to link the 340*7c478bd9Sstevel@tonic-gate * various datastructs listed below. 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate typedef struct rfs4_state_list { 343*7c478bd9Sstevel@tonic-gate struct rfs4_state_list *next; 344*7c478bd9Sstevel@tonic-gate struct rfs4_state_list *prev; 345*7c478bd9Sstevel@tonic-gate struct rfs4_state *sp; 346*7c478bd9Sstevel@tonic-gate } rfs4_state_list_t; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate typedef struct rfs4_lo_state_list { 349*7c478bd9Sstevel@tonic-gate struct rfs4_lo_state_list *next; 350*7c478bd9Sstevel@tonic-gate struct rfs4_lo_state_list *prev; 351*7c478bd9Sstevel@tonic-gate struct rfs4_lo_state *lsp; 352*7c478bd9Sstevel@tonic-gate } rfs4_lo_state_list_t; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate typedef struct rfs4_openowner_list { 355*7c478bd9Sstevel@tonic-gate struct rfs4_openowner_list *next; 356*7c478bd9Sstevel@tonic-gate struct rfs4_openowner_list *prev; 357*7c478bd9Sstevel@tonic-gate struct rfs4_openowner *oop; 358*7c478bd9Sstevel@tonic-gate } rfs4_openowner_list_t; 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate typedef struct rfs4_deleg_list { 361*7c478bd9Sstevel@tonic-gate struct rfs4_deleg_list *next; 362*7c478bd9Sstevel@tonic-gate struct rfs4_deleg_list *prev; 363*7c478bd9Sstevel@tonic-gate struct rfs4_deleg_state *dsp; 364*7c478bd9Sstevel@tonic-gate } rfs4_deleg_list_t; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * The server maintains a set of state on a per client basis that 368*7c478bd9Sstevel@tonic-gate * matches that of the protocol requirements. A client's state is 369*7c478bd9Sstevel@tonic-gate * rooted with the rfs4_client_t struct of which there is one per 370*7c478bd9Sstevel@tonic-gate * client and is created when SETCLIENTID/SETCLIENTID_CONFIRM are 371*7c478bd9Sstevel@tonic-gate * received. From there, the server then creates rfs4_openowner_t 372*7c478bd9Sstevel@tonic-gate * structs for each new open owner from that client and are initiated 373*7c478bd9Sstevel@tonic-gate * at OPEN/OPEN_CONFIRM (when the open owner is new to the server). 374*7c478bd9Sstevel@tonic-gate * At OPEN, at least two other structures are created, and potentially a 375*7c478bd9Sstevel@tonic-gate * third. rfs4_state_t is created to track the association between an 376*7c478bd9Sstevel@tonic-gate * open owner and a particular file. An rfs4_file_t struct may be 377*7c478bd9Sstevel@tonic-gate * created (if the file is not already open) at OPEN as well. The 378*7c478bd9Sstevel@tonic-gate * rfs4_file_t struct is the only one that is per server and not per 379*7c478bd9Sstevel@tonic-gate * client. The rfs4_deleg_state_t struct is created in the 380*7c478bd9Sstevel@tonic-gate * instance that the server is going to provide a delegation for the 381*7c478bd9Sstevel@tonic-gate * file being OPENed. Finally, the rfs4_lockowner_t is created at the 382*7c478bd9Sstevel@tonic-gate * first use of a lock owner at the server and is a result of the LOCK 383*7c478bd9Sstevel@tonic-gate * operation. The rfs4_lo_state_t struct is then created to represent 384*7c478bd9Sstevel@tonic-gate * the relation between the lock owner and the file. 385*7c478bd9Sstevel@tonic-gate * 386*7c478bd9Sstevel@tonic-gate */ 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * The following ascii art represents each of these data structs and 389*7c478bd9Sstevel@tonic-gate * their references to each other. Note: "<-(x)->" represents the 390*7c478bd9Sstevel@tonic-gate * doubly link lists defined above. 391*7c478bd9Sstevel@tonic-gate * 392*7c478bd9Sstevel@tonic-gate * ____________________ 393*7c478bd9Sstevel@tonic-gate * | | 394*7c478bd9Sstevel@tonic-gate * | rfs4_client_t | 395*7c478bd9Sstevel@tonic-gate * ->| (1),(2) |<- 396*7c478bd9Sstevel@tonic-gate * / |____________________| \ 397*7c478bd9Sstevel@tonic-gate * / ^ \ 398*7c478bd9Sstevel@tonic-gate * / | \ 399*7c478bd9Sstevel@tonic-gate * ____________________ ____________________ ____________________ 400*7c478bd9Sstevel@tonic-gate * | | | | | | 401*7c478bd9Sstevel@tonic-gate * | rfs4_lockowner_t | | rfs4_openowner_t | | rfs4_deleg_state_t | 402*7c478bd9Sstevel@tonic-gate * | | | (3) <-(1)-> | | <-(2)-> | 403*7c478bd9Sstevel@tonic-gate * |____________________| |____________________| |____________________| 404*7c478bd9Sstevel@tonic-gate * ^ ^ | 405*7c478bd9Sstevel@tonic-gate * | | V 406*7c478bd9Sstevel@tonic-gate * ____________________ ____________________ ____________________ 407*7c478bd9Sstevel@tonic-gate * | | | | | | 408*7c478bd9Sstevel@tonic-gate * | rfs4_lo_state_t |->| rfs4_state_t |->| rfs4_file_t | 409*7c478bd9Sstevel@tonic-gate * | <-(4)-> | | (4) <-(3)-> | | | 410*7c478bd9Sstevel@tonic-gate * |____________________| |____________________| |____________________| 411*7c478bd9Sstevel@tonic-gate */ 412*7c478bd9Sstevel@tonic-gate /* 413*7c478bd9Sstevel@tonic-gate * Each of these data types are kept in a separate rfs4_table_t and is 414*7c478bd9Sstevel@tonic-gate * actually encapsulated within a rfs4_dbe_t struct. The various 415*7c478bd9Sstevel@tonic-gate * tables and their construction is done in nfs4_state.c but 416*7c478bd9Sstevel@tonic-gate * documented here to completeness. 417*7c478bd9Sstevel@tonic-gate * 418*7c478bd9Sstevel@tonic-gate * Table Data struct stored Indexed by 419*7c478bd9Sstevel@tonic-gate * ----- ------------------ ---------- 420*7c478bd9Sstevel@tonic-gate * rfs4_client_tab rfs4_client_t nfs_client_id4 421*7c478bd9Sstevel@tonic-gate * clientid4 422*7c478bd9Sstevel@tonic-gate * 423*7c478bd9Sstevel@tonic-gate * rfs4_openowner_tab rfs4_openowner_t open_owner4 424*7c478bd9Sstevel@tonic-gate * 425*7c478bd9Sstevel@tonic-gate * rfs4_state_tab rfs4_state_t open_owner4 | file 426*7c478bd9Sstevel@tonic-gate * stateid 427*7c478bd9Sstevel@tonic-gate * 428*7c478bd9Sstevel@tonic-gate * rfs4_lo_state_tab rfs4_lo_state_t lockowner | stateid 429*7c478bd9Sstevel@tonic-gate * lock_stateid 430*7c478bd9Sstevel@tonic-gate * 431*7c478bd9Sstevel@tonic-gate * rfs4_lockowner_tab rfs4_lockowner_t lockowner 432*7c478bd9Sstevel@tonic-gate * pid 433*7c478bd9Sstevel@tonic-gate * 434*7c478bd9Sstevel@tonic-gate * rfs4_file_tab rfs4_file_t filehandle 435*7c478bd9Sstevel@tonic-gate * 436*7c478bd9Sstevel@tonic-gate * rfs4_deleg_state_tab rfs4_deleg_state_t clientid4 | file 437*7c478bd9Sstevel@tonic-gate * deleg_stateid 438*7c478bd9Sstevel@tonic-gate */ 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate /* 441*7c478bd9Sstevel@tonic-gate * The client struct, it is the root of all state for a particular 442*7c478bd9Sstevel@tonic-gate * client. The client is identified by the nfs_client_id4 via 443*7c478bd9Sstevel@tonic-gate * SETCLIENTID and the server returns the clientid4 as short hand reference 444*7c478bd9Sstevel@tonic-gate */ 445*7c478bd9Sstevel@tonic-gate /* 446*7c478bd9Sstevel@tonic-gate * Client struct - as mentioned above it is the root of all state for 447*7c478bd9Sstevel@tonic-gate * a single client as identified by the client supplied nfs_client_id4 448*7c478bd9Sstevel@tonic-gate * 449*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 450*7c478bd9Sstevel@tonic-gate * clientid - server assigned short hand reference to client 451*7c478bd9Sstevel@tonic-gate * nfs_client - client supplied identifier for itself 452*7c478bd9Sstevel@tonic-gate * confirm_verf - the value provided to the client for SETCLIENTID_CONFIRM 453*7c478bd9Sstevel@tonic-gate * need_confirm - does this client need to be SETCLIENTID_CONFIRMed? 454*7c478bd9Sstevel@tonic-gate * 455*7c478bd9Sstevel@tonic-gate * unlksys_completed - has an F_UNLKSYS been done for this client which 456*7c478bd9Sstevel@tonic-gate * says that the use of cleanlocks() on individual files 457*7c478bd9Sstevel@tonic-gate * is not required? 458*7c478bd9Sstevel@tonic-gate * can_reclaim - indicates if client is allowed to reclaim after server 459*7c478bd9Sstevel@tonic-gate * start-up (client had previous state at server) 460*7c478bd9Sstevel@tonic-gate * ss_remove - indicates that the rfs4_client_destroy function should 461*7c478bd9Sstevel@tonic-gate * clean up stable storage file. 462*7c478bd9Sstevel@tonic-gate * forced_expire - set if the sysadmin has used clear_locks for this client. 463*7c478bd9Sstevel@tonic-gate * deleg_revoked - how many delegations have been revoked for this client? 464*7c478bd9Sstevel@tonic-gate * 465*7c478bd9Sstevel@tonic-gate * cp_confirmed - this refers to a confirmed client struct that has 466*7c478bd9Sstevel@tonic-gate * the same nfs_client_id4 as this client struct. When/if this client 467*7c478bd9Sstevel@tonic-gate * struct is confirmed via SETCLINETID_CONFIRM, the previously 468*7c478bd9Sstevel@tonic-gate * confirmed client struct will be "closed" and hence this reference. 469*7c478bd9Sstevel@tonic-gate * 470*7c478bd9Sstevel@tonic-gate * last_access - used to determine if the client has let its lease expire 471*7c478bd9Sstevel@tonic-gate * cbinfo - struct containing all callback related information 472*7c478bd9Sstevel@tonic-gate * cr_set - credentials used for the SETCLIENTID/SETCLIENTID_CONFIRM pair 473*7c478bd9Sstevel@tonic-gate * sysid - the lock manager sysid allocated for this client's file locks 474*7c478bd9Sstevel@tonic-gate * openownerlist - root of openowners list associated with this client 475*7c478bd9Sstevel@tonic-gate * clientdeleglist - root of delegations list provided to this client 476*7c478bd9Sstevel@tonic-gate * ss_pn - Pathname to the stable storage file. 477*7c478bd9Sstevel@tonic-gate * cl_addr - Clients network address. 478*7c478bd9Sstevel@tonic-gate * server_instance - pointer to the currently associated server instance 479*7c478bd9Sstevel@tonic-gate */ 480*7c478bd9Sstevel@tonic-gate typedef struct rfs4_client { 481*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 482*7c478bd9Sstevel@tonic-gate clientid4 clientid; 483*7c478bd9Sstevel@tonic-gate nfs_client_id4 nfs_client; 484*7c478bd9Sstevel@tonic-gate verifier4 confirm_verf; 485*7c478bd9Sstevel@tonic-gate unsigned need_confirm:1; 486*7c478bd9Sstevel@tonic-gate unsigned unlksys_completed:1; 487*7c478bd9Sstevel@tonic-gate unsigned can_reclaim:1; 488*7c478bd9Sstevel@tonic-gate unsigned ss_remove:1; 489*7c478bd9Sstevel@tonic-gate unsigned forced_expire:1; 490*7c478bd9Sstevel@tonic-gate uint_t deleg_revoked; 491*7c478bd9Sstevel@tonic-gate struct rfs4_client *cp_confirmed; 492*7c478bd9Sstevel@tonic-gate time_t last_access; 493*7c478bd9Sstevel@tonic-gate rfs4_cbinfo_t cbinfo; 494*7c478bd9Sstevel@tonic-gate cred_set_t cr_set; 495*7c478bd9Sstevel@tonic-gate sysid_t sysidt; 496*7c478bd9Sstevel@tonic-gate rfs4_openowner_list_t openownerlist; 497*7c478bd9Sstevel@tonic-gate rfs4_deleg_list_t clientdeleglist; 498*7c478bd9Sstevel@tonic-gate rfs4_ss_pn_t *ss_pn; 499*7c478bd9Sstevel@tonic-gate struct sockaddr_storage cl_addr; 500*7c478bd9Sstevel@tonic-gate rfs4_servinst_t *server_instance; 501*7c478bd9Sstevel@tonic-gate } rfs4_client_t; 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate /* 504*7c478bd9Sstevel@tonic-gate * The openowner contains the client supplied open_owner4 as well as 505*7c478bd9Sstevel@tonic-gate * the matching sequence id and is used to track the client's usage of 506*7c478bd9Sstevel@tonic-gate * the open_owner4. Note that a reply is saved here as well for 507*7c478bd9Sstevel@tonic-gate * processing of retransmissions. 508*7c478bd9Sstevel@tonic-gate * 509*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 510*7c478bd9Sstevel@tonic-gate * client - reference to rfs4_client_t for this openowner 511*7c478bd9Sstevel@tonic-gate * owner - actual client supplied open_owner4 512*7c478bd9Sstevel@tonic-gate * need_confirm - does this openowner need to be OPEN_CONFIRMed 513*7c478bd9Sstevel@tonic-gate * postpone_confirm - set if error received on first use of open_owner 514*7c478bd9Sstevel@tonic-gate * state2confirm - what stateid4 should be used on the OPEN_CONFIRM 515*7c478bd9Sstevel@tonic-gate * open_seqid - what is the next open_seqid expected for this openowner 516*7c478bd9Sstevel@tonic-gate * oo_sw - used to serialize access to the open seqid/reply handling 517*7c478bd9Sstevel@tonic-gate * cr_set - credential used for the OPEN 518*7c478bd9Sstevel@tonic-gate * ownerstateids - root of state struct list associated with this openowner 519*7c478bd9Sstevel@tonic-gate * openownerlist - list of openowners for a client struct 520*7c478bd9Sstevel@tonic-gate * reply_fh - open replay processing needs the filehandle so that it is 521*7c478bd9Sstevel@tonic-gate * able to reset the current filehandle for appropriate compound 522*7c478bd9Sstevel@tonic-gate * processing and reply. 523*7c478bd9Sstevel@tonic-gate * reply - last reply sent in relation to this openowner 524*7c478bd9Sstevel@tonic-gate */ 525*7c478bd9Sstevel@tonic-gate typedef struct rfs4_openowner { 526*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 527*7c478bd9Sstevel@tonic-gate rfs4_client_t *client; 528*7c478bd9Sstevel@tonic-gate open_owner4 owner; 529*7c478bd9Sstevel@tonic-gate unsigned need_confirm:1; 530*7c478bd9Sstevel@tonic-gate unsigned postpone_confirm:1; 531*7c478bd9Sstevel@tonic-gate seqid4 open_seqid; 532*7c478bd9Sstevel@tonic-gate rfs4_state_wait_t oo_sw; 533*7c478bd9Sstevel@tonic-gate cred_set_t cr_set; 534*7c478bd9Sstevel@tonic-gate rfs4_state_list_t ownerstateids; 535*7c478bd9Sstevel@tonic-gate rfs4_openowner_list_t openownerlist; 536*7c478bd9Sstevel@tonic-gate nfs_fh4 reply_fh; 537*7c478bd9Sstevel@tonic-gate nfs_resop4 reply[1]; 538*7c478bd9Sstevel@tonic-gate } rfs4_openowner_t; 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate /* 541*7c478bd9Sstevel@tonic-gate * This state struct represents the association between an openowner 542*7c478bd9Sstevel@tonic-gate * and a file that has been OPENed by that openowner. 543*7c478bd9Sstevel@tonic-gate * 544*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 545*7c478bd9Sstevel@tonic-gate * stateid - server provided stateid 546*7c478bd9Sstevel@tonic-gate * owner - reference back to the openowner for this state 547*7c478bd9Sstevel@tonic-gate * finfo - reference to the open file for this state 548*7c478bd9Sstevel@tonic-gate * share_access - how did the openowner OPEN the file (access) 549*7c478bd9Sstevel@tonic-gate * share_deny - how did the openowner OPEN the file (deny) 550*7c478bd9Sstevel@tonic-gate * closed - has this file been closed? 551*7c478bd9Sstevel@tonic-gate * lockownerlist - root of list of lockowners associated with this state/file 552*7c478bd9Sstevel@tonic-gate * ownerstateids - list of state structs for an openowner 553*7c478bd9Sstevel@tonic-gate */ 554*7c478bd9Sstevel@tonic-gate typedef struct rfs4_state { 555*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 556*7c478bd9Sstevel@tonic-gate stateid_t stateid; 557*7c478bd9Sstevel@tonic-gate rfs4_openowner_t *owner; 558*7c478bd9Sstevel@tonic-gate struct rfs4_file *finfo; 559*7c478bd9Sstevel@tonic-gate uint32_t share_access; 560*7c478bd9Sstevel@tonic-gate uint32_t share_deny; 561*7c478bd9Sstevel@tonic-gate unsigned closed:1; 562*7c478bd9Sstevel@tonic-gate rfs4_lo_state_list_t lockownerlist; 563*7c478bd9Sstevel@tonic-gate rfs4_state_list_t ownerstateids; 564*7c478bd9Sstevel@tonic-gate } rfs4_state_t; 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate /* 567*7c478bd9Sstevel@tonic-gate * Lockowner - track the lockowner and its related info 568*7c478bd9Sstevel@tonic-gate * 569*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 570*7c478bd9Sstevel@tonic-gate * client - reference to the client 571*7c478bd9Sstevel@tonic-gate * owner - lockowner supplied by the client 572*7c478bd9Sstevel@tonic-gate * pid - local identifier used for file locking 573*7c478bd9Sstevel@tonic-gate */ 574*7c478bd9Sstevel@tonic-gate typedef struct rfs4_lockowner { 575*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 576*7c478bd9Sstevel@tonic-gate rfs4_client_t *client; 577*7c478bd9Sstevel@tonic-gate lock_owner4 owner; 578*7c478bd9Sstevel@tonic-gate pid_t pid; 579*7c478bd9Sstevel@tonic-gate } rfs4_lockowner_t; 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * Lockowner_state associated with a state struct and lockowner 583*7c478bd9Sstevel@tonic-gate * 584*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 585*7c478bd9Sstevel@tonic-gate * state - reference back to state struct for open file 586*7c478bd9Sstevel@tonic-gate * lockid - stateid for this lockowner/state 587*7c478bd9Sstevel@tonic-gate * locker - reference to lockowner 588*7c478bd9Sstevel@tonic-gate * seqid - sequence id for this lockowner/state 589*7c478bd9Sstevel@tonic-gate * skip_seqid_check - used on initialization of struct 590*7c478bd9Sstevel@tonic-gate * locks_cleaned - have all locks been released for this lockowner/file? 591*7c478bd9Sstevel@tonic-gate * lock_completed - successful LOCK with lockowner/file? 592*7c478bd9Sstevel@tonic-gate * ls_sw - used to serialize update seqid/reply/stateid handling 593*7c478bd9Sstevel@tonic-gate * lockownerlist - list of lockowners for a state struct 594*7c478bd9Sstevel@tonic-gate * reply - last reply sent in relation to this lockowner/state 595*7c478bd9Sstevel@tonic-gate */ 596*7c478bd9Sstevel@tonic-gate typedef struct rfs4_lo_state { 597*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 598*7c478bd9Sstevel@tonic-gate rfs4_state_t *state; 599*7c478bd9Sstevel@tonic-gate stateid_t lockid; 600*7c478bd9Sstevel@tonic-gate rfs4_lockowner_t *locker; 601*7c478bd9Sstevel@tonic-gate seqid4 seqid; 602*7c478bd9Sstevel@tonic-gate unsigned skip_seqid_check:1; 603*7c478bd9Sstevel@tonic-gate unsigned locks_cleaned:1; 604*7c478bd9Sstevel@tonic-gate unsigned lock_completed:1; 605*7c478bd9Sstevel@tonic-gate rfs4_state_wait_t ls_sw; 606*7c478bd9Sstevel@tonic-gate rfs4_lo_state_list_t lockownerlist; 607*7c478bd9Sstevel@tonic-gate nfs_resop4 reply[1]; 608*7c478bd9Sstevel@tonic-gate } rfs4_lo_state_t; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate /* 611*7c478bd9Sstevel@tonic-gate * Delegation state - per client 612*7c478bd9Sstevel@tonic-gate * 613*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 614*7c478bd9Sstevel@tonic-gate * dtype - type of delegation (NONE, READ, WRITE) 615*7c478bd9Sstevel@tonic-gate * delegid - stateid for this delegation 616*7c478bd9Sstevel@tonic-gate * time_granted - time this delegation was assigned to client 617*7c478bd9Sstevel@tonic-gate * time_recalled - time when the server started recall process 618*7c478bd9Sstevel@tonic-gate * time_revoked - if revoked, time that the revoke occurred 619*7c478bd9Sstevel@tonic-gate * finfo - reference to the file associated with this delegation 620*7c478bd9Sstevel@tonic-gate * client - reference to client for which this delegation is associated 621*7c478bd9Sstevel@tonic-gate * delegationlist - list of delegations for the file (WRITE == 1, READ == ) 622*7c478bd9Sstevel@tonic-gate * clientdeleglist - list of delegations for the client 623*7c478bd9Sstevel@tonic-gate */ 624*7c478bd9Sstevel@tonic-gate typedef struct rfs4_deleg_state { 625*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 626*7c478bd9Sstevel@tonic-gate open_delegation_type4 dtype; 627*7c478bd9Sstevel@tonic-gate stateid_t delegid; 628*7c478bd9Sstevel@tonic-gate time_t time_granted; 629*7c478bd9Sstevel@tonic-gate time_t time_recalled; 630*7c478bd9Sstevel@tonic-gate time_t time_revoked; 631*7c478bd9Sstevel@tonic-gate struct rfs4_file *finfo; 632*7c478bd9Sstevel@tonic-gate rfs4_client_t *client; 633*7c478bd9Sstevel@tonic-gate rfs4_deleg_list_t delegationlist; 634*7c478bd9Sstevel@tonic-gate rfs4_deleg_list_t clientdeleglist; 635*7c478bd9Sstevel@tonic-gate } rfs4_deleg_state_t; 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate /* 638*7c478bd9Sstevel@tonic-gate * Delegation info associated with the file 639*7c478bd9Sstevel@tonic-gate * 640*7c478bd9Sstevel@tonic-gate * dtype - type of delegation for file (NONE, READ, WRITE) 641*7c478bd9Sstevel@tonic-gate * time_returned - time that last delegation was returned for file 642*7c478bd9Sstevel@tonic-gate * time_recalled - time that recall sequence started 643*7c478bd9Sstevel@tonic-gate * time_lastgrant - time that last delegation was provided to a client 644*7c478bd9Sstevel@tonic-gate * time_lastwrite - time of last write to use the delegation stateid 645*7c478bd9Sstevel@tonic-gate * time_rm_delayed - time of last remove/rename which was DELAYed 646*7c478bd9Sstevel@tonic-gate * rdgrants - how many read delegations have been provided for this file 647*7c478bd9Sstevel@tonic-gate * wrgrants - how many write delegations provided (can only be one) 648*7c478bd9Sstevel@tonic-gate * recall_count - how many recall threads are outstanding 649*7c478bd9Sstevel@tonic-gate * recall_lock - lock to protect contents of this struct 650*7c478bd9Sstevel@tonic-gate * recall_cv - condition var for the "parent" thread to wait upon 651*7c478bd9Sstevel@tonic-gate * deleg_change_grant - value for change attribute at time of write grant 652*7c478bd9Sstevel@tonic-gate * deleg_change - most recent value of change obtained from client 653*7c478bd9Sstevel@tonic-gate * deleg_change_ts - time of last deleg_change update 654*7c478bd9Sstevel@tonic-gate * ever_recalled - has this particular delegation ever been recalled? 655*7c478bd9Sstevel@tonic-gate * dont_grant - file deletion is impending, don't grant a delegation 656*7c478bd9Sstevel@tonic-gate * conflicted_client - clientid of the client that caused a CB_RECALL 657*7c478bd9Sstevel@tonic-gate * to occur. This is used for delegation policy (should a delegation 658*7c478bd9Sstevel@tonic-gate * be granted shortly after it has been returned?) 659*7c478bd9Sstevel@tonic-gate */ 660*7c478bd9Sstevel@tonic-gate typedef struct rfs4_dinfo { 661*7c478bd9Sstevel@tonic-gate open_delegation_type4 dtype; 662*7c478bd9Sstevel@tonic-gate time_t time_returned; 663*7c478bd9Sstevel@tonic-gate time_t time_recalled; 664*7c478bd9Sstevel@tonic-gate time_t time_lastgrant; 665*7c478bd9Sstevel@tonic-gate time_t time_lastwrite; 666*7c478bd9Sstevel@tonic-gate time_t time_rm_delayed; 667*7c478bd9Sstevel@tonic-gate uint32_t rdgrants; 668*7c478bd9Sstevel@tonic-gate uint32_t wrgrants; 669*7c478bd9Sstevel@tonic-gate int32_t recall_count; 670*7c478bd9Sstevel@tonic-gate kmutex_t recall_lock[1]; 671*7c478bd9Sstevel@tonic-gate kcondvar_t recall_cv[1]; 672*7c478bd9Sstevel@tonic-gate bool_t ever_recalled; 673*7c478bd9Sstevel@tonic-gate uint32_t hold_grant; 674*7c478bd9Sstevel@tonic-gate clientid4 conflicted_client; 675*7c478bd9Sstevel@tonic-gate } rfs4_dinfo_t; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * File 679*7c478bd9Sstevel@tonic-gate * 680*7c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 681*7c478bd9Sstevel@tonic-gate * vp - vnode for the file that is open or has a delegation 682*7c478bd9Sstevel@tonic-gate * filehandle - the filehandle generated by the server for this file 683*7c478bd9Sstevel@tonic-gate * delegationlist - root of delegation list for this file 684*7c478bd9Sstevel@tonic-gate * dinfo - see struct definition above 685*7c478bd9Sstevel@tonic-gate * share_deny - union of all deny modes on file 686*7c478bd9Sstevel@tonic-gate * share_access - union of all access modes on file 687*7c478bd9Sstevel@tonic-gate * access_read - count of read access 688*7c478bd9Sstevel@tonic-gate * access_write - count of write access 689*7c478bd9Sstevel@tonic-gate * deny_read - count of deny reads 690*7c478bd9Sstevel@tonic-gate * deny_write - count of deny writes 691*7c478bd9Sstevel@tonic-gate * file_rwlock - lock for serializing the removal of a file while 692*7c478bd9Sstevel@tonic-gate * the state structures are active within the server 693*7c478bd9Sstevel@tonic-gate * 694*7c478bd9Sstevel@tonic-gate * The only requirement for locking file_rwlock is that the 695*7c478bd9Sstevel@tonic-gate * caller have a reference to the containing rfs4_file. The dbe 696*7c478bd9Sstevel@tonic-gate * lock may or may not be held for lock/unlock of file_rwlock. 697*7c478bd9Sstevel@tonic-gate * As mentioned above, the file_rwlock is used for serialization 698*7c478bd9Sstevel@tonic-gate * of file removal and more specifically reference to the held 699*7c478bd9Sstevel@tonic-gate * vnode (e.g. vp). 700*7c478bd9Sstevel@tonic-gate */ 701*7c478bd9Sstevel@tonic-gate typedef struct rfs4_file { 702*7c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 703*7c478bd9Sstevel@tonic-gate vnode_t *vp; 704*7c478bd9Sstevel@tonic-gate nfs_fh4 filehandle; 705*7c478bd9Sstevel@tonic-gate rfs4_deleg_list_t delegationlist; 706*7c478bd9Sstevel@tonic-gate rfs4_dinfo_t dinfo[1]; 707*7c478bd9Sstevel@tonic-gate uint32_t share_deny; 708*7c478bd9Sstevel@tonic-gate uint32_t share_access; 709*7c478bd9Sstevel@tonic-gate uint32_t access_read; 710*7c478bd9Sstevel@tonic-gate uint32_t access_write; 711*7c478bd9Sstevel@tonic-gate uint32_t deny_read; 712*7c478bd9Sstevel@tonic-gate uint32_t deny_write; 713*7c478bd9Sstevel@tonic-gate krwlock_t file_rwlock; 714*7c478bd9Sstevel@tonic-gate } rfs4_file_t; 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate extern int rfs4_servinst_debug; 717*7c478bd9Sstevel@tonic-gate extern int rfs4_seen_first_compound; /* set first time we see one */ 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate extern rfs4_servinst_t *rfs4_cur_servinst; /* current server instance */ 720*7c478bd9Sstevel@tonic-gate extern kmutex_t rfs4_servinst_lock; /* protects linked list */ 721*7c478bd9Sstevel@tonic-gate extern void rfs4_servinst_create(int); 722*7c478bd9Sstevel@tonic-gate extern void rfs4_servinst_destroy_all(void); 723*7c478bd9Sstevel@tonic-gate extern void rfs4_servinst_assign(rfs4_client_t *, 724*7c478bd9Sstevel@tonic-gate rfs4_servinst_t *); 725*7c478bd9Sstevel@tonic-gate extern rfs4_servinst_t *rfs4_servinst(rfs4_client_t *); 726*7c478bd9Sstevel@tonic-gate extern int rfs4_clnt_in_grace(rfs4_client_t *); 727*7c478bd9Sstevel@tonic-gate extern int rfs4_servinst_in_grace(rfs4_servinst_t *); 728*7c478bd9Sstevel@tonic-gate extern int rfs4_servinst_grace_new(rfs4_servinst_t *); 729*7c478bd9Sstevel@tonic-gate extern void rfs4_grace_start(rfs4_servinst_t *); 730*7c478bd9Sstevel@tonic-gate extern void rfs4_grace_start_new(void); 731*7c478bd9Sstevel@tonic-gate extern void rfs4_grace_reset_all(void); 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate /* 734*7c478bd9Sstevel@tonic-gate * rfs4_deleg_policy is used to signify the server's global delegation 735*7c478bd9Sstevel@tonic-gate * policy. The default is to NEVER delegate files and the 736*7c478bd9Sstevel@tonic-gate * administrator must configure the server to enable delegations. 737*7c478bd9Sstevel@tonic-gate * 738*7c478bd9Sstevel@tonic-gate * The disable/enable delegation functions are used to eliminate a 739*7c478bd9Sstevel@tonic-gate * race with exclusive creates. 740*7c478bd9Sstevel@tonic-gate */ 741*7c478bd9Sstevel@tonic-gate typedef enum { 742*7c478bd9Sstevel@tonic-gate SRV_NEVER_DELEGATE = 0, 743*7c478bd9Sstevel@tonic-gate SRV_NORMAL_DELEGATE = 1 744*7c478bd9Sstevel@tonic-gate } srv_deleg_policy_t; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate extern srv_deleg_policy_t rfs4_deleg_policy; 747*7c478bd9Sstevel@tonic-gate extern kmutex_t rfs4_deleg_lock; 748*7c478bd9Sstevel@tonic-gate extern void rfs4_disable_delegation(void), rfs4_enable_delegation(void); 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate /* 751*7c478bd9Sstevel@tonic-gate * Request types for delegation. These correspond with 752*7c478bd9Sstevel@tonic-gate * open_delegation_type4 with the addition of a new value, DELEG_ANY, 753*7c478bd9Sstevel@tonic-gate * to reqequest any delegation. 754*7c478bd9Sstevel@tonic-gate */ 755*7c478bd9Sstevel@tonic-gate typedef enum { 756*7c478bd9Sstevel@tonic-gate DELEG_NONE = 0, /* Corresponds to OPEN_DELEG_NONE */ 757*7c478bd9Sstevel@tonic-gate DELEG_READ = 1, /* Corresponds to OPEN_DELEG_READ */ 758*7c478bd9Sstevel@tonic-gate DELEG_WRITE = 2, /* Corresponds to OPEN_DELEG_WRITE */ 759*7c478bd9Sstevel@tonic-gate DELEG_ANY = -1 /* New value to request any delegation type */ 760*7c478bd9Sstevel@tonic-gate } delegreq_t; 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate #define NFS4_DELEG4TYPE2REQTYPE(x) (delegreq_t)(x) 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate /* 765*7c478bd9Sstevel@tonic-gate * Various interfaces to manipulate the state structures introduced 766*7c478bd9Sstevel@tonic-gate * above 767*7c478bd9Sstevel@tonic-gate */ 768*7c478bd9Sstevel@tonic-gate extern kmutex_t rfs4_state_lock; 769*7c478bd9Sstevel@tonic-gate extern void rfs4_clean_state_exi(struct exportinfo *exi); 770*7c478bd9Sstevel@tonic-gate extern void rfs4_free_reply(nfs_resop4 *); 771*7c478bd9Sstevel@tonic-gate extern void rfs4_copy_reply(nfs_resop4 *, nfs_resop4 *); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate /* rfs4_client_t handling */ 774*7c478bd9Sstevel@tonic-gate extern rfs4_client_t *rfs4_findclient(nfs_client_id4 *, 775*7c478bd9Sstevel@tonic-gate bool_t *, rfs4_client_t *); 776*7c478bd9Sstevel@tonic-gate extern rfs4_client_t *rfs4_findclient_by_id(clientid4, bool_t); 777*7c478bd9Sstevel@tonic-gate extern void rfs4_client_rele(rfs4_client_t *); 778*7c478bd9Sstevel@tonic-gate extern void rfs4_client_close(rfs4_client_t *); 779*7c478bd9Sstevel@tonic-gate extern void rfs4_client_state_remove(rfs4_client_t *); 780*7c478bd9Sstevel@tonic-gate extern void rfs4_client_scv_next(rfs4_client_t *); 781*7c478bd9Sstevel@tonic-gate extern void rfs4_update_lease(rfs4_client_t *); 782*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_lease_expired(rfs4_client_t *); 783*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_check_clientid(clientid4 *, int); 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate /* rfs4_openowner_t handling */ 786*7c478bd9Sstevel@tonic-gate extern rfs4_openowner_t *rfs4_findopenowner(open_owner4 *, bool_t *, seqid4); 787*7c478bd9Sstevel@tonic-gate extern void rfs4_update_open_sequence(rfs4_openowner_t *); 788*7c478bd9Sstevel@tonic-gate extern void rfs4_update_open_resp(rfs4_openowner_t *, 789*7c478bd9Sstevel@tonic-gate nfs_resop4 *, nfs_fh4 *); 790*7c478bd9Sstevel@tonic-gate extern void rfs4_openowner_rele(rfs4_openowner_t *); 791*7c478bd9Sstevel@tonic-gate extern void rfs4_free_opens(rfs4_openowner_t *, bool_t, bool_t); 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate /* rfs4_lockowner_t handling */ 794*7c478bd9Sstevel@tonic-gate extern rfs4_lockowner_t *rfs4_findlockowner(lock_owner4 *, bool_t *); 795*7c478bd9Sstevel@tonic-gate extern rfs4_lockowner_t *rfs4_findlockowner_by_pid(pid_t); 796*7c478bd9Sstevel@tonic-gate extern void rfs4_lockowner_rele(rfs4_lockowner_t *); 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* rfs4_state_t handling */ 799*7c478bd9Sstevel@tonic-gate extern rfs4_state_t *rfs4_findstate_by_owner_file(rfs4_openowner_t *, 800*7c478bd9Sstevel@tonic-gate rfs4_file_t *, bool_t *); 801*7c478bd9Sstevel@tonic-gate extern void rfs4_state_rele(rfs4_state_t *); 802*7c478bd9Sstevel@tonic-gate extern void rfs4_state_close(rfs4_state_t *, bool_t, 803*7c478bd9Sstevel@tonic-gate bool_t, cred_t *); 804*7c478bd9Sstevel@tonic-gate extern void rfs4_release_share_lock_state(rfs4_state_t *, 805*7c478bd9Sstevel@tonic-gate cred_t *, bool_t); 806*7c478bd9Sstevel@tonic-gate extern void rfs4_close_all_state(rfs4_file_t *); 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate /* rfs4_lo_state_t handling */ 809*7c478bd9Sstevel@tonic-gate extern rfs4_lo_state_t *rfs4_findlo_state_by_owner(rfs4_lockowner_t *, 810*7c478bd9Sstevel@tonic-gate rfs4_state_t *, bool_t *); 811*7c478bd9Sstevel@tonic-gate extern void rfs4_lo_state_rele(rfs4_lo_state_t *, bool_t); 812*7c478bd9Sstevel@tonic-gate extern void rfs4_update_lock_sequence(rfs4_lo_state_t *); 813*7c478bd9Sstevel@tonic-gate extern void rfs4_update_lock_resp(rfs4_lo_state_t *, 814*7c478bd9Sstevel@tonic-gate nfs_resop4 *); 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate /* rfs4_file_t handling */ 817*7c478bd9Sstevel@tonic-gate extern rfs4_file_t *rfs4_findfile(vnode_t *, nfs_fh4 *, bool_t *); 818*7c478bd9Sstevel@tonic-gate extern rfs4_file_t *rfs4_findfile_withlock(vnode_t *, nfs_fh4 *, 819*7c478bd9Sstevel@tonic-gate bool_t *); 820*7c478bd9Sstevel@tonic-gate extern void rfs4_file_rele(rfs4_file_t *); 821*7c478bd9Sstevel@tonic-gate extern void rfs4_file_rele_withunlock(rfs4_file_t *); 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate /* General collection of "get state" functions */ 824*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_state(stateid4 *, rfs4_state_t **, 825*7c478bd9Sstevel@tonic-gate rfs4_dbsearch_type_t); 826*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_deleg_state(stateid4 *, 827*7c478bd9Sstevel@tonic-gate rfs4_deleg_state_t **); 828*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_lo_state(stateid4 *, rfs4_lo_state_t **, 829*7c478bd9Sstevel@tonic-gate bool_t); 830*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_check_stateid(int, vnode_t *, stateid4 *, 831*7c478bd9Sstevel@tonic-gate bool_t, bool_t *, bool_t); 832*7c478bd9Sstevel@tonic-gate extern int rfs4_check_stateid_seqid(rfs4_state_t *, stateid4 *); 833*7c478bd9Sstevel@tonic-gate extern int rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *, 834*7c478bd9Sstevel@tonic-gate stateid4 *); 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate /* return values for rfs4_check_stateid_seqid() */ 837*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_OKAY 1 838*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_OLD 2 839*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_BAD 3 840*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_EXPIRED 4 841*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_REPLAY 5 842*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_CLOSED 6 843*7c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_UNCONFIRMED 7 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate /* delay() time that server is willing to briefly wait for a delegreturn */ 846*7c478bd9Sstevel@tonic-gate #define NFS4_DELEGATION_CONFLICT_DELAY (hz/10) 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate /* 849*7c478bd9Sstevel@tonic-gate * Interfaces for handling of callback's client handle cache and 850*7c478bd9Sstevel@tonic-gate * callback interfaces themselves. 851*7c478bd9Sstevel@tonic-gate */ 852*7c478bd9Sstevel@tonic-gate extern void rfs4_cbinfo_free(rfs4_cbinfo_t *); 853*7c478bd9Sstevel@tonic-gate extern void rfs4_client_setcb(rfs4_client_t *, cb_client4 *, 854*7c478bd9Sstevel@tonic-gate uint32_t); 855*7c478bd9Sstevel@tonic-gate extern void rfs4_deleg_cb_check(rfs4_client_t *); 856*7c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_vop_getattr(vnode_t *, vattr_t *, int, cred_t *); 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate /* rfs4_deleg_state_t handling and other delegation interfaces */ 859*7c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_finddeleg(rfs4_state_t *, bool_t *); 860*7c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_finddelegstate(stateid_t *); 861*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_check_recall(rfs4_state_t *, uint32_t); 862*7c478bd9Sstevel@tonic-gate extern void rfs4_recall_deleg(rfs4_file_t *, 863*7c478bd9Sstevel@tonic-gate bool_t, rfs4_client_t *); 864*7c478bd9Sstevel@tonic-gate extern int rfs4_get_deleg(rfs4_state_t *, open_delegation_type4, 865*7c478bd9Sstevel@tonic-gate open_delegation_type4 (*policy)(rfs4_state_t *, 866*7c478bd9Sstevel@tonic-gate open_delegation_type4 dtype)); 867*7c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_grant_delegation(delegreq_t, rfs4_state_t *, 868*7c478bd9Sstevel@tonic-gate int *); 869*7c478bd9Sstevel@tonic-gate extern void rfs4_set_deleg_response(rfs4_deleg_state_t *, 870*7c478bd9Sstevel@tonic-gate open_delegation4 *, nfsace4 *, int); 871*7c478bd9Sstevel@tonic-gate extern void rfs4_return_deleg(rfs4_deleg_state_t *, bool_t); 872*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_is_deleg(rfs4_state_t *); 873*7c478bd9Sstevel@tonic-gate extern void rfs4_deleg_state_rele(rfs4_deleg_state_t *); 874*7c478bd9Sstevel@tonic-gate extern bool_t rfs4_check_delegated_byfp(int, rfs4_file_t *, 875*7c478bd9Sstevel@tonic-gate bool_t, bool_t, bool_t, clientid4 *); 876*7c478bd9Sstevel@tonic-gate extern void rfs4_clear_dont_grant(rfs4_file_t *); 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* 879*7c478bd9Sstevel@tonic-gate * nfs4 monitored operations. 880*7c478bd9Sstevel@tonic-gate */ 881*7c478bd9Sstevel@tonic-gate extern int deleg_rdopen(femarg_t *, int, cred_t *); 882*7c478bd9Sstevel@tonic-gate extern int deleg_wropen(femarg_t *, int, cred_t *); 883*7c478bd9Sstevel@tonic-gate extern int deleg_rd_rwlock(femarg_t *, int, caller_context_t *); 884*7c478bd9Sstevel@tonic-gate extern int deleg_wr_rwlock(femarg_t *, int, caller_context_t *); 885*7c478bd9Sstevel@tonic-gate extern int deleg_read(femarg_t *, uio_t *, int, cred_t *, caller_context_t *); 886*7c478bd9Sstevel@tonic-gate extern int deleg_write(femarg_t *, uio_t *, int, cred_t *, caller_context_t *); 887*7c478bd9Sstevel@tonic-gate extern int deleg_setattr(femarg_t *, vattr_t *, int, cred_t *, 888*7c478bd9Sstevel@tonic-gate caller_context_t *); 889*7c478bd9Sstevel@tonic-gate extern int deleg_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *, 890*7c478bd9Sstevel@tonic-gate caller_context_t *); 891*7c478bd9Sstevel@tonic-gate extern int deleg_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *); 892*7c478bd9Sstevel@tonic-gate extern int deleg_vnevent(femarg_t *, vnevent_t); 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate extern void rfs4_mon_hold(void *); 895*7c478bd9Sstevel@tonic-gate extern void rfs4_mon_rele(void *); 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate extern fem_t *deleg_rdops; 898*7c478bd9Sstevel@tonic-gate extern fem_t *deleg_wrops; 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate extern void rfs4_unshare(rfs4_state_t *); 901*7c478bd9Sstevel@tonic-gate extern void rfs4_set_deleg_policy(srv_deleg_policy_t); 902*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 903*7c478bd9Sstevel@tonic-gate #define NFS4_DEBUG(var, args) if (var) cmn_err args 904*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 905*7c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 906*7c478bd9Sstevel@tonic-gate #define NFS4_DEBUG_STACK(var, args) \ 907*7c478bd9Sstevel@tonic-gate if (var) { \ 908*7c478bd9Sstevel@tonic-gate int i, depth; \ 909*7c478bd9Sstevel@tonic-gate pc_t stack[25]; \ 910*7c478bd9Sstevel@tonic-gate char *sym; \ 911*7c478bd9Sstevel@tonic-gate ulong_t off; \ 912*7c478bd9Sstevel@tonic-gate \ 913*7c478bd9Sstevel@tonic-gate cmn_err args; \ 914*7c478bd9Sstevel@tonic-gate depth = getpcstack(stack, 25); \ 915*7c478bd9Sstevel@tonic-gate for (i = 0; i < depth; i++) { \ 916*7c478bd9Sstevel@tonic-gate sym = kobj_getsymname(stack[i], &off); \ 917*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, \ 918*7c478bd9Sstevel@tonic-gate "\t%s+%lx", sym ? sym : "?", off); \ 919*7c478bd9Sstevel@tonic-gate } \ 920*7c478bd9Sstevel@tonic-gate } 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate extern int rfs4_debug; 923*7c478bd9Sstevel@tonic-gate extern int nfs4_client_attr_debug; 924*7c478bd9Sstevel@tonic-gate extern int nfs4_client_state_debug; 925*7c478bd9Sstevel@tonic-gate extern int nfs4_client_shadow_debug; 926*7c478bd9Sstevel@tonic-gate extern int nfs4_client_lock_debug; 927*7c478bd9Sstevel@tonic-gate extern int nfs4_client_lease_debug; 928*7c478bd9Sstevel@tonic-gate extern int nfs4_seqid_sync; 929*7c478bd9Sstevel@tonic-gate extern int nfs4_client_map_debug; 930*7c478bd9Sstevel@tonic-gate extern int nfs4_client_inactive_debug; 931*7c478bd9Sstevel@tonic-gate extern int nfs4_client_recov_debug; 932*7c478bd9Sstevel@tonic-gate extern int nfs4_client_recov_stub_debug; 933*7c478bd9Sstevel@tonic-gate extern int nfs4_client_failover_debug; 934*7c478bd9Sstevel@tonic-gate extern int nfs4_client_call_debug; 935*7c478bd9Sstevel@tonic-gate extern int nfs4_client_foo_debug; 936*7c478bd9Sstevel@tonic-gate extern int nfs4_client_zone_debug; 937*7c478bd9Sstevel@tonic-gate extern int nfs4_lost_rqst_debug; 938*7c478bd9Sstevel@tonic-gate extern int nfs4_open_stream_debug; 939*7c478bd9Sstevel@tonic-gate extern int nfs4_client_open_dg; 940*7c478bd9Sstevel@tonic-gate extern int nfs4_srvmnt_debug; 941*7c478bd9Sstevel@tonic-gate extern int nfs4_utf8_debug; 942*7c478bd9Sstevel@tonic-gate 943*7c478bd9Sstevel@tonic-gate void rfs4_dbe_debug(rfs4_dbe_t *e); 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate #ifdef NFS4_DEBUG_MUTEX 946*7c478bd9Sstevel@tonic-gate void nfs4_debug_mutex_enter(kmutex_t *, char *, int); 947*7c478bd9Sstevel@tonic-gate void nfs4_debug_mutex_exit(kmutex_t *, char *, int); 948*7c478bd9Sstevel@tonic-gate 949*7c478bd9Sstevel@tonic-gate #define mutex_enter(m) nfs4_debug_mutex_enter((m), __FILE__, __LINE__) 950*7c478bd9Sstevel@tonic-gate #define mutex_exit(m) nfs4_debug_mutex_exit((m), __FILE__, __LINE__) 951*7c478bd9Sstevel@tonic-gate #endif /* NFS4_DEBUG_MUTEX */ 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate #else /* ! DEBUG */ 954*7c478bd9Sstevel@tonic-gate #define NFS4_DEBUG(var, args) 955*7c478bd9Sstevel@tonic-gate #define NFS4_DEBUG_STACK(var, args) 956*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate /* 959*7c478bd9Sstevel@tonic-gate * XXX - temporary for testing of volatile fh 960*7c478bd9Sstevel@tonic-gate */ 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate #ifdef VOLATILE_FH_TEST 963*7c478bd9Sstevel@tonic-gate 964*7c478bd9Sstevel@tonic-gate struct nfs_fh4_fmt { 965*7c478bd9Sstevel@tonic-gate fhandle_t fh4_i; 966*7c478bd9Sstevel@tonic-gate uint32_t fh4_flag; 967*7c478bd9Sstevel@tonic-gate uint32_t fh4_volatile_id; 968*7c478bd9Sstevel@tonic-gate }; 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate #else /* VOLATILE_FH_TEST */ 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate struct nfs_fh4_fmt { 973*7c478bd9Sstevel@tonic-gate fhandle_t fh4_i; 974*7c478bd9Sstevel@tonic-gate uint32_t fh4_flag; 975*7c478bd9Sstevel@tonic-gate }; 976*7c478bd9Sstevel@tonic-gate 977*7c478bd9Sstevel@tonic-gate #endif /* VOLATILE_FH_TEST */ 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate #define FH4_NAMEDATTR 1 980*7c478bd9Sstevel@tonic-gate #define FH4_ATTRDIR 2 981*7c478bd9Sstevel@tonic-gate 982*7c478bd9Sstevel@tonic-gate #define fh4_fsid fh4_i.fh_fsid 983*7c478bd9Sstevel@tonic-gate #define fh4_len fh4_i.fh_len /* fid length */ 984*7c478bd9Sstevel@tonic-gate #define fh4_data fh4_i.fh_data /* fid bytes */ 985*7c478bd9Sstevel@tonic-gate #define fh4_xlen fh4_i.fh_xlen 986*7c478bd9Sstevel@tonic-gate #define fh4_xdata fh4_i.fh_xdata 987*7c478bd9Sstevel@tonic-gate typedef struct nfs_fh4_fmt nfs_fh4_fmt_t; 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate #define fh4_to_fmt4(fh4p) ((nfs_fh4_fmt_t *)(fh4p)->nfs_fh4_val) 990*7c478bd9Sstevel@tonic-gate #define get_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) & (flag)) 991*7c478bd9Sstevel@tonic-gate #define set_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) |= (flag)) 992*7c478bd9Sstevel@tonic-gate #define clr_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) &= ~(flag)) 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate #define NFS_FH4_LEN sizeof (nfs_fh4_fmt_t) 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate /* 998*7c478bd9Sstevel@tonic-gate * A few definitions of repeatedly used constructs for nfsv4 999*7c478bd9Sstevel@tonic-gate */ 1000*7c478bd9Sstevel@tonic-gate #define UTF8STRING_FREE(str) \ 1001*7c478bd9Sstevel@tonic-gate kmem_free((str).utf8string_val, (str).utf8string_len); \ 1002*7c478bd9Sstevel@tonic-gate (str).utf8string_val = NULL; \ 1003*7c478bd9Sstevel@tonic-gate (str).utf8string_len = 0; 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate /* 1006*7c478bd9Sstevel@tonic-gate * NFS4_VOLATILE_FH yields non-zero if the filesystem uses non-persistent 1007*7c478bd9Sstevel@tonic-gate * filehandles. 1008*7c478bd9Sstevel@tonic-gate */ 1009*7c478bd9Sstevel@tonic-gate #define NFS4_VOLATILE_FH(mi) \ 1010*7c478bd9Sstevel@tonic-gate ((mi)->mi_fh_expire_type & \ 1011*7c478bd9Sstevel@tonic-gate (FH4_VOLATILE_ANY | FH4_VOL_MIGRATION | FH4_VOL_RENAME)) 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate /* 1014*7c478bd9Sstevel@tonic-gate * NFS_IS_DOTNAME checks if the name given represents a dot or dotdot entry 1015*7c478bd9Sstevel@tonic-gate */ 1016*7c478bd9Sstevel@tonic-gate #define NFS_IS_DOTNAME(name) \ 1017*7c478bd9Sstevel@tonic-gate (((name)[0] == '.') && \ 1018*7c478bd9Sstevel@tonic-gate (((name)[1] == '\0') || (((name)[1] == '.') && ((name)[2] == '\0')))) 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate /* 1021*7c478bd9Sstevel@tonic-gate * Define the number of bits in a bitmap word (uint32) 1022*7c478bd9Sstevel@tonic-gate */ 1023*7c478bd9Sstevel@tonic-gate #define NFS4_BITMAP4_BITSPERWORD (sizeof (uint32_t) * 8) 1024*7c478bd9Sstevel@tonic-gate 1025*7c478bd9Sstevel@tonic-gate /* 1026*7c478bd9Sstevel@tonic-gate * Define the value for the access field of the compound_state structure 1027*7c478bd9Sstevel@tonic-gate * based on the result of nfsauth access checking. 1028*7c478bd9Sstevel@tonic-gate */ 1029*7c478bd9Sstevel@tonic-gate #define CS_ACCESS_OK 0x1 1030*7c478bd9Sstevel@tonic-gate #define CS_ACCESS_DENIED 0x2 1031*7c478bd9Sstevel@tonic-gate #define CS_ACCESS_LIMITED 0x4 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate /* 1034*7c478bd9Sstevel@tonic-gate * compound state in nfsv4 server 1035*7c478bd9Sstevel@tonic-gate */ 1036*7c478bd9Sstevel@tonic-gate struct compound_state { 1037*7c478bd9Sstevel@tonic-gate struct exportinfo *exi; 1038*7c478bd9Sstevel@tonic-gate struct exportinfo *saved_exi; /* export struct for saved_vp */ 1039*7c478bd9Sstevel@tonic-gate cred_t *basecr; /* UNIX cred: only RPC request */ 1040*7c478bd9Sstevel@tonic-gate caddr_t principal; 1041*7c478bd9Sstevel@tonic-gate int nfsflavor; 1042*7c478bd9Sstevel@tonic-gate cred_t *cr; /* UNIX cred: RPC request and */ 1043*7c478bd9Sstevel@tonic-gate /* target export */ 1044*7c478bd9Sstevel@tonic-gate bool_t cont; 1045*7c478bd9Sstevel@tonic-gate uint_t access; /* access perm on vp per request */ 1046*7c478bd9Sstevel@tonic-gate bool_t deleg; /* TRUE if current fh has */ 1047*7c478bd9Sstevel@tonic-gate /* write delegated */ 1048*7c478bd9Sstevel@tonic-gate vnode_t *vp; /* modified by PUTFH, and by ops that */ 1049*7c478bd9Sstevel@tonic-gate /* input to GETFH */ 1050*7c478bd9Sstevel@tonic-gate bool_t mandlock; /* Is mandatory locking in effect */ 1051*7c478bd9Sstevel@tonic-gate /* for vp */ 1052*7c478bd9Sstevel@tonic-gate vnode_t *saved_vp; /* modified by SAVEFH, copied to */ 1053*7c478bd9Sstevel@tonic-gate /* vp by RESTOREFH */ 1054*7c478bd9Sstevel@tonic-gate nfsstat4 *statusp; 1055*7c478bd9Sstevel@tonic-gate nfs_fh4 fh; /* ditto. valid only if vp != NULL */ 1056*7c478bd9Sstevel@tonic-gate nfs_fh4 saved_fh; /* ditto. valid only if */ 1057*7c478bd9Sstevel@tonic-gate /* saved_vp != NULL */ 1058*7c478bd9Sstevel@tonic-gate struct svc_req *req; 1059*7c478bd9Sstevel@tonic-gate char fhbuf[NFS4_FHSIZE]; 1060*7c478bd9Sstevel@tonic-gate }; 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate /* 1063*7c478bd9Sstevel@tonic-gate * Conversion commands for nfsv4 server attr checking 1064*7c478bd9Sstevel@tonic-gate */ 1065*7c478bd9Sstevel@tonic-gate enum nfs4_attr_cmd { 1066*7c478bd9Sstevel@tonic-gate NFS4ATTR_SUPPORTED = 0, /* check which attrs supported */ 1067*7c478bd9Sstevel@tonic-gate NFS4ATTR_GETIT = 1, /* getattr - sys to fattr4 (r) */ 1068*7c478bd9Sstevel@tonic-gate NFS4ATTR_SETIT = 2, /* setattr - fattr4 to sys (w) */ 1069*7c478bd9Sstevel@tonic-gate NFS4ATTR_VERIT = 3, /* verify - fattr4 to sys (r) */ 1070*7c478bd9Sstevel@tonic-gate NFS4ATTR_FREEIT = 4 /* free any alloc'd space for attr */ 1071*7c478bd9Sstevel@tonic-gate }; 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate typedef enum nfs4_attr_cmd nfs4_attr_cmd_t; 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate struct nfs4_svgetit_arg { 1076*7c478bd9Sstevel@tonic-gate nfs4_attr_cmd_t op; /* getit or setit */ 1077*7c478bd9Sstevel@tonic-gate struct compound_state *cs; 1078*7c478bd9Sstevel@tonic-gate struct statvfs64 *sbp; 1079*7c478bd9Sstevel@tonic-gate uint_t flag; /* VOP_GETATTR/VOP_SETATTR flag */ 1080*7c478bd9Sstevel@tonic-gate uint_t xattr; /* object is xattr */ 1081*7c478bd9Sstevel@tonic-gate bool_t rdattr_error_req; /* if readdir & client wants */ 1082*7c478bd9Sstevel@tonic-gate /* rdattr_error */ 1083*7c478bd9Sstevel@tonic-gate nfsstat4 rdattr_error; /* used for per-entry status */ 1084*7c478bd9Sstevel@tonic-gate /* (if rdattr_err) */ 1085*7c478bd9Sstevel@tonic-gate bool_t mntdfid_set; 1086*7c478bd9Sstevel@tonic-gate fattr4_mounted_on_fileid 1087*7c478bd9Sstevel@tonic-gate mounted_on_fileid; 1088*7c478bd9Sstevel@tonic-gate /* readdir op can always return */ 1089*7c478bd9Sstevel@tonic-gate /* d_ino from server fs dirent */ 1090*7c478bd9Sstevel@tonic-gate /* for mounted_on_fileid attr. */ 1091*7c478bd9Sstevel@tonic-gate /* This field holds d_ino so */ 1092*7c478bd9Sstevel@tonic-gate /* srv attr conv code can avoid */ 1093*7c478bd9Sstevel@tonic-gate /* doing an untraverse. */ 1094*7c478bd9Sstevel@tonic-gate vattr_t vap[1]; 1095*7c478bd9Sstevel@tonic-gate }; 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate struct nfs4_ntov_map { 1098*7c478bd9Sstevel@tonic-gate bitmap4 fbit; /* FATTR4_XXX_MASKY */ 1099*7c478bd9Sstevel@tonic-gate uint_t vbit; /* AT_XXX */ 1100*7c478bd9Sstevel@tonic-gate bool_t vfsstat; 1101*7c478bd9Sstevel@tonic-gate bool_t mandatory; /* attribute mandatory to implement? */ 1102*7c478bd9Sstevel@tonic-gate uint_t nval; 1103*7c478bd9Sstevel@tonic-gate int xdr_size; /* Size of XDR'd attr */ 1104*7c478bd9Sstevel@tonic-gate xdrproc_t xfunc; 1105*7c478bd9Sstevel@tonic-gate int (*sv_getit)(nfs4_attr_cmd_t, struct nfs4_svgetit_arg *, 1106*7c478bd9Sstevel@tonic-gate union nfs4_attr_u *); /* subroutine for getting attr. */ 1107*7c478bd9Sstevel@tonic-gate char *prtstr; /* string attr for printing */ 1108*7c478bd9Sstevel@tonic-gate }; 1109*7c478bd9Sstevel@tonic-gate 1110*7c478bd9Sstevel@tonic-gate struct nfs4attr_to_vattr { 1111*7c478bd9Sstevel@tonic-gate vnode_t *vp; 1112*7c478bd9Sstevel@tonic-gate vattr_t *vap; 1113*7c478bd9Sstevel@tonic-gate nfs_fh4 *fhp; 1114*7c478bd9Sstevel@tonic-gate nfsstat4 rdattr_error; 1115*7c478bd9Sstevel@tonic-gate uint32_t flag; 1116*7c478bd9Sstevel@tonic-gate fattr4_change change; 1117*7c478bd9Sstevel@tonic-gate fattr4_fsid srv_fsid; 1118*7c478bd9Sstevel@tonic-gate fattr4_mounted_on_fileid mntd_fid; 1119*7c478bd9Sstevel@tonic-gate }; 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate typedef struct nfs4attr_to_vattr ntov4_t; 1122*7c478bd9Sstevel@tonic-gate 1123*7c478bd9Sstevel@tonic-gate /* 1124*7c478bd9Sstevel@tonic-gate * nfs4attr_to_vattr flags 1125*7c478bd9Sstevel@tonic-gate */ 1126*7c478bd9Sstevel@tonic-gate #define NTOV_FHP_VALID 0x01 1127*7c478bd9Sstevel@tonic-gate #define NTOV_RDATTR_ERROR_VALID 0x02 1128*7c478bd9Sstevel@tonic-gate #define NTOV_CHANGE_VALID 0x04 1129*7c478bd9Sstevel@tonic-gate #define NTOV_SUPP_VALID 0x08 1130*7c478bd9Sstevel@tonic-gate #define NTOV_SRV_FSID_VALID 0x10 1131*7c478bd9Sstevel@tonic-gate #define NTOV_MOUNTED_ON_FILEID_VALID 0x20 1132*7c478bd9Sstevel@tonic-gate 1133*7c478bd9Sstevel@tonic-gate 1134*7c478bd9Sstevel@tonic-gate #define FATTR4_MANDATTR_MASK ( \ 1135*7c478bd9Sstevel@tonic-gate FATTR4_SUPPORTED_ATTRS_MASK | \ 1136*7c478bd9Sstevel@tonic-gate FATTR4_TYPE_MASK | \ 1137*7c478bd9Sstevel@tonic-gate FATTR4_FH_EXPIRE_TYPE_MASK | \ 1138*7c478bd9Sstevel@tonic-gate FATTR4_CHANGE_MASK | \ 1139*7c478bd9Sstevel@tonic-gate FATTR4_SIZE_MASK | \ 1140*7c478bd9Sstevel@tonic-gate FATTR4_LINK_SUPPORT_MASK | \ 1141*7c478bd9Sstevel@tonic-gate FATTR4_SYMLINK_SUPPORT_MASK | \ 1142*7c478bd9Sstevel@tonic-gate FATTR4_NAMED_ATTR_MASK | \ 1143*7c478bd9Sstevel@tonic-gate FATTR4_FSID_MASK | \ 1144*7c478bd9Sstevel@tonic-gate FATTR4_UNIQUE_HANDLES_MASK | \ 1145*7c478bd9Sstevel@tonic-gate FATTR4_LEASE_TIME_MASK | \ 1146*7c478bd9Sstevel@tonic-gate FATTR4_RDATTR_ERROR_MASK | \ 1147*7c478bd9Sstevel@tonic-gate FATTR4_FILEHANDLE_MASK) 1148*7c478bd9Sstevel@tonic-gate 1149*7c478bd9Sstevel@tonic-gate 1150*7c478bd9Sstevel@tonic-gate struct nfs4attr_to_osattr { 1151*7c478bd9Sstevel@tonic-gate void *attrconv_arg; 1152*7c478bd9Sstevel@tonic-gate uint_t mask; 1153*7c478bd9Sstevel@tonic-gate }; 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate struct mntinfo4; 1156*7c478bd9Sstevel@tonic-gate 1157*7c478bd9Sstevel@tonic-gate /* 1158*7c478bd9Sstevel@tonic-gate * lkp4_attr_setup lists the different options for attributes when calling 1159*7c478bd9Sstevel@tonic-gate * nfs4lookup_setup - either no attributes (just lookups - e.g., secinfo), 1160*7c478bd9Sstevel@tonic-gate * one component only (normal component lookup), get attributes for the 1161*7c478bd9Sstevel@tonic-gate * last component (e.g., mount), attributes for each component (e.g., 1162*7c478bd9Sstevel@tonic-gate * failovers later), just the filehandle for the last component (e.g., 1163*7c478bd9Sstevel@tonic-gate * volatile filehandle recovery), or stuff that needs OPENATTR (e.g. 1164*7c478bd9Sstevel@tonic-gate * looking up a named attribute or it's hidden directory). 1165*7c478bd9Sstevel@tonic-gate */ 1166*7c478bd9Sstevel@tonic-gate enum lkp4_attr_setup { 1167*7c478bd9Sstevel@tonic-gate LKP4_NO_ATTRIBUTES = 0, /* no attrs or filehandles */ 1168*7c478bd9Sstevel@tonic-gate LKP4_ALL_ATTRIBUTES = 3, /* multi-comp: attrs for all comps */ 1169*7c478bd9Sstevel@tonic-gate LKP4_LAST_NAMED_ATTR = 5, /* multi-comp: named attr & attrdir */ 1170*7c478bd9Sstevel@tonic-gate LKP4_LAST_ATTRDIR = 6, /* multi-comp: just attrdir */ 1171*7c478bd9Sstevel@tonic-gate LKP4_ALL_ATTR_SECINFO = 7 /* multi-comp: attrs for all comp and */ 1172*7c478bd9Sstevel@tonic-gate /* secinfo for last comp */ 1173*7c478bd9Sstevel@tonic-gate }; 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate /* 1176*7c478bd9Sstevel@tonic-gate * lookup4_param a set of parameters to nfs4lookup_setup - 1177*7c478bd9Sstevel@tonic-gate * used to setup a path lookup compound request. 1178*7c478bd9Sstevel@tonic-gate */ 1179*7c478bd9Sstevel@tonic-gate typedef struct lookup4_param { 1180*7c478bd9Sstevel@tonic-gate enum lkp4_attr_setup l4_getattrs; /* (in) get attrs in the lookup? */ 1181*7c478bd9Sstevel@tonic-gate int header_len; /* (in) num ops before first lookup */ 1182*7c478bd9Sstevel@tonic-gate int trailer_len; /* (in) num ops after last */ 1183*7c478bd9Sstevel@tonic-gate /* Lookup/Getattr */ 1184*7c478bd9Sstevel@tonic-gate bitmap4 ga_bits; /* (in) Which attributes for Getattr */ 1185*7c478bd9Sstevel@tonic-gate COMPOUND4args_clnt *argsp; /* (in/out) args for compound struct */ 1186*7c478bd9Sstevel@tonic-gate COMPOUND4res_clnt *resp; /* (in/out) res for compound struct */ 1187*7c478bd9Sstevel@tonic-gate int arglen; /* (out) argop buffer alloc'd length */ 1188*7c478bd9Sstevel@tonic-gate struct mntinfo4 *mi; 1189*7c478bd9Sstevel@tonic-gate } lookup4_param_t; 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate 1192*7c478bd9Sstevel@tonic-gate #define NFS4_FATTR4_FINISH -1 /* fattr4 index indicating finish */ 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate typedef int (*nfs4attr_to_os_t)(int, union nfs4_attr_u *, 1195*7c478bd9Sstevel@tonic-gate struct nfs4attr_to_osattr *); 1196*7c478bd9Sstevel@tonic-gate 1197*7c478bd9Sstevel@tonic-gate /* 1198*7c478bd9Sstevel@tonic-gate * The nfs4_error_t is the basic structure to return error values 1199*7c478bd9Sstevel@tonic-gate * from rfs4call. It encapsulates the unix errno 1200*7c478bd9Sstevel@tonic-gate * value, the nfsstat4 value and the rpc status value into a single 1201*7c478bd9Sstevel@tonic-gate * structure. 1202*7c478bd9Sstevel@tonic-gate * 1203*7c478bd9Sstevel@tonic-gate * If error is set, then stat is ignored and rpc_status may be 1204*7c478bd9Sstevel@tonic-gate * set if the error occurred as the result of a CLNT_CALL. If 1205*7c478bd9Sstevel@tonic-gate * stat is set, then rpc request succeeded, error and 1206*7c478bd9Sstevel@tonic-gate * rpc_status are set to 0 and stat contains the result of 1207*7c478bd9Sstevel@tonic-gate * operation, NFS4_OK or one of the NFS4ERR_* values. 1208*7c478bd9Sstevel@tonic-gate * 1209*7c478bd9Sstevel@tonic-gate * Functions which want to generate errors independently from 1210*7c478bd9Sstevel@tonic-gate * rfs4call should set error to the desired errno value and 1211*7c478bd9Sstevel@tonic-gate * set stat and rpc_status to 0. nfs4_error_init() is a 1212*7c478bd9Sstevel@tonic-gate * convenient function to do this. 1213*7c478bd9Sstevel@tonic-gate */ 1214*7c478bd9Sstevel@tonic-gate typedef struct { 1215*7c478bd9Sstevel@tonic-gate int error; 1216*7c478bd9Sstevel@tonic-gate nfsstat4 stat; 1217*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_status; 1218*7c478bd9Sstevel@tonic-gate } nfs4_error_t; 1219*7c478bd9Sstevel@tonic-gate 1220*7c478bd9Sstevel@tonic-gate /* 1221*7c478bd9Sstevel@tonic-gate * Shared functions 1222*7c478bd9Sstevel@tonic-gate */ 1223*7c478bd9Sstevel@tonic-gate extern void rfs4_op_readdir(nfs_argop4 *, nfs_resop4 *, 1224*7c478bd9Sstevel@tonic-gate struct svc_req *, struct compound_state *); 1225*7c478bd9Sstevel@tonic-gate extern void nfs_fh4_copy(nfs_fh4 *, nfs_fh4 *); 1226*7c478bd9Sstevel@tonic-gate 1227*7c478bd9Sstevel@tonic-gate extern void nfs4_fattr4_free(fattr4 *); 1228*7c478bd9Sstevel@tonic-gate 1229*7c478bd9Sstevel@tonic-gate extern int nfs4lookup_setup(char *, lookup4_param_t *, int); 1230*7c478bd9Sstevel@tonic-gate extern void nfs4_getattr_otw_norecovery(vnode_t *, 1231*7c478bd9Sstevel@tonic-gate nfs4_ga_res_t *, nfs4_error_t *, cred_t *, int); 1232*7c478bd9Sstevel@tonic-gate extern int nfs4_getattr_otw(vnode_t *, nfs4_ga_res_t *, cred_t *, int); 1233*7c478bd9Sstevel@tonic-gate extern int nfs4cmpfh(const nfs_fh4 *, const nfs_fh4 *); 1234*7c478bd9Sstevel@tonic-gate extern int nfs4cmpfhandle(nfs4_fhandle_t *, nfs4_fhandle_t *); 1235*7c478bd9Sstevel@tonic-gate extern int nfs4getattr(vnode_t *, struct vattr *, cred_t *); 1236*7c478bd9Sstevel@tonic-gate extern int nfs4_waitfor_purge_complete(vnode_t *); 1237*7c478bd9Sstevel@tonic-gate extern int nfs4_validate_caches(vnode_t *, cred_t *); 1238*7c478bd9Sstevel@tonic-gate extern int nfs4init(int, char *); 1239*7c478bd9Sstevel@tonic-gate extern void nfs4fini(void); 1240*7c478bd9Sstevel@tonic-gate extern int nfs4_vfsinit(void); 1241*7c478bd9Sstevel@tonic-gate extern void nfs4_vfsfini(void); 1242*7c478bd9Sstevel@tonic-gate 1243*7c478bd9Sstevel@tonic-gate extern void nfs4_vnops_init(void); 1244*7c478bd9Sstevel@tonic-gate extern void nfs4_vnops_fini(void); 1245*7c478bd9Sstevel@tonic-gate extern void nfs_idmap_init(void); 1246*7c478bd9Sstevel@tonic-gate extern void nfs_idmap_flush(int); 1247*7c478bd9Sstevel@tonic-gate extern void nfs_idmap_fini(void); 1248*7c478bd9Sstevel@tonic-gate extern int nfs4_rnode_init(void); 1249*7c478bd9Sstevel@tonic-gate extern int nfs4_rnode_fini(void); 1250*7c478bd9Sstevel@tonic-gate extern int nfs4_shadow_init(void); 1251*7c478bd9Sstevel@tonic-gate extern int nfs4_shadow_fini(void); 1252*7c478bd9Sstevel@tonic-gate extern int nfs4_acache_init(void); 1253*7c478bd9Sstevel@tonic-gate extern int nfs4_acache_fini(void); 1254*7c478bd9Sstevel@tonic-gate extern int nfs4_subr_init(void); 1255*7c478bd9Sstevel@tonic-gate extern int nfs4_subr_fini(void); 1256*7c478bd9Sstevel@tonic-gate extern void nfs4_acl_init(void); 1257*7c478bd9Sstevel@tonic-gate extern void nfs4_acl_free_cache(vsecattr_t *); 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate extern int geterrno4(nfsstat4); 1260*7c478bd9Sstevel@tonic-gate extern nfsstat4 puterrno4(int); 1261*7c478bd9Sstevel@tonic-gate extern int nfs4_need_to_bump_seqid(COMPOUND4res_clnt *); 1262*7c478bd9Sstevel@tonic-gate extern int nfs4tsize(void); 1263*7c478bd9Sstevel@tonic-gate extern int checkauth4(struct compound_state *, struct svc_req *); 1264*7c478bd9Sstevel@tonic-gate extern nfsstat4 call_checkauth4(struct compound_state *, struct svc_req *); 1265*7c478bd9Sstevel@tonic-gate extern int is_exported_sec(int, struct exportinfo *); 1266*7c478bd9Sstevel@tonic-gate extern void nfs4_vmask_to_nmask(uint_t, bitmap4 *); 1267*7c478bd9Sstevel@tonic-gate extern int nfs_idmap_str_uid(utf8string *u8s, uid_t *, bool_t); 1268*7c478bd9Sstevel@tonic-gate extern int nfs_idmap_str_gid(utf8string *u8s, gid_t *, bool_t); 1269*7c478bd9Sstevel@tonic-gate extern int nfs_idmap_uid_str(uid_t, utf8string *u8s, bool_t); 1270*7c478bd9Sstevel@tonic-gate extern int nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t); 1271*7c478bd9Sstevel@tonic-gate extern int nfs4_time_ntov(nfstime4 *, timestruc_t *); 1272*7c478bd9Sstevel@tonic-gate extern int nfs4_time_vton(timestruc_t *, nfstime4 *); 1273*7c478bd9Sstevel@tonic-gate extern char *utf8_to_str(utf8string *, uint_t *, char *); 1274*7c478bd9Sstevel@tonic-gate extern char *utf8_to_fn(utf8string *, uint_t *, char *); 1275*7c478bd9Sstevel@tonic-gate extern utf8string *str_to_utf8(char *, utf8string *); 1276*7c478bd9Sstevel@tonic-gate extern utf8string *utf8_copy(utf8string *, utf8string *); 1277*7c478bd9Sstevel@tonic-gate extern int utf8_compare(const utf8string *, const utf8string *); 1278*7c478bd9Sstevel@tonic-gate extern int utf8_dir_verify(utf8string *); 1279*7c478bd9Sstevel@tonic-gate extern char *utf8_strchr(utf8string *, const char); 1280*7c478bd9Sstevel@tonic-gate extern int ln_ace4_cmp(nfsace4 *, nfsace4 *, int); 1281*7c478bd9Sstevel@tonic-gate extern int vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int); 1282*7c478bd9Sstevel@tonic-gate extern int vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t, 1283*7c478bd9Sstevel@tonic-gate int, int, int); 1284*7c478bd9Sstevel@tonic-gate extern int vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t, 1285*7c478bd9Sstevel@tonic-gate int, int, int); 1286*7c478bd9Sstevel@tonic-gate extern int vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int, int); 1287*7c478bd9Sstevel@tonic-gate extern void vs_acet_destroy(vsecattr_t *); 1288*7c478bd9Sstevel@tonic-gate extern void vs_ace4_destroy(vsecattr_t *); 1289*7c478bd9Sstevel@tonic-gate extern void vs_aent_destroy(vsecattr_t *); 1290*7c478bd9Sstevel@tonic-gate 1291*7c478bd9Sstevel@tonic-gate extern int stateid4_cmp(stateid4 *, stateid4 *); 1292*7c478bd9Sstevel@tonic-gate 1293*7c478bd9Sstevel@tonic-gate extern vtype_t nf4_to_vt[]; 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate extern struct nfs4_ntov_map nfs4_ntov_map[]; 1296*7c478bd9Sstevel@tonic-gate extern uint_t nfs4_ntov_map_size; 1297*7c478bd9Sstevel@tonic-gate 1298*7c478bd9Sstevel@tonic-gate extern kstat_named_t *rfsproccnt_v4_ptr; 1299*7c478bd9Sstevel@tonic-gate extern struct vfsops *nfs4_vfsops; 1300*7c478bd9Sstevel@tonic-gate extern struct vnodeops *nfs4_vnodeops; 1301*7c478bd9Sstevel@tonic-gate extern const struct fs_operation_def nfs4_vnodeops_template[]; 1302*7c478bd9Sstevel@tonic-gate 1303*7c478bd9Sstevel@tonic-gate extern uint_t nfs4_tsize(struct knetconfig *); 1304*7c478bd9Sstevel@tonic-gate extern uint_t rfs4_tsize(struct svc_req *); 1305*7c478bd9Sstevel@tonic-gate 1306*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1307*7c478bd9Sstevel@tonic-gate extern int rfs4_do_pre_op_attr; 1308*7c478bd9Sstevel@tonic-gate extern int rfs4_do_post_op_attr; 1309*7c478bd9Sstevel@tonic-gate #endif 1310*7c478bd9Sstevel@tonic-gate 1311*7c478bd9Sstevel@tonic-gate extern stateid4 clnt_special0; 1312*7c478bd9Sstevel@tonic-gate extern stateid4 clnt_special1; 1313*7c478bd9Sstevel@tonic-gate #define CLNT_ISSPECIAL(id) (stateid4_cmp(id, &clnt_special0) || \ 1314*7c478bd9Sstevel@tonic-gate stateid4_cmp(id, &clnt_special1)) 1315*7c478bd9Sstevel@tonic-gate 1316*7c478bd9Sstevel@tonic-gate /* 1317*7c478bd9Sstevel@tonic-gate * The NFS Version 4 service procedures. 1318*7c478bd9Sstevel@tonic-gate */ 1319*7c478bd9Sstevel@tonic-gate 1320*7c478bd9Sstevel@tonic-gate extern void rfs4_compound(COMPOUND4args *, COMPOUND4res *, 1321*7c478bd9Sstevel@tonic-gate struct exportinfo *, struct svc_req *, cred_t *); 1322*7c478bd9Sstevel@tonic-gate extern void rfs4_compound_free(COMPOUND4res *); 1323*7c478bd9Sstevel@tonic-gate extern void rfs4_compound_flagproc(COMPOUND4args *, int *); 1324*7c478bd9Sstevel@tonic-gate 1325*7c478bd9Sstevel@tonic-gate extern int rfs4_srvrinit(void); 1326*7c478bd9Sstevel@tonic-gate extern void rfs4_srvrfini(void); 1327*7c478bd9Sstevel@tonic-gate extern void rfs4_state_init(void); 1328*7c478bd9Sstevel@tonic-gate extern void rfs4_state_fini(void); 1329*7c478bd9Sstevel@tonic-gate 1330*7c478bd9Sstevel@tonic-gate #endif 1331*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 1332*7c478bd9Sstevel@tonic-gate } 1333*7c478bd9Sstevel@tonic-gate #endif 1334*7c478bd9Sstevel@tonic-gate 1335*7c478bd9Sstevel@tonic-gate #endif /* _NFS4_H */ 1336