17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 527242a7cSthurlow * Common Development and Distribution License (the "License"). 627242a7cSthurlow * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21bbe876c0SMarcel Telka 227c478bd9Sstevel@tonic-gate /* 23*0dfe541eSEvan Layton * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*0dfe541eSEvan Layton * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 26bbe876c0SMarcel Telka 2715721462SDaniil Lunev /* 28*0dfe541eSEvan Layton * Copyright 2018 Nexenta Systems, Inc. 29*0dfe541eSEvan Layton * Copyright 2019 Nexenta by DDN, Inc. 3015721462SDaniil Lunev */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #ifndef _NFS4_H 337c478bd9Sstevel@tonic-gate #define _NFS4_H 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <sys/types.h> 367c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 377c478bd9Sstevel@tonic-gate #include <sys/fem.h> 387c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 397c478bd9Sstevel@tonic-gate #include <nfs/nfs.h> 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #ifdef _KERNEL 427c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 43*0dfe541eSEvan Layton #include <nfs/nfs4_drc.h> 44cee86682Scalum #include <sys/nvpair.h> 457c478bd9Sstevel@tonic-gate #else 467c478bd9Sstevel@tonic-gate #include <rpcsvc/nfs4_prot.h> 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate #include <nfs/nfs4_attr.h> 497c478bd9Sstevel@tonic-gate #include <sys/acl.h> 50d216dff5SRobert Mastors #include <sys/list.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #ifdef __cplusplus 537c478bd9Sstevel@tonic-gate extern "C" { 547c478bd9Sstevel@tonic-gate #endif 557c478bd9Sstevel@tonic-gate 56bbe876c0SMarcel Telka #define NFS4_MAX_SECOID4 65536 577c478bd9Sstevel@tonic-gate #define NFS4_MAX_UTF8STRING 65536 58bbe876c0SMarcel Telka #define NFS4_MAX_LINKTEXT4 65536 597c478bd9Sstevel@tonic-gate #define NFS4_MAX_PATHNAME4 65536 60bbe876c0SMarcel Telka 61bbe876c0SMarcel Telka struct nfs_fsl_info { 62bbe876c0SMarcel Telka uint_t netbuf_len; 63bbe876c0SMarcel Telka uint_t netnm_len; 64bbe876c0SMarcel Telka uint_t knconf_len; 65bbe876c0SMarcel Telka char *netname; 66bbe876c0SMarcel Telka struct netbuf *addr; 67bbe876c0SMarcel Telka struct knetconfig *knconf; 68bbe876c0SMarcel Telka }; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #ifdef _KERNEL 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate typedef struct nfs4_fhandle { 737c478bd9Sstevel@tonic-gate int fh_len; 747c478bd9Sstevel@tonic-gate char fh_buf[NFS4_FHSIZE]; 757c478bd9Sstevel@tonic-gate } nfs4_fhandle_t; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate #define NFS4_MINORVERSION 0 787c478bd9Sstevel@tonic-gate #define CB4_MINORVERSION 0 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * Set the fattr4_change variable using a time struct. Note that change 827c478bd9Sstevel@tonic-gate * is 64 bits, but timestruc_t is 128 bits in a 64-bit kernel. 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate #define NFS4_SET_FATTR4_CHANGE(change, ts) \ 857c478bd9Sstevel@tonic-gate { \ 867c478bd9Sstevel@tonic-gate change = (ts).tv_sec; \ 877c478bd9Sstevel@tonic-gate change <<= 32; \ 887c478bd9Sstevel@tonic-gate change |= (uint32_t)((ts).tv_nsec); \ 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate /* 927c478bd9Sstevel@tonic-gate * Server lease period. Value is in seconds; Also used for grace period 937c478bd9Sstevel@tonic-gate */ 947c478bd9Sstevel@tonic-gate extern time_t rfs4_lease_time; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* 977c478bd9Sstevel@tonic-gate * This set of typedefs and interfaces represent the core or base set 987c478bd9Sstevel@tonic-gate * of functionality that backs the NFSv4 server's state related data 997c478bd9Sstevel@tonic-gate * structures. Since the NFSv4 server needs inter-RPC state to be 1007c478bd9Sstevel@tonic-gate * available that is unrelated to the filesystem (in other words, 1017c478bd9Sstevel@tonic-gate * soft-state), this functionality is needed to maintain that and is 1027c478bd9Sstevel@tonic-gate * written to be somewhat flexible to adapt to the various types of 1037c478bd9Sstevel@tonic-gate * data structures contained within the server. 1047c478bd9Sstevel@tonic-gate * 1057c478bd9Sstevel@tonic-gate * The basic structure at this level is that the server maintains a 1067c478bd9Sstevel@tonic-gate * global "database" which consists of a set of tables. Each table 1077c478bd9Sstevel@tonic-gate * contains a set of like data structures. Each table is indexed by 1087c478bd9Sstevel@tonic-gate * at least one hash function and in most cases two hashes. Each 1097c478bd9Sstevel@tonic-gate * table's characteristics is set when it is created at run-time via 1107c478bd9Sstevel@tonic-gate * rfs4_table_create(). All table creation and related functions are 1117c478bd9Sstevel@tonic-gate * located in nfs4_state.c. The generic database functionality is 1127c478bd9Sstevel@tonic-gate * located in nfs4_db.c. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate typedef struct rfs4_dbe rfs4_dbe_t; /* basic opaque db entry */ 1167c478bd9Sstevel@tonic-gate typedef struct rfs4_table rfs4_table_t; /* basic table type */ 1177c478bd9Sstevel@tonic-gate typedef struct rfs4_index rfs4_index_t; /* index */ 1187c478bd9Sstevel@tonic-gate typedef struct rfs4_database rfs4_database_t; /* and database */ 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate typedef struct { /* opaque entry type for later use */ 1217c478bd9Sstevel@tonic-gate rfs4_dbe_t *dbe; 1227c478bd9Sstevel@tonic-gate } *rfs4_entry_t; 1237c478bd9Sstevel@tonic-gate 124*0dfe541eSEvan Layton /* 125*0dfe541eSEvan Layton * NFSv4 server state databases 126*0dfe541eSEvan Layton * 127*0dfe541eSEvan Layton * Initialized when the module is loaded and used by NFSv4 state tables. 128*0dfe541eSEvan Layton * These kmem_cache free pools are used globally, the NFSv4 state tables 129*0dfe541eSEvan Layton * which make use of these kmem_cache free pools are per zone. 130*0dfe541eSEvan Layton */ 131*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_client_mem_cache; 132*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_clntIP_mem_cache; 133*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_openown_mem_cache; 134*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_openstID_mem_cache; 135*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_lockstID_mem_cache; 136*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_lockown_mem_cache; 137*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_file_mem_cache; 138*0dfe541eSEvan Layton extern kmem_cache_t *rfs4_delegstID_mem_cache; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* database, table, index creation entry points */ 1417c478bd9Sstevel@tonic-gate extern rfs4_database_t *rfs4_database_create(uint32_t); 1427c478bd9Sstevel@tonic-gate extern void rfs4_database_shutdown(rfs4_database_t *); 1437c478bd9Sstevel@tonic-gate extern void rfs4_database_destroy(rfs4_database_t *); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate extern void rfs4_database_destroy(rfs4_database_t *); 1467c478bd9Sstevel@tonic-gate 147*0dfe541eSEvan Layton extern kmem_cache_t *nfs4_init_mem_cache(char *, uint32_t, uint32_t, 148*0dfe541eSEvan Layton uint32_t); 1497c478bd9Sstevel@tonic-gate extern rfs4_table_t *rfs4_table_create(rfs4_database_t *, char *, 1507c478bd9Sstevel@tonic-gate time_t, uint32_t, 1517c478bd9Sstevel@tonic-gate bool_t (*create)(rfs4_entry_t, void *), 1527c478bd9Sstevel@tonic-gate void (*destroy)(rfs4_entry_t), 1537c478bd9Sstevel@tonic-gate bool_t (*expiry)(rfs4_entry_t), 1547c478bd9Sstevel@tonic-gate uint32_t, uint32_t, uint32_t, id_t); 1557c478bd9Sstevel@tonic-gate extern void rfs4_table_destroy(rfs4_database_t *, rfs4_table_t *); 1567c478bd9Sstevel@tonic-gate extern rfs4_index_t *rfs4_index_create(rfs4_table_t *, char *, 1577c478bd9Sstevel@tonic-gate uint32_t (*hash)(void *), 1587c478bd9Sstevel@tonic-gate bool_t (compare)(rfs4_entry_t, void *), 1597c478bd9Sstevel@tonic-gate void *(*mkkey)(rfs4_entry_t), bool_t); 1607c478bd9Sstevel@tonic-gate extern void rfs4_index_destroy(rfs4_index_t *); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* Type used to direct rfs4_dbsearch() in what types of records to inspect */ 1637c478bd9Sstevel@tonic-gate typedef enum {RFS4_DBS_VALID, RFS4_DBS_INVALID} rfs4_dbsearch_type_t; 1647c478bd9Sstevel@tonic-gate /* search and db entry manipulation entry points */ 1657c478bd9Sstevel@tonic-gate extern rfs4_entry_t rfs4_dbsearch(rfs4_index_t *, void *, 1667c478bd9Sstevel@tonic-gate bool_t *, void *, rfs4_dbsearch_type_t); 1677c478bd9Sstevel@tonic-gate extern void rfs4_dbe_lock(rfs4_dbe_t *); 1687c478bd9Sstevel@tonic-gate extern void rfs4_dbe_unlock(rfs4_dbe_t *); 1697c478bd9Sstevel@tonic-gate extern clock_t rfs4_dbe_twait(rfs4_dbe_t *, clock_t); 1707c478bd9Sstevel@tonic-gate extern void rfs4_dbe_cv_broadcast(rfs4_dbe_t *); 1717c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hold(rfs4_dbe_t *); 1727c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hold_nolock(rfs4_dbe_t *); 1737c478bd9Sstevel@tonic-gate extern void rfs4_dbe_rele_nolock(rfs4_dbe_t *); 1747c478bd9Sstevel@tonic-gate extern void rfs4_dbe_rele(rfs4_dbe_t *); 1757c478bd9Sstevel@tonic-gate extern uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *); 1767c478bd9Sstevel@tonic-gate extern id_t rfs4_dbe_getid(rfs4_dbe_t *); 1777c478bd9Sstevel@tonic-gate extern void rfs4_dbe_invalidate(rfs4_dbe_t *); 1787c478bd9Sstevel@tonic-gate extern bool_t rfs4_dbe_is_invalid(rfs4_dbe_t *); 1797c478bd9Sstevel@tonic-gate extern time_t rfs4_dbe_get_timerele(rfs4_dbe_t *); 1807c478bd9Sstevel@tonic-gate extern void rfs4_dbe_hide(rfs4_dbe_t *); 1817c478bd9Sstevel@tonic-gate extern void rfs4_dbe_unhide(rfs4_dbe_t *); 1827c478bd9Sstevel@tonic-gate #ifdef DEBUG 1837c478bd9Sstevel@tonic-gate extern bool_t rfs4_dbe_islocked(rfs4_dbe_t *); 1847c478bd9Sstevel@tonic-gate #endif 1857c478bd9Sstevel@tonic-gate extern void rfs4_dbe_walk(rfs4_table_t *, 1867c478bd9Sstevel@tonic-gate void (*callout)(rfs4_entry_t, void *), void *); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* 1897c478bd9Sstevel@tonic-gate * Minimal server stable storage. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * Currently the NFSv4 server will only save the client 1927c478bd9Sstevel@tonic-gate * ID (the long version) so that it will be able to 1937c478bd9Sstevel@tonic-gate * grant possible reclaim requests during the infamous 1947c478bd9Sstevel@tonic-gate * grace_period. 1957c478bd9Sstevel@tonic-gate */ 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate #define RFS4_SS_DIRSIZE 64 * 1024 1987c478bd9Sstevel@tonic-gate #define NFS4_SS_VERSION 1 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* handy pathname structure */ 2017c478bd9Sstevel@tonic-gate typedef struct ss_pn { 2027c478bd9Sstevel@tonic-gate char *leaf; 2037c478bd9Sstevel@tonic-gate char pn[MAXPATHLEN]; 2047c478bd9Sstevel@tonic-gate } rfs4_ss_pn_t; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * The server will build this link list on startup. It represents the 2087c478bd9Sstevel@tonic-gate * clients that have had valid state on the server in a prior instance. 2097c478bd9Sstevel@tonic-gate * 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate typedef struct rfs4_oldstate { 21252deb364SToomas Soome struct rfs4_oldstate *next; 21352deb364SToomas Soome struct rfs4_oldstate *prev; 2147c478bd9Sstevel@tonic-gate rfs4_ss_pn_t *ss_pn; 2157c478bd9Sstevel@tonic-gate nfs_client_id4 cl_id4; 2167c478bd9Sstevel@tonic-gate } rfs4_oldstate_t; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* 2197c478bd9Sstevel@tonic-gate * This union is used to overlay the server's internal treatment of 2207c478bd9Sstevel@tonic-gate * the protocols stateid4 datatype. Therefore, "bits" must not exceed 2217c478bd9Sstevel@tonic-gate * the size of stateid4 and more importantly should match the size of 2227c478bd9Sstevel@tonic-gate * stateid4. The chgseq field must the first entry since it overlays 2237c478bd9Sstevel@tonic-gate * stateid4.seqid. 2247c478bd9Sstevel@tonic-gate */ 2257c478bd9Sstevel@tonic-gate typedef union { 2267c478bd9Sstevel@tonic-gate stateid4 stateid; 2277c478bd9Sstevel@tonic-gate struct { 2287c478bd9Sstevel@tonic-gate uint32_t chgseq; /* State changes / protocol's seqid */ 2297c478bd9Sstevel@tonic-gate uint32_t boottime; /* boot time */ 2307c478bd9Sstevel@tonic-gate uint32_t type:2; /* stateid_type_t as define below */ 2317c478bd9Sstevel@tonic-gate uint32_t clnodeid:8; /* cluster server nodeid */ 2327c478bd9Sstevel@tonic-gate uint32_t ident:22; /* 2^22-1 openowner x fhs */ 2337c478bd9Sstevel@tonic-gate pid_t pid; /* pid of corresponding lock owner */ 2347c478bd9Sstevel@tonic-gate } bits; 2357c478bd9Sstevel@tonic-gate } stateid_t; 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * Note that the way the type field above is defined, this enum must 2387c478bd9Sstevel@tonic-gate * not have more than 4 members. 2397c478bd9Sstevel@tonic-gate */ 2407c478bd9Sstevel@tonic-gate typedef enum {OPENID, LOCKID, DELEGID} stateid_type_t; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate /* 2447c478bd9Sstevel@tonic-gate * Set of RPC credentials used for a particular operation. 2457c478bd9Sstevel@tonic-gate * Used for operations like SETCLIENTID_CONFIRM where the 2467c478bd9Sstevel@tonic-gate * credentials needs to match those used at SETCLIENTID. 2477c478bd9Sstevel@tonic-gate */ 2487c478bd9Sstevel@tonic-gate typedef void *cred_set_t; /* For now XXX */ 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* 2517c478bd9Sstevel@tonic-gate * "wait" struct for use in the open open and lock owner state 2527c478bd9Sstevel@tonic-gate * structures to provide serialization between server threads that are 2537c478bd9Sstevel@tonic-gate * handling requests for the same open owner or lock stateid. This 2547c478bd9Sstevel@tonic-gate * way only one thread will be updating things like sequence ids, 2557c478bd9Sstevel@tonic-gate * replay cache and stateid at a time. 2567c478bd9Sstevel@tonic-gate */ 2577c478bd9Sstevel@tonic-gate typedef struct rfs4_state_wait { 2587c478bd9Sstevel@tonic-gate uint32_t sw_active; 2597c478bd9Sstevel@tonic-gate uint32_t sw_wait_count; 2607c478bd9Sstevel@tonic-gate kmutex_t sw_cv_lock[1]; 2617c478bd9Sstevel@tonic-gate kcondvar_t sw_cv[1]; 2627c478bd9Sstevel@tonic-gate } rfs4_state_wait_t; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate extern void rfs4_sw_enter(rfs4_state_wait_t *); 2657c478bd9Sstevel@tonic-gate extern void rfs4_sw_exit(rfs4_state_wait_t *); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * This enum and the following rfs4_cbinfo_t struct are used to 2697c478bd9Sstevel@tonic-gate * maintain information about the callback path used from the server 2707c478bd9Sstevel@tonic-gate * to client for operations like CB_GETATTR and CB_RECALL. The 2717c478bd9Sstevel@tonic-gate * rfs4_cbinfo_t struct is meant to be encompassed in the client 2727c478bd9Sstevel@tonic-gate * struct and managed within that structure's locking scheme. 2737c478bd9Sstevel@tonic-gate * 2747c478bd9Sstevel@tonic-gate * The various states of the callback path are used by the server to 2757c478bd9Sstevel@tonic-gate * determine if delegations should initially be provided to a client 2767c478bd9Sstevel@tonic-gate * and then later on if connectivity has been lost and delegations 2777c478bd9Sstevel@tonic-gate * should be revoked. 2787c478bd9Sstevel@tonic-gate */ 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate /* 2817c478bd9Sstevel@tonic-gate * CB_NOCHANGE - Special value used for interfaces within the delegation 2827c478bd9Sstevel@tonic-gate * code to signify that "no change" has occurred to the 2837c478bd9Sstevel@tonic-gate * callback path 2847c478bd9Sstevel@tonic-gate * CB_UNINIT - No callback info provided by the client 2857c478bd9Sstevel@tonic-gate * CB_NONE - Callback info provided but CB_NULL call 2867c478bd9Sstevel@tonic-gate * has yet to be attempted 2877c478bd9Sstevel@tonic-gate * CB_OK - Callback path tested with CB_NULL with success 2887c478bd9Sstevel@tonic-gate * CB_INPROG - Callback path currently being tested with CB_NULL 2897c478bd9Sstevel@tonic-gate * CB_FAILED - Callback path was == CB_OK but has failed 2907c478bd9Sstevel@tonic-gate * with timeout/rpc error 2917c478bd9Sstevel@tonic-gate * CB_BAD - Callback info provided but CB_NULL failed 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate typedef enum { 2947c478bd9Sstevel@tonic-gate CB_NOCHANGE = 0, 2957c478bd9Sstevel@tonic-gate CB_UNINIT = 1, 2967c478bd9Sstevel@tonic-gate CB_NONE = 2, 2977c478bd9Sstevel@tonic-gate CB_OK = 3, 2987c478bd9Sstevel@tonic-gate CB_INPROG = 4, 2997c478bd9Sstevel@tonic-gate CB_FAILED = 5, 3007c478bd9Sstevel@tonic-gate CB_BAD = 6 3017c478bd9Sstevel@tonic-gate } rfs4_cbstate_t; 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate #define RFS4_CBCH_MAX 10 /* size callback client handle cache */ 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * Callback info for a client. 3067c478bd9Sstevel@tonic-gate * Client only provides: cb_client4 and cb_ident 3077c478bd9Sstevel@tonic-gate * The rest of the information is used to track callback path status 3087c478bd9Sstevel@tonic-gate * and usage. 3097c478bd9Sstevel@tonic-gate * 3107c478bd9Sstevel@tonic-gate * cb_state - used as comments for the rfs4_cbstate_t enum indicate 3117c478bd9Sstevel@tonic-gate * cb_notified_of_cb_path_down - if the callback path was once CB_OK and 3127c478bd9Sstevel@tonic-gate * has hence CB_FAILED, the client needs to be notified via RENEW. 3137c478bd9Sstevel@tonic-gate * cb_timefailed - current time when cb_state transitioned from 3147c478bd9Sstevel@tonic-gate * CB_OK -> CB_FAILED. Meant for observability. When did that happen? 3157c478bd9Sstevel@tonic-gate * cb_chc_free/cb_chc - cache of client handles for the callback path 3167c478bd9Sstevel@tonic-gate * cb_ident - SETCLIENTID provided callback_ident value 3177c478bd9Sstevel@tonic-gate * callback - SETCLIENTID provided cb_client4 value 3187c478bd9Sstevel@tonic-gate * cb_refcnt - current number of users of this structure's content 3197c478bd9Sstevel@tonic-gate * protected by cb_lock 3207c478bd9Sstevel@tonic-gate * cb_badbehavior - how many times did a client do something we didn't like? 3217c478bd9Sstevel@tonic-gate * cb_lock - lock for contents of cbinfo 3227c478bd9Sstevel@tonic-gate * cb_cv - used to allow threads to wait on CB_NULL completion 3237c478bd9Sstevel@tonic-gate * cb_nullcaller - is there a thread currently taking care of 3247c478bd9Sstevel@tonic-gate * new callback information? 3257c478bd9Sstevel@tonic-gate * cb_cv_nullcaller - used by the thread doing CB_NULL to wait on 3267c478bd9Sstevel@tonic-gate * threads that may be using client handles of the current 3277c478bd9Sstevel@tonic-gate * client handle cache. 3287c478bd9Sstevel@tonic-gate * newer - new callback info provided by a client and awaiting 3297c478bd9Sstevel@tonic-gate * CB_NULL testing and move to regular cbinfo. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate typedef struct { 3327c478bd9Sstevel@tonic-gate rfs4_cbstate_t cb_state; 3337c478bd9Sstevel@tonic-gate unsigned cb_notified_of_cb_path_down:1; 3347c478bd9Sstevel@tonic-gate time_t cb_timefailed; 3357c478bd9Sstevel@tonic-gate int cb_chc_free; 3367c478bd9Sstevel@tonic-gate CLIENT *cb_chc[RFS4_CBCH_MAX]; 3377c478bd9Sstevel@tonic-gate uint32_t cb_ident; 3387c478bd9Sstevel@tonic-gate cb_client4 cb_callback; 3397c478bd9Sstevel@tonic-gate uint32_t cb_refcnt; 3407c478bd9Sstevel@tonic-gate uint32_t cb_badbehavior; 3417c478bd9Sstevel@tonic-gate kmutex_t cb_lock[1]; 3427c478bd9Sstevel@tonic-gate kcondvar_t cb_cv[1]; 3437c478bd9Sstevel@tonic-gate bool_t cb_nullcaller; 3447c478bd9Sstevel@tonic-gate kcondvar_t cb_cv_nullcaller[1]; 3457c478bd9Sstevel@tonic-gate struct { 3467c478bd9Sstevel@tonic-gate bool_t cb_new; 3477c478bd9Sstevel@tonic-gate bool_t cb_confirmed; 3487c478bd9Sstevel@tonic-gate uint32_t cb_ident; 3497c478bd9Sstevel@tonic-gate cb_client4 cb_callback; 3507c478bd9Sstevel@tonic-gate } cb_newer; 3517c478bd9Sstevel@tonic-gate } rfs4_cbinfo_t; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * A server instance. We can associate sets of clients - via a pointer in 3557c478bd9Sstevel@tonic-gate * rfs4_client_t - with a given server instance, allowing us to treat clients 3567c478bd9Sstevel@tonic-gate * in the set differently to clients in other sets. 3577c478bd9Sstevel@tonic-gate * 3587c478bd9Sstevel@tonic-gate * Currently used only for Sun Cluster HA-NFS support, to group clients 3597c478bd9Sstevel@tonic-gate * on NFS resource failover so each set of clients gets its own dedicated 360cee86682Scalum * grace period and distributed stable storage data. 3617c478bd9Sstevel@tonic-gate */ 3627c478bd9Sstevel@tonic-gate typedef struct rfs4_servinst { 363cee86682Scalum int dss_npaths; 3647c478bd9Sstevel@tonic-gate krwlock_t rwlock; 365cee86682Scalum krwlock_t oldstate_lock; 3667c478bd9Sstevel@tonic-gate time_t start_time; 3677c478bd9Sstevel@tonic-gate time_t grace_period; 368cee86682Scalum rfs4_oldstate_t *oldstate; 369cee86682Scalum struct rfs4_dss_path **dss_paths; 3707c478bd9Sstevel@tonic-gate struct rfs4_servinst *next; 3717c478bd9Sstevel@tonic-gate struct rfs4_servinst *prev; 3727c478bd9Sstevel@tonic-gate } rfs4_servinst_t; 3737c478bd9Sstevel@tonic-gate 374cee86682Scalum /* 375cee86682Scalum * DSS: distributed stable storage 376cee86682Scalum */ 377cee86682Scalum 378cee86682Scalum typedef struct rfs4_dss_path { 379cee86682Scalum struct rfs4_dss_path *next; /* for insque/remque */ 380cee86682Scalum struct rfs4_dss_path *prev; /* for insque/remque */ 381cee86682Scalum char *path; 382cee86682Scalum struct rfs4_servinst *sip; 383cee86682Scalum unsigned index; /* offset in servinst's array */ 384cee86682Scalum } rfs4_dss_path_t; 385cee86682Scalum 386cee86682Scalum /* array of paths passed-in from nfsd command-line; stored in nvlist */ 387cee86682Scalum char **rfs4_dss_newpaths; 388cee86682Scalum uint_t rfs4_dss_numnewpaths; 389cee86682Scalum 390cee86682Scalum /* nvlists of all DSS paths: current, and before last warmstart */ 391cee86682Scalum nvlist_t *rfs4_dss_paths, *rfs4_dss_oldpaths; 392cee86682Scalum 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * The server maintains a set of state on a per client basis that 3957c478bd9Sstevel@tonic-gate * matches that of the protocol requirements. A client's state is 3967c478bd9Sstevel@tonic-gate * rooted with the rfs4_client_t struct of which there is one per 3977c478bd9Sstevel@tonic-gate * client and is created when SETCLIENTID/SETCLIENTID_CONFIRM are 3987c478bd9Sstevel@tonic-gate * received. From there, the server then creates rfs4_openowner_t 3997c478bd9Sstevel@tonic-gate * structs for each new open owner from that client and are initiated 4007c478bd9Sstevel@tonic-gate * at OPEN/OPEN_CONFIRM (when the open owner is new to the server). 4017c478bd9Sstevel@tonic-gate * At OPEN, at least two other structures are created, and potentially a 4027c478bd9Sstevel@tonic-gate * third. rfs4_state_t is created to track the association between an 4037c478bd9Sstevel@tonic-gate * open owner and a particular file. An rfs4_file_t struct may be 4047c478bd9Sstevel@tonic-gate * created (if the file is not already open) at OPEN as well. The 4057c478bd9Sstevel@tonic-gate * rfs4_file_t struct is the only one that is per server and not per 4067c478bd9Sstevel@tonic-gate * client. The rfs4_deleg_state_t struct is created in the 4077c478bd9Sstevel@tonic-gate * instance that the server is going to provide a delegation for the 4087c478bd9Sstevel@tonic-gate * file being OPENed. Finally, the rfs4_lockowner_t is created at the 4097c478bd9Sstevel@tonic-gate * first use of a lock owner at the server and is a result of the LOCK 4107c478bd9Sstevel@tonic-gate * operation. The rfs4_lo_state_t struct is then created to represent 4117c478bd9Sstevel@tonic-gate * the relation between the lock owner and the file. 4127c478bd9Sstevel@tonic-gate * 4137c478bd9Sstevel@tonic-gate */ 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * The following ascii art represents each of these data structs and 4167c478bd9Sstevel@tonic-gate * their references to each other. Note: "<-(x)->" represents the 417cfe63ebfSMarcel Telka * doubly link lists (list_t). 4187c478bd9Sstevel@tonic-gate * 4197c478bd9Sstevel@tonic-gate * ____________________ 4207c478bd9Sstevel@tonic-gate * | | 4217c478bd9Sstevel@tonic-gate * | rfs4_client_t | 422cfe63ebfSMarcel Telka * ->| (1) |<- 4237c478bd9Sstevel@tonic-gate * / |____________________| \ 4247c478bd9Sstevel@tonic-gate * / ^ \ 4257c478bd9Sstevel@tonic-gate * / | \ 4267c478bd9Sstevel@tonic-gate * ____________________ ____________________ ____________________ 4277c478bd9Sstevel@tonic-gate * | | | | | | 4287c478bd9Sstevel@tonic-gate * | rfs4_lockowner_t | | rfs4_openowner_t | | rfs4_deleg_state_t | 4297c478bd9Sstevel@tonic-gate * | | | (3) <-(1)-> | | <-(2)-> | 4307c478bd9Sstevel@tonic-gate * |____________________| |____________________| |____________________| 4317c478bd9Sstevel@tonic-gate * ^ ^ | 4327c478bd9Sstevel@tonic-gate * | | V 4337c478bd9Sstevel@tonic-gate * ____________________ ____________________ ____________________ 4347c478bd9Sstevel@tonic-gate * | | | | | | 4357c478bd9Sstevel@tonic-gate * | rfs4_lo_state_t |->| rfs4_state_t |->| rfs4_file_t | 436cfe63ebfSMarcel Telka * | <-(4)-> | | (4) <-(3)-> | | (2) | 4377c478bd9Sstevel@tonic-gate * |____________________| |____________________| |____________________| 4387c478bd9Sstevel@tonic-gate */ 4397c478bd9Sstevel@tonic-gate /* 4407c478bd9Sstevel@tonic-gate * Each of these data types are kept in a separate rfs4_table_t and is 4417c478bd9Sstevel@tonic-gate * actually encapsulated within a rfs4_dbe_t struct. The various 4427c478bd9Sstevel@tonic-gate * tables and their construction is done in nfs4_state.c but 4437c478bd9Sstevel@tonic-gate * documented here to completeness. 4447c478bd9Sstevel@tonic-gate * 4457c478bd9Sstevel@tonic-gate * Table Data struct stored Indexed by 4467c478bd9Sstevel@tonic-gate * ----- ------------------ ---------- 4477c478bd9Sstevel@tonic-gate * rfs4_client_tab rfs4_client_t nfs_client_id4 4487c478bd9Sstevel@tonic-gate * clientid4 4497c478bd9Sstevel@tonic-gate * 4507c478bd9Sstevel@tonic-gate * rfs4_openowner_tab rfs4_openowner_t open_owner4 4517c478bd9Sstevel@tonic-gate * 4527c478bd9Sstevel@tonic-gate * rfs4_state_tab rfs4_state_t open_owner4 | file 4537c478bd9Sstevel@tonic-gate * stateid 4547c478bd9Sstevel@tonic-gate * 4557c478bd9Sstevel@tonic-gate * rfs4_lo_state_tab rfs4_lo_state_t lockowner | stateid 4567c478bd9Sstevel@tonic-gate * lock_stateid 4577c478bd9Sstevel@tonic-gate * 4587c478bd9Sstevel@tonic-gate * rfs4_lockowner_tab rfs4_lockowner_t lockowner 4597c478bd9Sstevel@tonic-gate * pid 4607c478bd9Sstevel@tonic-gate * 4617c478bd9Sstevel@tonic-gate * rfs4_file_tab rfs4_file_t filehandle 4627c478bd9Sstevel@tonic-gate * 4637c478bd9Sstevel@tonic-gate * rfs4_deleg_state_tab rfs4_deleg_state_t clientid4 | file 4647c478bd9Sstevel@tonic-gate * deleg_stateid 4657c478bd9Sstevel@tonic-gate */ 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate /* 4687c478bd9Sstevel@tonic-gate * The client struct, it is the root of all state for a particular 4697c478bd9Sstevel@tonic-gate * client. The client is identified by the nfs_client_id4 via 4707c478bd9Sstevel@tonic-gate * SETCLIENTID and the server returns the clientid4 as short hand reference 4717c478bd9Sstevel@tonic-gate */ 4727c478bd9Sstevel@tonic-gate /* 4737c478bd9Sstevel@tonic-gate * Client struct - as mentioned above it is the root of all state for 4747c478bd9Sstevel@tonic-gate * a single client as identified by the client supplied nfs_client_id4 4757c478bd9Sstevel@tonic-gate * 4767c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 4777c478bd9Sstevel@tonic-gate * clientid - server assigned short hand reference to client 4787c478bd9Sstevel@tonic-gate * nfs_client - client supplied identifier for itself 4797c478bd9Sstevel@tonic-gate * confirm_verf - the value provided to the client for SETCLIENTID_CONFIRM 4807c478bd9Sstevel@tonic-gate * need_confirm - does this client need to be SETCLIENTID_CONFIRMed? 4817c478bd9Sstevel@tonic-gate * 4827c478bd9Sstevel@tonic-gate * unlksys_completed - has an F_UNLKSYS been done for this client which 4837c478bd9Sstevel@tonic-gate * says that the use of cleanlocks() on individual files 4847c478bd9Sstevel@tonic-gate * is not required? 4857c478bd9Sstevel@tonic-gate * can_reclaim - indicates if client is allowed to reclaim after server 48652deb364SToomas Soome * start-up (client had previous state at server) 4877c478bd9Sstevel@tonic-gate * ss_remove - indicates that the rfs4_client_destroy function should 48852deb364SToomas Soome * clean up stable storage file. 4897c478bd9Sstevel@tonic-gate * forced_expire - set if the sysadmin has used clear_locks for this client. 4902f172c55SRobert Thurlow * no_referrals - set if the client is Solaris and pre-dates referrals 4917c478bd9Sstevel@tonic-gate * deleg_revoked - how many delegations have been revoked for this client? 4927c478bd9Sstevel@tonic-gate * 4937c478bd9Sstevel@tonic-gate * cp_confirmed - this refers to a confirmed client struct that has 4947c478bd9Sstevel@tonic-gate * the same nfs_client_id4 as this client struct. When/if this client 4957c478bd9Sstevel@tonic-gate * struct is confirmed via SETCLINETID_CONFIRM, the previously 4967c478bd9Sstevel@tonic-gate * confirmed client struct will be "closed" and hence this reference. 4977c478bd9Sstevel@tonic-gate * 4987c478bd9Sstevel@tonic-gate * last_access - used to determine if the client has let its lease expire 4997c478bd9Sstevel@tonic-gate * cbinfo - struct containing all callback related information 5007c478bd9Sstevel@tonic-gate * cr_set - credentials used for the SETCLIENTID/SETCLIENTID_CONFIRM pair 5017c478bd9Sstevel@tonic-gate * sysid - the lock manager sysid allocated for this client's file locks 5027c478bd9Sstevel@tonic-gate * openownerlist - root of openowners list associated with this client 5037c478bd9Sstevel@tonic-gate * ss_pn - Pathname to the stable storage file. 5047c478bd9Sstevel@tonic-gate * cl_addr - Clients network address. 5057c478bd9Sstevel@tonic-gate * server_instance - pointer to the currently associated server instance 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate typedef struct rfs4_client { 508d216dff5SRobert Mastors rfs4_dbe_t *rc_dbe; 509d216dff5SRobert Mastors clientid4 rc_clientid; 510d216dff5SRobert Mastors nfs_client_id4 rc_nfs_client; 511d216dff5SRobert Mastors verifier4 rc_confirm_verf; 512d216dff5SRobert Mastors unsigned rc_need_confirm:1; 513d216dff5SRobert Mastors unsigned rc_unlksys_completed:1; 514d216dff5SRobert Mastors unsigned rc_can_reclaim:1; 51552deb364SToomas Soome unsigned rc_ss_remove:1; 516d216dff5SRobert Mastors unsigned rc_forced_expire:1; 517d216dff5SRobert Mastors uint_t rc_deleg_revoked; 518d216dff5SRobert Mastors struct rfs4_client *rc_cp_confirmed; 519d216dff5SRobert Mastors time_t rc_last_access; 520d216dff5SRobert Mastors rfs4_cbinfo_t rc_cbinfo; 521d216dff5SRobert Mastors cred_set_t rc_cr_set; 522d216dff5SRobert Mastors sysid_t rc_sysidt; 523d216dff5SRobert Mastors list_t rc_openownerlist; 524d216dff5SRobert Mastors rfs4_ss_pn_t *rc_ss_pn; 525d216dff5SRobert Mastors struct sockaddr_storage rc_addr; 526d216dff5SRobert Mastors rfs4_servinst_t *rc_server_instance; 5277c478bd9Sstevel@tonic-gate } rfs4_client_t; 5287c478bd9Sstevel@tonic-gate 5292f172c55SRobert Thurlow /* 5302f172c55SRobert Thurlow * ClntIP struct - holds the diagnosis about whether the client 5312f172c55SRobert Thurlow * cannot support referrals. Set to true for old Solaris clients. 5322f172c55SRobert Thurlow */ 5332f172c55SRobert Thurlow 5342f172c55SRobert Thurlow typedef struct rfs4_clntip { 5352f172c55SRobert Thurlow rfs4_dbe_t *ri_dbe; 5362f172c55SRobert Thurlow struct sockaddr_storage ri_addr; 5372f172c55SRobert Thurlow unsigned ri_no_referrals:1; 5382f172c55SRobert Thurlow } rfs4_clntip_t; 5392f172c55SRobert Thurlow 5407c478bd9Sstevel@tonic-gate /* 5417c478bd9Sstevel@tonic-gate * The openowner contains the client supplied open_owner4 as well as 5427c478bd9Sstevel@tonic-gate * the matching sequence id and is used to track the client's usage of 5437c478bd9Sstevel@tonic-gate * the open_owner4. Note that a reply is saved here as well for 5447c478bd9Sstevel@tonic-gate * processing of retransmissions. 5457c478bd9Sstevel@tonic-gate * 5467c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 5477c478bd9Sstevel@tonic-gate * client - reference to rfs4_client_t for this openowner 5487c478bd9Sstevel@tonic-gate * owner - actual client supplied open_owner4 5497c478bd9Sstevel@tonic-gate * need_confirm - does this openowner need to be OPEN_CONFIRMed 5507c478bd9Sstevel@tonic-gate * postpone_confirm - set if error received on first use of open_owner 5517c478bd9Sstevel@tonic-gate * state2confirm - what stateid4 should be used on the OPEN_CONFIRM 5527c478bd9Sstevel@tonic-gate * open_seqid - what is the next open_seqid expected for this openowner 5537c478bd9Sstevel@tonic-gate * oo_sw - used to serialize access to the open seqid/reply handling 5547c478bd9Sstevel@tonic-gate * cr_set - credential used for the OPEN 555d216dff5SRobert Mastors * statelist - root of state struct list associated with this openowner 556d216dff5SRobert Mastors * node - node for client struct list of openowners 5577c478bd9Sstevel@tonic-gate * reply_fh - open replay processing needs the filehandle so that it is 5587c478bd9Sstevel@tonic-gate * able to reset the current filehandle for appropriate compound 5597c478bd9Sstevel@tonic-gate * processing and reply. 5607c478bd9Sstevel@tonic-gate * reply - last reply sent in relation to this openowner 5617c478bd9Sstevel@tonic-gate */ 5627c478bd9Sstevel@tonic-gate typedef struct rfs4_openowner { 563d216dff5SRobert Mastors rfs4_dbe_t *ro_dbe; 564d216dff5SRobert Mastors rfs4_client_t *ro_client; 565d216dff5SRobert Mastors open_owner4 ro_owner; 566d216dff5SRobert Mastors unsigned ro_need_confirm:1; 567d216dff5SRobert Mastors unsigned ro_postpone_confirm:1; 568d216dff5SRobert Mastors seqid4 ro_open_seqid; 569d216dff5SRobert Mastors rfs4_state_wait_t ro_sw; 570d216dff5SRobert Mastors cred_set_t ro_cr_set; 571d216dff5SRobert Mastors list_t ro_statelist; 572d216dff5SRobert Mastors list_node_t ro_node; 573d216dff5SRobert Mastors nfs_fh4 ro_reply_fh; 574d216dff5SRobert Mastors nfs_resop4 ro_reply; 5757c478bd9Sstevel@tonic-gate } rfs4_openowner_t; 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * This state struct represents the association between an openowner 5797c478bd9Sstevel@tonic-gate * and a file that has been OPENed by that openowner. 5807c478bd9Sstevel@tonic-gate * 5817c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 5827c478bd9Sstevel@tonic-gate * stateid - server provided stateid 5837c478bd9Sstevel@tonic-gate * owner - reference back to the openowner for this state 5847c478bd9Sstevel@tonic-gate * finfo - reference to the open file for this state 58550956b22SJames Wahlig * open_access - how did the openowner OPEN the file (access) 58650956b22SJames Wahlig * open_deny - how did the openowner OPEN the file (deny) 58750956b22SJames Wahlig * share_access - what share reservation is on the file (access) 58850956b22SJames Wahlig * share_deny - what share reservation is on the file (deny) 5897c478bd9Sstevel@tonic-gate * closed - has this file been closed? 590d216dff5SRobert Mastors * lostatelist - root of list of lo_state associated with this state/file 591d216dff5SRobert Mastors * node - node for state struct list of states 5927c478bd9Sstevel@tonic-gate */ 5937c478bd9Sstevel@tonic-gate typedef struct rfs4_state { 594d216dff5SRobert Mastors rfs4_dbe_t *rs_dbe; 595d216dff5SRobert Mastors stateid_t rs_stateid; 596d216dff5SRobert Mastors rfs4_openowner_t *rs_owner; 597d216dff5SRobert Mastors struct rfs4_file *rs_finfo; 59850956b22SJames Wahlig uint32_t rs_open_access; 59950956b22SJames Wahlig uint32_t rs_open_deny; 600d216dff5SRobert Mastors uint32_t rs_share_access; 601d216dff5SRobert Mastors uint32_t rs_share_deny; 602d216dff5SRobert Mastors unsigned rs_closed:1; 603d216dff5SRobert Mastors list_t rs_lostatelist; 604d216dff5SRobert Mastors list_node_t rs_node; 6057c478bd9Sstevel@tonic-gate } rfs4_state_t; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate /* 6087c478bd9Sstevel@tonic-gate * Lockowner - track the lockowner and its related info 6097c478bd9Sstevel@tonic-gate * 6107c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 6117c478bd9Sstevel@tonic-gate * client - reference to the client 6127c478bd9Sstevel@tonic-gate * owner - lockowner supplied by the client 6137c478bd9Sstevel@tonic-gate * pid - local identifier used for file locking 6147c478bd9Sstevel@tonic-gate */ 6157c478bd9Sstevel@tonic-gate typedef struct rfs4_lockowner { 616d216dff5SRobert Mastors rfs4_dbe_t *rl_dbe; 617d216dff5SRobert Mastors rfs4_client_t *rl_client; 618d216dff5SRobert Mastors lock_owner4 rl_owner; 619d216dff5SRobert Mastors pid_t rl_pid; 6207c478bd9Sstevel@tonic-gate } rfs4_lockowner_t; 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* 6237c478bd9Sstevel@tonic-gate * Lockowner_state associated with a state struct and lockowner 6247c478bd9Sstevel@tonic-gate * 6257c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 6267c478bd9Sstevel@tonic-gate * state - reference back to state struct for open file 6277c478bd9Sstevel@tonic-gate * lockid - stateid for this lockowner/state 6287c478bd9Sstevel@tonic-gate * locker - reference to lockowner 6297c478bd9Sstevel@tonic-gate * seqid - sequence id for this lockowner/state 6307c478bd9Sstevel@tonic-gate * skip_seqid_check - used on initialization of struct 6317c478bd9Sstevel@tonic-gate * locks_cleaned - have all locks been released for this lockowner/file? 6327c478bd9Sstevel@tonic-gate * lock_completed - successful LOCK with lockowner/file? 6337c478bd9Sstevel@tonic-gate * ls_sw - used to serialize update seqid/reply/stateid handling 634d216dff5SRobert Mastors * node - node for state struct list of lo_states 6357c478bd9Sstevel@tonic-gate * reply - last reply sent in relation to this lockowner/state 6367c478bd9Sstevel@tonic-gate */ 6377c478bd9Sstevel@tonic-gate typedef struct rfs4_lo_state { 638d216dff5SRobert Mastors rfs4_dbe_t *rls_dbe; 639d216dff5SRobert Mastors rfs4_state_t *rls_state; 640d216dff5SRobert Mastors stateid_t rls_lockid; 641d216dff5SRobert Mastors rfs4_lockowner_t *rls_locker; 642d216dff5SRobert Mastors seqid4 rls_seqid; 643d216dff5SRobert Mastors unsigned rls_skip_seqid_check:1; 644d216dff5SRobert Mastors unsigned rls_locks_cleaned:1; 645d216dff5SRobert Mastors unsigned rls_lock_completed:1; 646d216dff5SRobert Mastors rfs4_state_wait_t rls_sw; 647d216dff5SRobert Mastors list_node_t rls_node; 648d216dff5SRobert Mastors nfs_resop4 rls_reply; 6497c478bd9Sstevel@tonic-gate } rfs4_lo_state_t; 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * Delegation state - per client 6537c478bd9Sstevel@tonic-gate * 6547c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 6557c478bd9Sstevel@tonic-gate * dtype - type of delegation (NONE, READ, WRITE) 6567c478bd9Sstevel@tonic-gate * delegid - stateid for this delegation 6577c478bd9Sstevel@tonic-gate * time_granted - time this delegation was assigned to client 6587c478bd9Sstevel@tonic-gate * time_recalled - time when the server started recall process 6597c478bd9Sstevel@tonic-gate * time_revoked - if revoked, time that the revoke occurred 6607c478bd9Sstevel@tonic-gate * finfo - reference to the file associated with this delegation 6617c478bd9Sstevel@tonic-gate * client - reference to client for which this delegation is associated 662d216dff5SRobert Mastors * node - list of delegations for the file (WRITE == 1, READ == ) 6637c478bd9Sstevel@tonic-gate */ 6647c478bd9Sstevel@tonic-gate typedef struct rfs4_deleg_state { 665d216dff5SRobert Mastors rfs4_dbe_t *rds_dbe; 666d216dff5SRobert Mastors open_delegation_type4 rds_dtype; 667d216dff5SRobert Mastors stateid_t rds_delegid; 668d216dff5SRobert Mastors time_t rds_time_granted; 669d216dff5SRobert Mastors time_t rds_time_recalled; 670d216dff5SRobert Mastors time_t rds_time_revoked; 671d216dff5SRobert Mastors struct rfs4_file *rds_finfo; 672d216dff5SRobert Mastors rfs4_client_t *rds_client; 673d216dff5SRobert Mastors list_node_t rds_node; 6747c478bd9Sstevel@tonic-gate } rfs4_deleg_state_t; 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate /* 6777c478bd9Sstevel@tonic-gate * Delegation info associated with the file 6787c478bd9Sstevel@tonic-gate * 6797c478bd9Sstevel@tonic-gate * dtype - type of delegation for file (NONE, READ, WRITE) 6807c478bd9Sstevel@tonic-gate * time_returned - time that last delegation was returned for file 6817c478bd9Sstevel@tonic-gate * time_recalled - time that recall sequence started 6827c478bd9Sstevel@tonic-gate * time_lastgrant - time that last delegation was provided to a client 6837c478bd9Sstevel@tonic-gate * time_lastwrite - time of last write to use the delegation stateid 6847c478bd9Sstevel@tonic-gate * time_rm_delayed - time of last remove/rename which was DELAYed 6857c478bd9Sstevel@tonic-gate * rdgrants - how many read delegations have been provided for this file 6867c478bd9Sstevel@tonic-gate * wrgrants - how many write delegations provided (can only be one) 6877c478bd9Sstevel@tonic-gate * recall_count - how many recall threads are outstanding 6887c478bd9Sstevel@tonic-gate * recall_lock - lock to protect contents of this struct 6897c478bd9Sstevel@tonic-gate * recall_cv - condition var for the "parent" thread to wait upon 6907c478bd9Sstevel@tonic-gate * deleg_change_grant - value for change attribute at time of write grant 6917c478bd9Sstevel@tonic-gate * deleg_change - most recent value of change obtained from client 6927c478bd9Sstevel@tonic-gate * deleg_change_ts - time of last deleg_change update 6937c478bd9Sstevel@tonic-gate * ever_recalled - has this particular delegation ever been recalled? 6947c478bd9Sstevel@tonic-gate * dont_grant - file deletion is impending, don't grant a delegation 6957c478bd9Sstevel@tonic-gate * conflicted_client - clientid of the client that caused a CB_RECALL 6967c478bd9Sstevel@tonic-gate * to occur. This is used for delegation policy (should a delegation 6977c478bd9Sstevel@tonic-gate * be granted shortly after it has been returned?) 6987c478bd9Sstevel@tonic-gate */ 6997c478bd9Sstevel@tonic-gate typedef struct rfs4_dinfo { 700d216dff5SRobert Mastors open_delegation_type4 rd_dtype; 701d216dff5SRobert Mastors time_t rd_time_returned; 702d216dff5SRobert Mastors time_t rd_time_recalled; 703d216dff5SRobert Mastors time_t rd_time_lastgrant; 704d216dff5SRobert Mastors time_t rd_time_lastwrite; 705d216dff5SRobert Mastors time_t rd_time_rm_delayed; 706d216dff5SRobert Mastors uint32_t rd_rdgrants; 707d216dff5SRobert Mastors uint32_t rd_wrgrants; 708d216dff5SRobert Mastors int32_t rd_recall_count; 709d216dff5SRobert Mastors kmutex_t rd_recall_lock[1]; 710d216dff5SRobert Mastors kcondvar_t rd_recall_cv[1]; 711d216dff5SRobert Mastors bool_t rd_ever_recalled; 712d216dff5SRobert Mastors uint32_t rd_hold_grant; 713d216dff5SRobert Mastors clientid4 rd_conflicted_client; 7147c478bd9Sstevel@tonic-gate } rfs4_dinfo_t; 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate /* 7177c478bd9Sstevel@tonic-gate * File 7187c478bd9Sstevel@tonic-gate * 7197c478bd9Sstevel@tonic-gate * dbe - encapsulation struct 7207c478bd9Sstevel@tonic-gate * vp - vnode for the file that is open or has a delegation 7217c478bd9Sstevel@tonic-gate * filehandle - the filehandle generated by the server for this file 722d216dff5SRobert Mastors * delegstatelist - root of delegation list for this file 7237c478bd9Sstevel@tonic-gate * dinfo - see struct definition above 7247c478bd9Sstevel@tonic-gate * share_deny - union of all deny modes on file 7257c478bd9Sstevel@tonic-gate * share_access - union of all access modes on file 7267c478bd9Sstevel@tonic-gate * access_read - count of read access 7277c478bd9Sstevel@tonic-gate * access_write - count of write access 7287c478bd9Sstevel@tonic-gate * deny_read - count of deny reads 7297c478bd9Sstevel@tonic-gate * deny_write - count of deny writes 7307c478bd9Sstevel@tonic-gate * file_rwlock - lock for serializing the removal of a file while 7317c478bd9Sstevel@tonic-gate * the state structures are active within the server 7327c478bd9Sstevel@tonic-gate * 73352deb364SToomas Soome * The only requirement for locking file_rwlock is that the 73452deb364SToomas Soome * caller have a reference to the containing rfs4_file. The dbe 73552deb364SToomas Soome * lock may or may not be held for lock/unlock of file_rwlock. 73652deb364SToomas Soome * As mentioned above, the file_rwlock is used for serialization 73752deb364SToomas Soome * of file removal and more specifically reference to the held 73852deb364SToomas Soome * vnode (e.g. vp). 7397c478bd9Sstevel@tonic-gate */ 7407c478bd9Sstevel@tonic-gate typedef struct rfs4_file { 741d216dff5SRobert Mastors rfs4_dbe_t *rf_dbe; 742d216dff5SRobert Mastors vnode_t *rf_vp; 743d216dff5SRobert Mastors nfs_fh4 rf_filehandle; 744d216dff5SRobert Mastors list_t rf_delegstatelist; 745d216dff5SRobert Mastors rfs4_dinfo_t rf_dinfo; 746d216dff5SRobert Mastors uint32_t rf_share_deny; 747d216dff5SRobert Mastors uint32_t rf_share_access; 748d216dff5SRobert Mastors uint32_t rf_access_read; 749d216dff5SRobert Mastors uint32_t rf_access_write; 750d216dff5SRobert Mastors uint32_t rf_deny_read; 751d216dff5SRobert Mastors uint32_t rf_deny_write; 752d216dff5SRobert Mastors krwlock_t rf_file_rwlock; 7537c478bd9Sstevel@tonic-gate } rfs4_file_t; 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate /* 756*0dfe541eSEvan Layton * nfs4_deleg_policy is used to signify the server's global delegation 7577c478bd9Sstevel@tonic-gate * policy. The default is to NEVER delegate files and the 7587c478bd9Sstevel@tonic-gate * administrator must configure the server to enable delegations. 7597c478bd9Sstevel@tonic-gate * 7607c478bd9Sstevel@tonic-gate * The disable/enable delegation functions are used to eliminate a 7617c478bd9Sstevel@tonic-gate * race with exclusive creates. 7627c478bd9Sstevel@tonic-gate */ 7637c478bd9Sstevel@tonic-gate typedef enum { 7647c478bd9Sstevel@tonic-gate SRV_NEVER_DELEGATE = 0, 7657c478bd9Sstevel@tonic-gate SRV_NORMAL_DELEGATE = 1 7667c478bd9Sstevel@tonic-gate } srv_deleg_policy_t; 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate extern void rfs4_disable_delegation(void), rfs4_enable_delegation(void); 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate /* 7717c478bd9Sstevel@tonic-gate * Request types for delegation. These correspond with 7727c478bd9Sstevel@tonic-gate * open_delegation_type4 with the addition of a new value, DELEG_ANY, 7737c478bd9Sstevel@tonic-gate * to reqequest any delegation. 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate typedef enum { 7767c478bd9Sstevel@tonic-gate DELEG_NONE = 0, /* Corresponds to OPEN_DELEG_NONE */ 7777c478bd9Sstevel@tonic-gate DELEG_READ = 1, /* Corresponds to OPEN_DELEG_READ */ 7787c478bd9Sstevel@tonic-gate DELEG_WRITE = 2, /* Corresponds to OPEN_DELEG_WRITE */ 7797c478bd9Sstevel@tonic-gate DELEG_ANY = -1 /* New value to request any delegation type */ 7807c478bd9Sstevel@tonic-gate } delegreq_t; 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate #define NFS4_DELEG4TYPE2REQTYPE(x) (delegreq_t)(x) 7837c478bd9Sstevel@tonic-gate 784*0dfe541eSEvan Layton /* 785*0dfe541eSEvan Layton * Zone global variables of NFSv4 server 786*0dfe541eSEvan Layton */ 787*0dfe541eSEvan Layton typedef struct nfs4_srv { 788*0dfe541eSEvan Layton /* Unique write verifier */ 789*0dfe541eSEvan Layton verifier4 write4verf; 790*0dfe541eSEvan Layton /* Delegation lock */ 791*0dfe541eSEvan Layton kmutex_t deleg_lock; 792*0dfe541eSEvan Layton /* Used to serialize create/destroy of nfs4_server_state database */ 793*0dfe541eSEvan Layton kmutex_t state_lock; 794*0dfe541eSEvan Layton rfs4_database_t *nfs4_server_state; 795*0dfe541eSEvan Layton /* Used to manage access to server instance linked list */ 796*0dfe541eSEvan Layton kmutex_t servinst_lock; 797*0dfe541eSEvan Layton rfs4_servinst_t *nfs4_cur_servinst; 798*0dfe541eSEvan Layton /* Used to manage access to nfs4_deleg_policy */ 799*0dfe541eSEvan Layton krwlock_t deleg_policy_lock; 800*0dfe541eSEvan Layton srv_deleg_policy_t nfs4_deleg_policy; 801*0dfe541eSEvan Layton /* Set first time we see one */ 802*0dfe541eSEvan Layton int seen_first_compound; 803*0dfe541eSEvan Layton /* 804*0dfe541eSEvan Layton * Circular double-linked list of paths for currently-served RGs. 805*0dfe541eSEvan Layton * No locking required -- only changed on server start. 806*0dfe541eSEvan Layton * Managed with insque/remque. 807*0dfe541eSEvan Layton */ 808*0dfe541eSEvan Layton rfs4_dss_path_t *dss_pathlist; 809*0dfe541eSEvan Layton /* Duplicate request cache */ 810*0dfe541eSEvan Layton rfs4_drc_t *nfs4_drc; 811*0dfe541eSEvan Layton /* nfsv4 server start time */ 812*0dfe541eSEvan Layton time_t rfs4_start_time; 813*0dfe541eSEvan Layton /* Used to serialize lookups of clientids */ 814*0dfe541eSEvan Layton krwlock_t rfs4_findclient_lock; 815*0dfe541eSEvan Layton 816*0dfe541eSEvan Layton /* NFSv4 server state client tables */ 817*0dfe541eSEvan Layton /* table expiry times */ 818*0dfe541eSEvan Layton time_t rfs4_client_cache_time; 819*0dfe541eSEvan Layton time_t rfs4_openowner_cache_time; 820*0dfe541eSEvan Layton time_t rfs4_state_cache_time; 821*0dfe541eSEvan Layton time_t rfs4_lo_state_cache_time; 822*0dfe541eSEvan Layton time_t rfs4_lockowner_cache_time; 823*0dfe541eSEvan Layton time_t rfs4_file_cache_time; 824*0dfe541eSEvan Layton time_t rfs4_deleg_state_cache_time; 825*0dfe541eSEvan Layton time_t rfs4_clntip_cache_time; 826*0dfe541eSEvan Layton /* tables and indexes */ 827*0dfe541eSEvan Layton /* client table */ 828*0dfe541eSEvan Layton rfs4_table_t *rfs4_client_tab; 829*0dfe541eSEvan Layton rfs4_index_t *rfs4_clientid_idx; 830*0dfe541eSEvan Layton rfs4_index_t *rfs4_nfsclnt_idx; 831*0dfe541eSEvan Layton /* client IP table */ 832*0dfe541eSEvan Layton rfs4_table_t *rfs4_clntip_tab; 833*0dfe541eSEvan Layton rfs4_index_t *rfs4_clntip_idx; 834*0dfe541eSEvan Layton /* Open Owner table */ 835*0dfe541eSEvan Layton rfs4_table_t *rfs4_openowner_tab; 836*0dfe541eSEvan Layton rfs4_index_t *rfs4_openowner_idx; 837*0dfe541eSEvan Layton /* Open State ID table */ 838*0dfe541eSEvan Layton rfs4_table_t *rfs4_state_tab; 839*0dfe541eSEvan Layton rfs4_index_t *rfs4_state_idx; 840*0dfe541eSEvan Layton rfs4_index_t *rfs4_state_owner_file_idx; 841*0dfe541eSEvan Layton rfs4_index_t *rfs4_state_file_idx; 842*0dfe541eSEvan Layton /* Lock State ID table */ 843*0dfe541eSEvan Layton rfs4_table_t *rfs4_lo_state_tab; 844*0dfe541eSEvan Layton rfs4_index_t *rfs4_lo_state_idx; 845*0dfe541eSEvan Layton rfs4_index_t *rfs4_lo_state_owner_idx; 846*0dfe541eSEvan Layton /* Lock owner table */ 847*0dfe541eSEvan Layton rfs4_table_t *rfs4_lockowner_tab; 848*0dfe541eSEvan Layton rfs4_index_t *rfs4_lockowner_idx; 849*0dfe541eSEvan Layton rfs4_index_t *rfs4_lockowner_pid_idx; 850*0dfe541eSEvan Layton /* File table */ 851*0dfe541eSEvan Layton rfs4_table_t *rfs4_file_tab; 852*0dfe541eSEvan Layton rfs4_index_t *rfs4_file_idx; 853*0dfe541eSEvan Layton /* Deleg State table */ 854*0dfe541eSEvan Layton rfs4_table_t *rfs4_deleg_state_tab; 855*0dfe541eSEvan Layton rfs4_index_t *rfs4_deleg_idx; 856*0dfe541eSEvan Layton rfs4_index_t *rfs4_deleg_state_idx; 857*0dfe541eSEvan Layton 858*0dfe541eSEvan Layton /* client stable storage */ 859*0dfe541eSEvan Layton int rfs4_ss_enabled; 860*0dfe541eSEvan Layton } nfs4_srv_t; 861*0dfe541eSEvan Layton 862*0dfe541eSEvan Layton /* 863*0dfe541eSEvan Layton * max length of the NFSv4 server database name 864*0dfe541eSEvan Layton */ 865*0dfe541eSEvan Layton #define RFS4_MAX_MEM_CACHE_NAME 48 866*0dfe541eSEvan Layton 867*0dfe541eSEvan Layton /* 868*0dfe541eSEvan Layton * global NFSv4 server kmem caches 869*0dfe541eSEvan Layton * r_db_name - The name of the state database and the table that will use it 870*0dfe541eSEvan Layton * These tables are defined in nfs4_srv_t 871*0dfe541eSEvan Layton * r_db_mem_cache - The kmem cache associated with the state database name 872*0dfe541eSEvan Layton */ 873*0dfe541eSEvan Layton typedef struct rfs4_db_mem_cache { 874*0dfe541eSEvan Layton char r_db_name[RFS4_MAX_MEM_CACHE_NAME]; 875*0dfe541eSEvan Layton kmem_cache_t *r_db_mem_cache; 876*0dfe541eSEvan Layton } rfs4_db_mem_cache_t; 877*0dfe541eSEvan Layton 878*0dfe541eSEvan Layton #define RFS4_DB_MEM_CACHE_NUM 8 879*0dfe541eSEvan Layton 880*0dfe541eSEvan Layton rfs4_db_mem_cache_t rfs4_db_mem_cache_table[RFS4_DB_MEM_CACHE_NUM]; 881*0dfe541eSEvan Layton 882*0dfe541eSEvan Layton 883*0dfe541eSEvan Layton extern srv_deleg_policy_t nfs4_get_deleg_policy(); 884*0dfe541eSEvan Layton 885*0dfe541eSEvan Layton extern void rfs4_servinst_create(nfs4_srv_t *, int, int, char **); 886*0dfe541eSEvan Layton extern void rfs4_servinst_destroy_all(nfs4_srv_t *); 887*0dfe541eSEvan Layton extern void rfs4_servinst_assign(nfs4_srv_t *, rfs4_client_t *, 888*0dfe541eSEvan Layton rfs4_servinst_t *); 889*0dfe541eSEvan Layton extern rfs4_servinst_t *rfs4_servinst(rfs4_client_t *); 890*0dfe541eSEvan Layton extern int rfs4_clnt_in_grace(rfs4_client_t *); 891*0dfe541eSEvan Layton extern int rfs4_servinst_in_grace(rfs4_servinst_t *); 892*0dfe541eSEvan Layton extern int rfs4_servinst_grace_new(rfs4_servinst_t *); 893*0dfe541eSEvan Layton extern void rfs4_grace_start(rfs4_servinst_t *); 894*0dfe541eSEvan Layton extern void rfs4_grace_start_new(nfs4_srv_t *); 895*0dfe541eSEvan Layton extern void rfs4_grace_reset_all(nfs4_srv_t *); 896*0dfe541eSEvan Layton extern void rfs4_ss_oldstate(rfs4_oldstate_t *, char *, char *); 897*0dfe541eSEvan Layton extern void rfs4_dss_readstate(nfs4_srv_t *, int, char **); 898*0dfe541eSEvan Layton 8997c478bd9Sstevel@tonic-gate /* 9007c478bd9Sstevel@tonic-gate * Various interfaces to manipulate the state structures introduced 9017c478bd9Sstevel@tonic-gate * above 9027c478bd9Sstevel@tonic-gate */ 9037c478bd9Sstevel@tonic-gate extern void rfs4_free_reply(nfs_resop4 *); 9047c478bd9Sstevel@tonic-gate extern void rfs4_copy_reply(nfs_resop4 *, nfs_resop4 *); 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate /* rfs4_client_t handling */ 9077c478bd9Sstevel@tonic-gate extern rfs4_client_t *rfs4_findclient(nfs_client_id4 *, 9087c478bd9Sstevel@tonic-gate bool_t *, rfs4_client_t *); 9097c478bd9Sstevel@tonic-gate extern rfs4_client_t *rfs4_findclient_by_id(clientid4, bool_t); 9102f172c55SRobert Thurlow extern rfs4_client_t *rfs4_findclient_by_addr(struct sockaddr *); 9117c478bd9Sstevel@tonic-gate extern void rfs4_client_rele(rfs4_client_t *); 9127c478bd9Sstevel@tonic-gate extern void rfs4_client_close(rfs4_client_t *); 9137c478bd9Sstevel@tonic-gate extern void rfs4_client_state_remove(rfs4_client_t *); 9147c478bd9Sstevel@tonic-gate extern void rfs4_client_scv_next(rfs4_client_t *); 9157c478bd9Sstevel@tonic-gate extern void rfs4_update_lease(rfs4_client_t *); 9167c478bd9Sstevel@tonic-gate extern bool_t rfs4_lease_expired(rfs4_client_t *); 9177c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_check_clientid(clientid4 *, int); 9187c478bd9Sstevel@tonic-gate 9192f172c55SRobert Thurlow /* rfs4_clntip_t handling */ 9202f172c55SRobert Thurlow extern rfs4_clntip_t *rfs4_find_clntip(struct sockaddr *, bool_t *); 9212f172c55SRobert Thurlow extern void rfs4_invalidate_clntip(struct sockaddr *); 9222f172c55SRobert Thurlow 9237c478bd9Sstevel@tonic-gate /* rfs4_openowner_t handling */ 9247c478bd9Sstevel@tonic-gate extern rfs4_openowner_t *rfs4_findopenowner(open_owner4 *, bool_t *, seqid4); 9257c478bd9Sstevel@tonic-gate extern void rfs4_update_open_sequence(rfs4_openowner_t *); 9267c478bd9Sstevel@tonic-gate extern void rfs4_update_open_resp(rfs4_openowner_t *, 9277c478bd9Sstevel@tonic-gate nfs_resop4 *, nfs_fh4 *); 9287c478bd9Sstevel@tonic-gate extern void rfs4_openowner_rele(rfs4_openowner_t *); 9297c478bd9Sstevel@tonic-gate extern void rfs4_free_opens(rfs4_openowner_t *, bool_t, bool_t); 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate /* rfs4_lockowner_t handling */ 9327c478bd9Sstevel@tonic-gate extern rfs4_lockowner_t *rfs4_findlockowner(lock_owner4 *, bool_t *); 9337c478bd9Sstevel@tonic-gate extern rfs4_lockowner_t *rfs4_findlockowner_by_pid(pid_t); 9347c478bd9Sstevel@tonic-gate extern void rfs4_lockowner_rele(rfs4_lockowner_t *); 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate /* rfs4_state_t handling */ 9377c478bd9Sstevel@tonic-gate extern rfs4_state_t *rfs4_findstate_by_owner_file(rfs4_openowner_t *, 9387c478bd9Sstevel@tonic-gate rfs4_file_t *, bool_t *); 9397c478bd9Sstevel@tonic-gate extern void rfs4_state_rele(rfs4_state_t *); 9407c478bd9Sstevel@tonic-gate extern void rfs4_state_close(rfs4_state_t *, bool_t, 9417c478bd9Sstevel@tonic-gate bool_t, cred_t *); 9427c478bd9Sstevel@tonic-gate extern void rfs4_release_share_lock_state(rfs4_state_t *, 9437c478bd9Sstevel@tonic-gate cred_t *, bool_t); 9447c478bd9Sstevel@tonic-gate extern void rfs4_close_all_state(rfs4_file_t *); 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate /* rfs4_lo_state_t handling */ 9477c478bd9Sstevel@tonic-gate extern rfs4_lo_state_t *rfs4_findlo_state_by_owner(rfs4_lockowner_t *, 9487c478bd9Sstevel@tonic-gate rfs4_state_t *, bool_t *); 9497c478bd9Sstevel@tonic-gate extern void rfs4_lo_state_rele(rfs4_lo_state_t *, bool_t); 9507c478bd9Sstevel@tonic-gate extern void rfs4_update_lock_sequence(rfs4_lo_state_t *); 9517c478bd9Sstevel@tonic-gate extern void rfs4_update_lock_resp(rfs4_lo_state_t *, 9527c478bd9Sstevel@tonic-gate nfs_resop4 *); 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate /* rfs4_file_t handling */ 9557c478bd9Sstevel@tonic-gate extern rfs4_file_t *rfs4_findfile(vnode_t *, nfs_fh4 *, bool_t *); 9567c478bd9Sstevel@tonic-gate extern rfs4_file_t *rfs4_findfile_withlock(vnode_t *, nfs_fh4 *, 9577c478bd9Sstevel@tonic-gate bool_t *); 9587c478bd9Sstevel@tonic-gate extern void rfs4_file_rele(rfs4_file_t *); 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate /* General collection of "get state" functions */ 9617c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_state(stateid4 *, rfs4_state_t **, 9627c478bd9Sstevel@tonic-gate rfs4_dbsearch_type_t); 9637c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_deleg_state(stateid4 *, 9647c478bd9Sstevel@tonic-gate rfs4_deleg_state_t **); 9657c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_get_lo_state(stateid4 *, rfs4_lo_state_t **, 9667c478bd9Sstevel@tonic-gate bool_t); 9677c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_check_stateid(int, vnode_t *, stateid4 *, 968da6c28aaSamw bool_t, bool_t *, bool_t, 969da6c28aaSamw caller_context_t *); 9707c478bd9Sstevel@tonic-gate extern int rfs4_check_stateid_seqid(rfs4_state_t *, stateid4 *); 9717c478bd9Sstevel@tonic-gate extern int rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *, 9727c478bd9Sstevel@tonic-gate stateid4 *); 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate /* return values for rfs4_check_stateid_seqid() */ 9757c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_OKAY 1 9767c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_OLD 2 9777c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_BAD 3 9787c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_EXPIRED 4 9797c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_REPLAY 5 9807c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_CLOSED 6 9817c478bd9Sstevel@tonic-gate #define NFS4_CHECK_STATEID_UNCONFIRMED 7 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate /* delay() time that server is willing to briefly wait for a delegreturn */ 9847c478bd9Sstevel@tonic-gate #define NFS4_DELEGATION_CONFLICT_DELAY (hz/10) 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate /* 9877c478bd9Sstevel@tonic-gate * Interfaces for handling of callback's client handle cache and 9887c478bd9Sstevel@tonic-gate * callback interfaces themselves. 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate extern void rfs4_cbinfo_free(rfs4_cbinfo_t *); 9917c478bd9Sstevel@tonic-gate extern void rfs4_client_setcb(rfs4_client_t *, cb_client4 *, 9927c478bd9Sstevel@tonic-gate uint32_t); 9937c478bd9Sstevel@tonic-gate extern void rfs4_deleg_cb_check(rfs4_client_t *); 9947c478bd9Sstevel@tonic-gate extern nfsstat4 rfs4_vop_getattr(vnode_t *, vattr_t *, int, cred_t *); 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate /* rfs4_deleg_state_t handling and other delegation interfaces */ 9977c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_finddeleg(rfs4_state_t *, bool_t *); 9987c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_finddelegstate(stateid_t *); 9997c478bd9Sstevel@tonic-gate extern bool_t rfs4_check_recall(rfs4_state_t *, uint32_t); 10007c478bd9Sstevel@tonic-gate extern void rfs4_recall_deleg(rfs4_file_t *, 10017c478bd9Sstevel@tonic-gate bool_t, rfs4_client_t *); 10027c478bd9Sstevel@tonic-gate extern int rfs4_get_deleg(rfs4_state_t *, open_delegation_type4, 10037c478bd9Sstevel@tonic-gate open_delegation_type4 (*policy)(rfs4_state_t *, 10047c478bd9Sstevel@tonic-gate open_delegation_type4 dtype)); 10057c478bd9Sstevel@tonic-gate extern rfs4_deleg_state_t *rfs4_grant_delegation(delegreq_t, rfs4_state_t *, 10067c478bd9Sstevel@tonic-gate int *); 10077c478bd9Sstevel@tonic-gate extern void rfs4_set_deleg_response(rfs4_deleg_state_t *, 10087c478bd9Sstevel@tonic-gate open_delegation4 *, nfsace4 *, int); 10097c478bd9Sstevel@tonic-gate extern void rfs4_return_deleg(rfs4_deleg_state_t *, bool_t); 10107c478bd9Sstevel@tonic-gate extern bool_t rfs4_is_deleg(rfs4_state_t *); 10117c478bd9Sstevel@tonic-gate extern void rfs4_deleg_state_rele(rfs4_deleg_state_t *); 10127c478bd9Sstevel@tonic-gate extern bool_t rfs4_check_delegated_byfp(int, rfs4_file_t *, 10137c478bd9Sstevel@tonic-gate bool_t, bool_t, bool_t, clientid4 *); 10147c478bd9Sstevel@tonic-gate extern void rfs4_clear_dont_grant(rfs4_file_t *); 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate /* 10177c478bd9Sstevel@tonic-gate * nfs4 monitored operations. 10187c478bd9Sstevel@tonic-gate */ 1019cfae96c2Sjwahlig extern int deleg_rd_open(femarg_t *, int, cred_t *, caller_context_t *); 1020cfae96c2Sjwahlig extern int deleg_wr_open(femarg_t *, int, cred_t *, caller_context_t *); 1021cfae96c2Sjwahlig extern int deleg_wr_read(femarg_t *, uio_t *, int, cred_t *, 1022cfae96c2Sjwahlig caller_context_t *); 1023cfae96c2Sjwahlig extern int deleg_rd_write(femarg_t *, uio_t *, int, cred_t *, 1024cfae96c2Sjwahlig caller_context_t *); 1025cfae96c2Sjwahlig extern int deleg_wr_write(femarg_t *, uio_t *, int, cred_t *, 1026cfae96c2Sjwahlig caller_context_t *); 1027cfae96c2Sjwahlig extern int deleg_rd_setattr(femarg_t *, vattr_t *, int, cred_t *, 1028cfae96c2Sjwahlig caller_context_t *); 1029cfae96c2Sjwahlig extern int deleg_wr_setattr(femarg_t *, vattr_t *, int, cred_t *, 1030cfae96c2Sjwahlig caller_context_t *); 10317c478bd9Sstevel@tonic-gate extern int deleg_rd_rwlock(femarg_t *, int, caller_context_t *); 10327c478bd9Sstevel@tonic-gate extern int deleg_wr_rwlock(femarg_t *, int, caller_context_t *); 1033cfae96c2Sjwahlig extern int deleg_rd_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *, 1034cfae96c2Sjwahlig caller_context_t *); 1035cfae96c2Sjwahlig extern int deleg_wr_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *, 1036cfae96c2Sjwahlig caller_context_t *); 1037cfae96c2Sjwahlig extern int deleg_rd_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *, 10387c478bd9Sstevel@tonic-gate caller_context_t *); 1039cfae96c2Sjwahlig extern int deleg_wr_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *, 10407c478bd9Sstevel@tonic-gate caller_context_t *); 1041cfae96c2Sjwahlig extern int deleg_rd_vnevent(femarg_t *, vnevent_t, vnode_t *, char *, 1042da6c28aaSamw caller_context_t *); 1043cfae96c2Sjwahlig extern int deleg_wr_vnevent(femarg_t *, vnevent_t, vnode_t *, char *, 1044da6c28aaSamw caller_context_t *); 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate extern void rfs4_mon_hold(void *); 10477c478bd9Sstevel@tonic-gate extern void rfs4_mon_rele(void *); 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate extern fem_t *deleg_rdops; 10507c478bd9Sstevel@tonic-gate extern fem_t *deleg_wrops; 10517c478bd9Sstevel@tonic-gate 1052d216dff5SRobert Mastors extern int rfs4_share(rfs4_state_t *, uint32_t, uint32_t); 1053d216dff5SRobert Mastors extern int rfs4_unshare(rfs4_state_t *); 1054*0dfe541eSEvan Layton extern void rfs4_set_deleg_policy(nfs4_srv_t *, srv_deleg_policy_t); 1055*0dfe541eSEvan Layton extern void rfs4_hold_deleg_policy(nfs4_srv_t *); 1056*0dfe541eSEvan Layton extern void rfs4_rele_deleg_policy(nfs4_srv_t *); 1057*0dfe541eSEvan Layton 10587c478bd9Sstevel@tonic-gate #ifdef DEBUG 10597c478bd9Sstevel@tonic-gate #define NFS4_DEBUG(var, args) if (var) cmn_err args 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate extern int rfs4_debug; 10627c478bd9Sstevel@tonic-gate extern int nfs4_client_attr_debug; 10637c478bd9Sstevel@tonic-gate extern int nfs4_client_state_debug; 10647c478bd9Sstevel@tonic-gate extern int nfs4_client_shadow_debug; 10657c478bd9Sstevel@tonic-gate extern int nfs4_client_lock_debug; 10667c478bd9Sstevel@tonic-gate extern int nfs4_client_lease_debug; 10677c478bd9Sstevel@tonic-gate extern int nfs4_seqid_sync; 10687c478bd9Sstevel@tonic-gate extern int nfs4_client_map_debug; 10697c478bd9Sstevel@tonic-gate extern int nfs4_client_inactive_debug; 10707c478bd9Sstevel@tonic-gate extern int nfs4_client_recov_debug; 10717c478bd9Sstevel@tonic-gate extern int nfs4_client_failover_debug; 10727c478bd9Sstevel@tonic-gate extern int nfs4_client_call_debug; 10737c478bd9Sstevel@tonic-gate extern int nfs4_client_foo_debug; 10747c478bd9Sstevel@tonic-gate extern int nfs4_client_zone_debug; 10757c478bd9Sstevel@tonic-gate extern int nfs4_lost_rqst_debug; 10767c478bd9Sstevel@tonic-gate extern int nfs4_open_stream_debug; 10777c478bd9Sstevel@tonic-gate extern int nfs4_client_open_dg; 10787c478bd9Sstevel@tonic-gate extern int nfs4_srvmnt_debug; 10797c478bd9Sstevel@tonic-gate extern int nfs4_utf8_debug; 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate void rfs4_dbe_debug(rfs4_dbe_t *e); 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate #ifdef NFS4_DEBUG_MUTEX 10847c478bd9Sstevel@tonic-gate void nfs4_debug_mutex_enter(kmutex_t *, char *, int); 10857c478bd9Sstevel@tonic-gate void nfs4_debug_mutex_exit(kmutex_t *, char *, int); 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate #define mutex_enter(m) nfs4_debug_mutex_enter((m), __FILE__, __LINE__) 10887c478bd9Sstevel@tonic-gate #define mutex_exit(m) nfs4_debug_mutex_exit((m), __FILE__, __LINE__) 10897c478bd9Sstevel@tonic-gate #endif /* NFS4_DEBUG_MUTEX */ 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate #else /* ! DEBUG */ 10927c478bd9Sstevel@tonic-gate #define NFS4_DEBUG(var, args) 10937c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate /* 10967c478bd9Sstevel@tonic-gate * XXX - temporary for testing of volatile fh 10977c478bd9Sstevel@tonic-gate */ 10987c478bd9Sstevel@tonic-gate 10997c478bd9Sstevel@tonic-gate #ifdef VOLATILE_FH_TEST 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate struct nfs_fh4_fmt { 110227242a7cSthurlow fhandle4_t fh4_i; 11037c46fb7fSek uint32_t fh4_flag; 11047c46fb7fSek uint32_t fh4_volatile_id; 11057c478bd9Sstevel@tonic-gate }; 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate #else /* VOLATILE_FH_TEST */ 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate struct nfs_fh4_fmt { 111027242a7cSthurlow fhandle4_t fh4_i; 11117c46fb7fSek uint32_t fh4_flag; 11127c478bd9Sstevel@tonic-gate }; 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate #endif /* VOLATILE_FH_TEST */ 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate #define FH4_NAMEDATTR 1 11177c478bd9Sstevel@tonic-gate #define FH4_ATTRDIR 2 11187c478bd9Sstevel@tonic-gate 11197c46fb7fSek #define fh4_fsid fh4_i.fhx_fsid 112052deb364SToomas Soome #define fh4_len fh4_i.fhx_len /* fid length */ 112152deb364SToomas Soome #define fh4_data fh4_i.fhx_data /* fid bytes */ 11227c46fb7fSek #define fh4_xlen fh4_i.fhx_xlen 11237c46fb7fSek #define fh4_xdata fh4_i.fhx_xdata 11247c478bd9Sstevel@tonic-gate typedef struct nfs_fh4_fmt nfs_fh4_fmt_t; 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate #define fh4_to_fmt4(fh4p) ((nfs_fh4_fmt_t *)(fh4p)->nfs_fh4_val) 11277c478bd9Sstevel@tonic-gate #define get_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) & (flag)) 11287c478bd9Sstevel@tonic-gate #define set_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) |= (flag)) 11297c478bd9Sstevel@tonic-gate #define clr_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) &= ~(flag)) 11307c478bd9Sstevel@tonic-gate 11317c478bd9Sstevel@tonic-gate #define NFS_FH4_LEN sizeof (nfs_fh4_fmt_t) 11327c478bd9Sstevel@tonic-gate 1133b096b66cSnr /* 1134b096b66cSnr * Copy fields from external (fhandle_t) to in-memory (nfs_fh4_fmt_t) 1135b096b66cSnr * format to support export info checking. It does not copy over 1136b096b66cSnr * the complete filehandle, just the fsid, xlen and xdata. It may 1137b096b66cSnr * need to be changed to be used in other places. 1138b096b66cSnr * 1139b096b66cSnr * NOTE: The macro expects the space to be pre-allocated for 1140b096b66cSnr * the contents of nfs_fh4_fmt_t. 1141b096b66cSnr */ 1142b096b66cSnr #define FH_TO_FMT4(exifh, nfs_fmt) { \ 1143b096b66cSnr bzero((nfs_fmt), NFS_FH4_LEN); \ 1144b096b66cSnr (nfs_fmt)->fh4_fsid = (exifh)->fh_fsid; \ 1145b096b66cSnr (nfs_fmt)->fh4_xlen = (exifh)->fh_xlen; \ 1146b096b66cSnr bcopy((exifh)->fh_xdata, (nfs_fmt)->fh4_xdata, \ 1147b096b66cSnr (exifh)->fh_xlen); \ 1148b096b66cSnr } 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate /* 11517c478bd9Sstevel@tonic-gate * A few definitions of repeatedly used constructs for nfsv4 11527c478bd9Sstevel@tonic-gate */ 115352deb364SToomas Soome #define UTF8STRING_FREE(str) { \ 11547c478bd9Sstevel@tonic-gate kmem_free((str).utf8string_val, (str).utf8string_len); \ 11557c478bd9Sstevel@tonic-gate (str).utf8string_val = NULL; \ 115652deb364SToomas Soome (str).utf8string_len = 0; \ 115752deb364SToomas Soome } 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * NFS4_VOLATILE_FH yields non-zero if the filesystem uses non-persistent 11617c478bd9Sstevel@tonic-gate * filehandles. 11627c478bd9Sstevel@tonic-gate */ 11637c478bd9Sstevel@tonic-gate #define NFS4_VOLATILE_FH(mi) \ 11647c478bd9Sstevel@tonic-gate ((mi)->mi_fh_expire_type & \ 11657c478bd9Sstevel@tonic-gate (FH4_VOLATILE_ANY | FH4_VOL_MIGRATION | FH4_VOL_RENAME)) 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate /* 11687c478bd9Sstevel@tonic-gate * NFS_IS_DOTNAME checks if the name given represents a dot or dotdot entry 11697c478bd9Sstevel@tonic-gate */ 11707c478bd9Sstevel@tonic-gate #define NFS_IS_DOTNAME(name) \ 11717c478bd9Sstevel@tonic-gate (((name)[0] == '.') && \ 11727c478bd9Sstevel@tonic-gate (((name)[1] == '\0') || (((name)[1] == '.') && ((name)[2] == '\0')))) 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate /* 11757c478bd9Sstevel@tonic-gate * Define the number of bits in a bitmap word (uint32) 11767c478bd9Sstevel@tonic-gate */ 11777c478bd9Sstevel@tonic-gate #define NFS4_BITMAP4_BITSPERWORD (sizeof (uint32_t) * 8) 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* 11807c478bd9Sstevel@tonic-gate * Define the value for the access field of the compound_state structure 11817c478bd9Sstevel@tonic-gate * based on the result of nfsauth access checking. 11827c478bd9Sstevel@tonic-gate */ 11837c478bd9Sstevel@tonic-gate #define CS_ACCESS_OK 0x1 11847c478bd9Sstevel@tonic-gate #define CS_ACCESS_DENIED 0x2 11857c478bd9Sstevel@tonic-gate #define CS_ACCESS_LIMITED 0x4 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate /* 11887c478bd9Sstevel@tonic-gate * compound state in nfsv4 server 11897c478bd9Sstevel@tonic-gate */ 11907c478bd9Sstevel@tonic-gate struct compound_state { 11917c478bd9Sstevel@tonic-gate struct exportinfo *exi; 11927c478bd9Sstevel@tonic-gate struct exportinfo *saved_exi; /* export struct for saved_vp */ 119352deb364SToomas Soome cred_t *basecr; /* UNIX cred: only RPC request */ 119452deb364SToomas Soome caddr_t principal; 119552deb364SToomas Soome int nfsflavor; 119652deb364SToomas Soome cred_t *cr; /* UNIX cred: RPC request and */ 11977c478bd9Sstevel@tonic-gate /* target export */ 119852deb364SToomas Soome bool_t cont; 119952deb364SToomas Soome uint_t access; /* access perm on vp per request */ 120052deb364SToomas Soome bool_t deleg; /* TRUE if current fh has */ 12017c478bd9Sstevel@tonic-gate /* write delegated */ 120252deb364SToomas Soome vnode_t *vp; /* modified by PUTFH, and by ops that */ 12037c478bd9Sstevel@tonic-gate /* input to GETFH */ 120452deb364SToomas Soome bool_t mandlock; /* Is mandatory locking in effect */ 12057c478bd9Sstevel@tonic-gate /* for vp */ 120652deb364SToomas Soome vnode_t *saved_vp; /* modified by SAVEFH, copied to */ 12077c478bd9Sstevel@tonic-gate /* vp by RESTOREFH */ 120852deb364SToomas Soome nfsstat4 *statusp; 120952deb364SToomas Soome nfs_fh4 fh; /* ditto. valid only if vp != NULL */ 121052deb364SToomas Soome nfs_fh4 saved_fh; /* ditto. valid only if */ 121152deb364SToomas Soome /* saved_vp != NULL */ 12127c478bd9Sstevel@tonic-gate struct svc_req *req; 121352deb364SToomas Soome char fhbuf[NFS4_FHSIZE]; 12147c478bd9Sstevel@tonic-gate }; 12157c478bd9Sstevel@tonic-gate 12167c478bd9Sstevel@tonic-gate /* 12177c478bd9Sstevel@tonic-gate * Conversion commands for nfsv4 server attr checking 12187c478bd9Sstevel@tonic-gate */ 12197c478bd9Sstevel@tonic-gate enum nfs4_attr_cmd { 12207c478bd9Sstevel@tonic-gate NFS4ATTR_SUPPORTED = 0, /* check which attrs supported */ 12217c478bd9Sstevel@tonic-gate NFS4ATTR_GETIT = 1, /* getattr - sys to fattr4 (r) */ 12227c478bd9Sstevel@tonic-gate NFS4ATTR_SETIT = 2, /* setattr - fattr4 to sys (w) */ 12237c478bd9Sstevel@tonic-gate NFS4ATTR_VERIT = 3, /* verify - fattr4 to sys (r) */ 12247c478bd9Sstevel@tonic-gate NFS4ATTR_FREEIT = 4 /* free any alloc'd space for attr */ 12257c478bd9Sstevel@tonic-gate }; 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate typedef enum nfs4_attr_cmd nfs4_attr_cmd_t; 12287c478bd9Sstevel@tonic-gate 12297c478bd9Sstevel@tonic-gate struct nfs4_svgetit_arg { 12307c478bd9Sstevel@tonic-gate nfs4_attr_cmd_t op; /* getit or setit */ 12317c478bd9Sstevel@tonic-gate struct compound_state *cs; 12327c478bd9Sstevel@tonic-gate struct statvfs64 *sbp; 123352deb364SToomas Soome uint_t flag; /* VOP_GETATTR/VOP_SETATTR flag */ 123452deb364SToomas Soome uint_t xattr; /* object is xattr */ 123552deb364SToomas Soome bool_t rdattr_error_req; /* if readdir & client wants */ 12367c478bd9Sstevel@tonic-gate /* rdattr_error */ 12377c478bd9Sstevel@tonic-gate nfsstat4 rdattr_error; /* used for per-entry status */ 12387c478bd9Sstevel@tonic-gate /* (if rdattr_err) */ 12392f172c55SRobert Thurlow bool_t is_referral; /* because sometimes we tell lies */ 12407c478bd9Sstevel@tonic-gate bool_t mntdfid_set; 12417c478bd9Sstevel@tonic-gate fattr4_mounted_on_fileid 12427c478bd9Sstevel@tonic-gate mounted_on_fileid; 12437c478bd9Sstevel@tonic-gate /* readdir op can always return */ 12447c478bd9Sstevel@tonic-gate /* d_ino from server fs dirent */ 12457c478bd9Sstevel@tonic-gate /* for mounted_on_fileid attr. */ 12467c478bd9Sstevel@tonic-gate /* This field holds d_ino so */ 12477c478bd9Sstevel@tonic-gate /* srv attr conv code can avoid */ 12487c478bd9Sstevel@tonic-gate /* doing an untraverse. */ 12497c478bd9Sstevel@tonic-gate vattr_t vap[1]; 12507c478bd9Sstevel@tonic-gate }; 12517c478bd9Sstevel@tonic-gate 12527c478bd9Sstevel@tonic-gate struct nfs4_ntov_map { 125352deb364SToomas Soome bitmap4 fbit; /* FATTR4_XXX_MASKY */ 125452deb364SToomas Soome uint_t vbit; /* AT_XXX */ 125552deb364SToomas Soome bool_t vfsstat; 125652deb364SToomas Soome bool_t mandatory; /* attribute mandatory to implement? */ 125752deb364SToomas Soome uint_t nval; 12587c478bd9Sstevel@tonic-gate int xdr_size; /* Size of XDR'd attr */ 125952deb364SToomas Soome xdrproc_t xfunc; 12607c478bd9Sstevel@tonic-gate int (*sv_getit)(nfs4_attr_cmd_t, struct nfs4_svgetit_arg *, 12617c478bd9Sstevel@tonic-gate union nfs4_attr_u *); /* subroutine for getting attr. */ 126252deb364SToomas Soome char *prtstr; /* string attr for printing */ 12637c478bd9Sstevel@tonic-gate }; 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate struct nfs4attr_to_vattr { 126652deb364SToomas Soome vnode_t *vp; 126752deb364SToomas Soome vattr_t *vap; 126852deb364SToomas Soome nfs_fh4 *fhp; 12697c478bd9Sstevel@tonic-gate nfsstat4 rdattr_error; 12707c478bd9Sstevel@tonic-gate uint32_t flag; 12717c478bd9Sstevel@tonic-gate fattr4_change change; 12727c478bd9Sstevel@tonic-gate fattr4_fsid srv_fsid; 12737c478bd9Sstevel@tonic-gate fattr4_mounted_on_fileid mntd_fid; 12747c478bd9Sstevel@tonic-gate }; 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate typedef struct nfs4attr_to_vattr ntov4_t; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate /* 12797c478bd9Sstevel@tonic-gate * nfs4attr_to_vattr flags 12807c478bd9Sstevel@tonic-gate */ 12817c478bd9Sstevel@tonic-gate #define NTOV_FHP_VALID 0x01 12827c478bd9Sstevel@tonic-gate #define NTOV_RDATTR_ERROR_VALID 0x02 12837c478bd9Sstevel@tonic-gate #define NTOV_CHANGE_VALID 0x04 12847c478bd9Sstevel@tonic-gate #define NTOV_SUPP_VALID 0x08 12857c478bd9Sstevel@tonic-gate #define NTOV_SRV_FSID_VALID 0x10 12867c478bd9Sstevel@tonic-gate #define NTOV_MOUNTED_ON_FILEID_VALID 0x20 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate #define FATTR4_MANDATTR_MASK ( \ 12907c478bd9Sstevel@tonic-gate FATTR4_SUPPORTED_ATTRS_MASK | \ 12917c478bd9Sstevel@tonic-gate FATTR4_TYPE_MASK | \ 12927c478bd9Sstevel@tonic-gate FATTR4_FH_EXPIRE_TYPE_MASK | \ 12937c478bd9Sstevel@tonic-gate FATTR4_CHANGE_MASK | \ 12947c478bd9Sstevel@tonic-gate FATTR4_SIZE_MASK | \ 12957c478bd9Sstevel@tonic-gate FATTR4_LINK_SUPPORT_MASK | \ 12967c478bd9Sstevel@tonic-gate FATTR4_SYMLINK_SUPPORT_MASK | \ 12977c478bd9Sstevel@tonic-gate FATTR4_NAMED_ATTR_MASK | \ 12987c478bd9Sstevel@tonic-gate FATTR4_FSID_MASK | \ 12997c478bd9Sstevel@tonic-gate FATTR4_UNIQUE_HANDLES_MASK | \ 13007c478bd9Sstevel@tonic-gate FATTR4_LEASE_TIME_MASK | \ 13017c478bd9Sstevel@tonic-gate FATTR4_RDATTR_ERROR_MASK | \ 13027c478bd9Sstevel@tonic-gate FATTR4_FILEHANDLE_MASK) 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate struct nfs4attr_to_osattr { 13067c478bd9Sstevel@tonic-gate void *attrconv_arg; 13077c478bd9Sstevel@tonic-gate uint_t mask; 13087c478bd9Sstevel@tonic-gate }; 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate struct mntinfo4; 13117c478bd9Sstevel@tonic-gate 13127c478bd9Sstevel@tonic-gate /* 13137c478bd9Sstevel@tonic-gate * lkp4_attr_setup lists the different options for attributes when calling 13147c478bd9Sstevel@tonic-gate * nfs4lookup_setup - either no attributes (just lookups - e.g., secinfo), 13157c478bd9Sstevel@tonic-gate * one component only (normal component lookup), get attributes for the 13167c478bd9Sstevel@tonic-gate * last component (e.g., mount), attributes for each component (e.g., 13177c478bd9Sstevel@tonic-gate * failovers later), just the filehandle for the last component (e.g., 13187c478bd9Sstevel@tonic-gate * volatile filehandle recovery), or stuff that needs OPENATTR (e.g. 13197c478bd9Sstevel@tonic-gate * looking up a named attribute or it's hidden directory). 13207c478bd9Sstevel@tonic-gate */ 13217c478bd9Sstevel@tonic-gate enum lkp4_attr_setup { 13227c478bd9Sstevel@tonic-gate LKP4_NO_ATTRIBUTES = 0, /* no attrs or filehandles */ 13237c478bd9Sstevel@tonic-gate LKP4_ALL_ATTRIBUTES = 3, /* multi-comp: attrs for all comps */ 13247c478bd9Sstevel@tonic-gate LKP4_LAST_NAMED_ATTR = 5, /* multi-comp: named attr & attrdir */ 13257c478bd9Sstevel@tonic-gate LKP4_LAST_ATTRDIR = 6, /* multi-comp: just attrdir */ 13267c478bd9Sstevel@tonic-gate LKP4_ALL_ATTR_SECINFO = 7 /* multi-comp: attrs for all comp and */ 13277c478bd9Sstevel@tonic-gate /* secinfo for last comp */ 13287c478bd9Sstevel@tonic-gate }; 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate /* 13317c478bd9Sstevel@tonic-gate * lookup4_param a set of parameters to nfs4lookup_setup - 13327c478bd9Sstevel@tonic-gate * used to setup a path lookup compound request. 13337c478bd9Sstevel@tonic-gate */ 13347c478bd9Sstevel@tonic-gate typedef struct lookup4_param { 13357c478bd9Sstevel@tonic-gate enum lkp4_attr_setup l4_getattrs; /* (in) get attrs in the lookup? */ 133652deb364SToomas Soome int header_len; /* (in) num ops before first lookup */ 133752deb364SToomas Soome int trailer_len; /* (in) num ops after last */ 13387c478bd9Sstevel@tonic-gate /* Lookup/Getattr */ 133952deb364SToomas Soome bitmap4 ga_bits; /* (in) Which attributes for Getattr */ 13407c478bd9Sstevel@tonic-gate COMPOUND4args_clnt *argsp; /* (in/out) args for compound struct */ 13417c478bd9Sstevel@tonic-gate COMPOUND4res_clnt *resp; /* (in/out) res for compound struct */ 134252deb364SToomas Soome int arglen; /* (out) argop buffer alloc'd length */ 13437c478bd9Sstevel@tonic-gate struct mntinfo4 *mi; 13447c478bd9Sstevel@tonic-gate } lookup4_param_t; 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate 13477c478bd9Sstevel@tonic-gate #define NFS4_FATTR4_FINISH -1 /* fattr4 index indicating finish */ 13487c478bd9Sstevel@tonic-gate 13497c478bd9Sstevel@tonic-gate typedef int (*nfs4attr_to_os_t)(int, union nfs4_attr_u *, 13507c478bd9Sstevel@tonic-gate struct nfs4attr_to_osattr *); 13517c478bd9Sstevel@tonic-gate 13527c478bd9Sstevel@tonic-gate /* 13537c478bd9Sstevel@tonic-gate * The nfs4_error_t is the basic structure to return error values 13547c478bd9Sstevel@tonic-gate * from rfs4call. It encapsulates the unix errno 13557c478bd9Sstevel@tonic-gate * value, the nfsstat4 value and the rpc status value into a single 13567c478bd9Sstevel@tonic-gate * structure. 13577c478bd9Sstevel@tonic-gate * 13587c478bd9Sstevel@tonic-gate * If error is set, then stat is ignored and rpc_status may be 13597c478bd9Sstevel@tonic-gate * set if the error occurred as the result of a CLNT_CALL. If 13607c478bd9Sstevel@tonic-gate * stat is set, then rpc request succeeded, error and 13617c478bd9Sstevel@tonic-gate * rpc_status are set to 0 and stat contains the result of 13627c478bd9Sstevel@tonic-gate * operation, NFS4_OK or one of the NFS4ERR_* values. 13637c478bd9Sstevel@tonic-gate * 13647c478bd9Sstevel@tonic-gate * Functions which want to generate errors independently from 13657c478bd9Sstevel@tonic-gate * rfs4call should set error to the desired errno value and 13667c478bd9Sstevel@tonic-gate * set stat and rpc_status to 0. nfs4_error_init() is a 13677c478bd9Sstevel@tonic-gate * convenient function to do this. 13687c478bd9Sstevel@tonic-gate */ 13697c478bd9Sstevel@tonic-gate typedef struct { 13707c478bd9Sstevel@tonic-gate int error; 13717c478bd9Sstevel@tonic-gate nfsstat4 stat; 13727c478bd9Sstevel@tonic-gate enum clnt_stat rpc_status; 13737c478bd9Sstevel@tonic-gate } nfs4_error_t; 13747c478bd9Sstevel@tonic-gate 13757c478bd9Sstevel@tonic-gate /* 13767c478bd9Sstevel@tonic-gate * Shared functions 13777c478bd9Sstevel@tonic-gate */ 13787c478bd9Sstevel@tonic-gate extern void rfs4_op_readdir(nfs_argop4 *, nfs_resop4 *, 13797c478bd9Sstevel@tonic-gate struct svc_req *, struct compound_state *); 13807c478bd9Sstevel@tonic-gate extern void nfs_fh4_copy(nfs_fh4 *, nfs_fh4 *); 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate extern void nfs4_fattr4_free(fattr4 *); 13837c478bd9Sstevel@tonic-gate 13847c478bd9Sstevel@tonic-gate extern int nfs4lookup_setup(char *, lookup4_param_t *, int); 13857c478bd9Sstevel@tonic-gate extern void nfs4_getattr_otw_norecovery(vnode_t *, 13867c478bd9Sstevel@tonic-gate nfs4_ga_res_t *, nfs4_error_t *, cred_t *, int); 13877c478bd9Sstevel@tonic-gate extern int nfs4_getattr_otw(vnode_t *, nfs4_ga_res_t *, cred_t *, int); 13887c478bd9Sstevel@tonic-gate extern int nfs4cmpfh(const nfs_fh4 *, const nfs_fh4 *); 13897c478bd9Sstevel@tonic-gate extern int nfs4cmpfhandle(nfs4_fhandle_t *, nfs4_fhandle_t *); 13907c478bd9Sstevel@tonic-gate extern int nfs4getattr(vnode_t *, struct vattr *, cred_t *); 13917c478bd9Sstevel@tonic-gate extern int nfs4_waitfor_purge_complete(vnode_t *); 13927c478bd9Sstevel@tonic-gate extern int nfs4_validate_caches(vnode_t *, cred_t *); 13937c478bd9Sstevel@tonic-gate extern int nfs4init(int, char *); 13947c478bd9Sstevel@tonic-gate extern void nfs4fini(void); 13957c478bd9Sstevel@tonic-gate extern int nfs4_vfsinit(void); 13967c478bd9Sstevel@tonic-gate extern void nfs4_vfsfini(void); 13977c478bd9Sstevel@tonic-gate 13987c478bd9Sstevel@tonic-gate extern void nfs4_vnops_init(void); 13997c478bd9Sstevel@tonic-gate extern void nfs4_vnops_fini(void); 14007c478bd9Sstevel@tonic-gate extern void nfs_idmap_init(void); 14017c478bd9Sstevel@tonic-gate extern void nfs_idmap_flush(int); 14027c478bd9Sstevel@tonic-gate extern void nfs_idmap_fini(void); 14037c478bd9Sstevel@tonic-gate extern int nfs4_rnode_init(void); 14047c478bd9Sstevel@tonic-gate extern int nfs4_rnode_fini(void); 14057c478bd9Sstevel@tonic-gate extern int nfs4_shadow_init(void); 14067c478bd9Sstevel@tonic-gate extern int nfs4_shadow_fini(void); 14077c478bd9Sstevel@tonic-gate extern int nfs4_acache_init(void); 14087c478bd9Sstevel@tonic-gate extern int nfs4_acache_fini(void); 14097c478bd9Sstevel@tonic-gate extern int nfs4_subr_init(void); 14107c478bd9Sstevel@tonic-gate extern int nfs4_subr_fini(void); 14117c478bd9Sstevel@tonic-gate extern void nfs4_acl_init(void); 14127c478bd9Sstevel@tonic-gate extern void nfs4_acl_free_cache(vsecattr_t *); 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate extern int geterrno4(nfsstat4); 14157c478bd9Sstevel@tonic-gate extern nfsstat4 puterrno4(int); 14167c478bd9Sstevel@tonic-gate extern int nfs4_need_to_bump_seqid(COMPOUND4res_clnt *); 14177c478bd9Sstevel@tonic-gate extern int nfs4tsize(void); 14187c478bd9Sstevel@tonic-gate extern int checkauth4(struct compound_state *, struct svc_req *); 14197c478bd9Sstevel@tonic-gate extern nfsstat4 call_checkauth4(struct compound_state *, struct svc_req *); 14207c478bd9Sstevel@tonic-gate extern int is_exported_sec(int, struct exportinfo *); 14217c478bd9Sstevel@tonic-gate extern void nfs4_vmask_to_nmask(uint_t, bitmap4 *); 14229720e166Sjasmith extern void nfs4_vmask_to_nmask_set(uint_t, bitmap4 *); 14237c478bd9Sstevel@tonic-gate extern int nfs_idmap_str_uid(utf8string *u8s, uid_t *, bool_t); 14247c478bd9Sstevel@tonic-gate extern int nfs_idmap_str_gid(utf8string *u8s, gid_t *, bool_t); 14257c478bd9Sstevel@tonic-gate extern int nfs_idmap_uid_str(uid_t, utf8string *u8s, bool_t); 14267c478bd9Sstevel@tonic-gate extern int nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t); 14277c478bd9Sstevel@tonic-gate extern int nfs4_time_ntov(nfstime4 *, timestruc_t *); 14287c478bd9Sstevel@tonic-gate extern int nfs4_time_vton(timestruc_t *, nfstime4 *); 14297c478bd9Sstevel@tonic-gate extern char *utf8_to_str(utf8string *, uint_t *, char *); 14307c478bd9Sstevel@tonic-gate extern char *utf8_to_fn(utf8string *, uint_t *, char *); 14317c478bd9Sstevel@tonic-gate extern utf8string *str_to_utf8(char *, utf8string *); 14327c478bd9Sstevel@tonic-gate extern utf8string *utf8_copy(utf8string *, utf8string *); 14337c478bd9Sstevel@tonic-gate extern int utf8_compare(const utf8string *, const utf8string *); 143415721462SDaniil Lunev extern nfsstat4 utf8_dir_verify(utf8string *); 14357c478bd9Sstevel@tonic-gate extern char *utf8_strchr(utf8string *, const char); 14367c478bd9Sstevel@tonic-gate extern int ln_ace4_cmp(nfsace4 *, nfsace4 *, int); 14377c478bd9Sstevel@tonic-gate extern int vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int); 14387c478bd9Sstevel@tonic-gate extern int vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t, 1439fa9e4066Sahrens int, int); 1440e913d9ecSLisa Week extern int vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t, 1441e913d9ecSLisa Week int); 1442fa9e4066Sahrens extern int vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int); 14437c478bd9Sstevel@tonic-gate extern void vs_acet_destroy(vsecattr_t *); 14447c478bd9Sstevel@tonic-gate extern void vs_ace4_destroy(vsecattr_t *); 14457c478bd9Sstevel@tonic-gate extern void vs_aent_destroy(vsecattr_t *); 14467c478bd9Sstevel@tonic-gate 14472f172c55SRobert Thurlow extern int vn_find_nfs_record(vnode_t *, nvlist_t **, char **, char **); 14482f172c55SRobert Thurlow extern int vn_is_nfs_reparse(vnode_t *, cred_t *); 14492f172c55SRobert Thurlow extern fs_locations4 *fetch_referral(vnode_t *, cred_t *); 14502f172c55SRobert Thurlow extern char *build_symlink(vnode_t *, cred_t *, size_t *); 14512f172c55SRobert Thurlow 14527c478bd9Sstevel@tonic-gate extern int stateid4_cmp(stateid4 *, stateid4 *); 14537c478bd9Sstevel@tonic-gate 14547c478bd9Sstevel@tonic-gate extern vtype_t nf4_to_vt[]; 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate extern struct nfs4_ntov_map nfs4_ntov_map[]; 14577c478bd9Sstevel@tonic-gate extern uint_t nfs4_ntov_map_size; 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate extern struct vfsops *nfs4_vfsops; 14607c478bd9Sstevel@tonic-gate extern struct vnodeops *nfs4_vnodeops; 14617c478bd9Sstevel@tonic-gate extern const struct fs_operation_def nfs4_vnodeops_template[]; 1462b9238976Sth extern vnodeops_t *nfs4_trigger_vnodeops; 1463b9238976Sth extern const struct fs_operation_def nfs4_trigger_vnodeops_template[]; 14647c478bd9Sstevel@tonic-gate 14657c478bd9Sstevel@tonic-gate extern uint_t nfs4_tsize(struct knetconfig *); 14667c478bd9Sstevel@tonic-gate extern uint_t rfs4_tsize(struct svc_req *); 14677c478bd9Sstevel@tonic-gate 1468eac3aab7Srobinson extern bool_t xdr_inline_decode_nfs_fh4(uint32_t *, nfs_fh4_fmt_t *, 1469eac3aab7Srobinson uint32_t); 14707c46fb7fSek extern bool_t xdr_inline_encode_nfs_fh4(uint32_t **, uint32_t *, 14717c46fb7fSek nfs_fh4_fmt_t *); 14727c46fb7fSek 14737c478bd9Sstevel@tonic-gate #ifdef DEBUG 14747c478bd9Sstevel@tonic-gate extern int rfs4_do_pre_op_attr; 14757c478bd9Sstevel@tonic-gate extern int rfs4_do_post_op_attr; 14767c478bd9Sstevel@tonic-gate #endif 14777c478bd9Sstevel@tonic-gate 14787c478bd9Sstevel@tonic-gate extern stateid4 clnt_special0; 14797c478bd9Sstevel@tonic-gate extern stateid4 clnt_special1; 14807c478bd9Sstevel@tonic-gate #define CLNT_ISSPECIAL(id) (stateid4_cmp(id, &clnt_special0) || \ 14817c478bd9Sstevel@tonic-gate stateid4_cmp(id, &clnt_special1)) 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate /* 14847c478bd9Sstevel@tonic-gate * The NFS Version 4 service procedures. 14857c478bd9Sstevel@tonic-gate */ 14867c478bd9Sstevel@tonic-gate 1487*0dfe541eSEvan Layton extern void rfs4_do_server_start(int, int, int); 14887c478bd9Sstevel@tonic-gate extern void rfs4_compound(COMPOUND4args *, COMPOUND4res *, 14892e9d26a4Srmesta struct exportinfo *, struct svc_req *, cred_t *, int *); 14907c478bd9Sstevel@tonic-gate extern void rfs4_compound_free(COMPOUND4res *); 14917c478bd9Sstevel@tonic-gate extern void rfs4_compound_flagproc(COMPOUND4args *, int *); 14927c478bd9Sstevel@tonic-gate 1493*0dfe541eSEvan Layton extern void rfs4_srvrinit(void); 14947c478bd9Sstevel@tonic-gate extern void rfs4_srvrfini(void); 1495*0dfe541eSEvan Layton extern void rfs4_srv_zone_init(nfs_globals_t *); 1496*0dfe541eSEvan Layton extern void rfs4_srv_zone_fini(nfs_globals_t *); 1497*0dfe541eSEvan Layton extern void rfs4_state_g_init(void); 1498*0dfe541eSEvan Layton extern void rfs4_state_zone_init(nfs4_srv_t *); 1499*0dfe541eSEvan Layton extern void rfs4_state_g_fini(void); 1500*0dfe541eSEvan Layton extern void rfs4_state_zone_fini(void); 1501*0dfe541eSEvan Layton extern nfs4_srv_t *nfs4_get_srv(void); 15027c478bd9Sstevel@tonic-gate 15037c478bd9Sstevel@tonic-gate #endif 15047c478bd9Sstevel@tonic-gate #ifdef __cplusplus 15057c478bd9Sstevel@tonic-gate } 15067c478bd9Sstevel@tonic-gate #endif 15077c478bd9Sstevel@tonic-gate 15087c478bd9Sstevel@tonic-gate #endif /* _NFS4_H */ 1509