1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 32*0Sstevel@tonic-gate * under license from the Regents of the University of California. 33*0Sstevel@tonic-gate */ 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #ifndef _NFS4_CLNT_H 36*0Sstevel@tonic-gate #define _NFS4_CLNT_H 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #include <sys/errno.h> 41*0Sstevel@tonic-gate #include <sys/types.h> 42*0Sstevel@tonic-gate #include <sys/kstat.h> 43*0Sstevel@tonic-gate #include <sys/time.h> 44*0Sstevel@tonic-gate #include <sys/flock.h> 45*0Sstevel@tonic-gate #include <vm/page.h> 46*0Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 47*0Sstevel@tonic-gate #include <nfs/nfs4.h> 48*0Sstevel@tonic-gate #include <nfs/rnode.h> 49*0Sstevel@tonic-gate #include <sys/avl.h> 50*0Sstevel@tonic-gate #include <sys/list.h> 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate #ifdef __cplusplus 53*0Sstevel@tonic-gate extern "C" { 54*0Sstevel@tonic-gate #endif 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate #define NFS4_SIZE_OK(size) ((size) <= MAXOFFSET_T) 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* Four states of nfs4_server's lease_valid */ 59*0Sstevel@tonic-gate #define NFS4_LEASE_INVALID 0 60*0Sstevel@tonic-gate #define NFS4_LEASE_VALID 1 61*0Sstevel@tonic-gate #define NFS4_LEASE_UNINITIALIZED 2 62*0Sstevel@tonic-gate #define NFS4_LEASE_NOT_STARTED 3 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* flag to tell the renew thread it should exit */ 65*0Sstevel@tonic-gate #define NFS4_THREAD_EXIT 1 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate /* Default number of seconds to wait on GRACE and DELAY errors */ 68*0Sstevel@tonic-gate #define NFS4ERR_DELAY_TIME 10 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate /* Number of hash buckets for open owners for each nfs4_server */ 71*0Sstevel@tonic-gate #define NFS4_NUM_OO_BUCKETS 53 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate /* Number of freed open owners (per mntinfo4_t) to keep around */ 74*0Sstevel@tonic-gate #define NFS4_NUM_FREED_OPEN_OWNERS 8 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */ 77*0Sstevel@tonic-gate #define NFS4_RETRY_SCLID_DELAY 10 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */ 80*0Sstevel@tonic-gate #define NFS4_NUM_SCLID_RETRIES 3 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */ 83*0Sstevel@tonic-gate #define NFS4_NUM_RETRY_BAD_SEQID 3 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate /* 86*0Sstevel@tonic-gate * Is the attribute cache valid? If client holds a delegation, then attrs 87*0Sstevel@tonic-gate * are by definition valid. If not, then check to see if attrs have timed out. 88*0Sstevel@tonic-gate */ 89*0Sstevel@tonic-gate #define ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \ 90*0Sstevel@tonic-gate gethrtime() < VTOR4(vp)->r_time_attr_inval) 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate /* 93*0Sstevel@tonic-gate * Flags to indicate whether to purge the DNLC for non-directory vnodes 94*0Sstevel@tonic-gate * in a call to nfs_purge_caches. 95*0Sstevel@tonic-gate */ 96*0Sstevel@tonic-gate #define NFS4_NOPURGE_DNLC 0 97*0Sstevel@tonic-gate #define NFS4_PURGE_DNLC 1 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate /* 100*0Sstevel@tonic-gate * Is cache valid? 101*0Sstevel@tonic-gate * Swap is always valid, if no attributes (attrtime == 0) or 102*0Sstevel@tonic-gate * if mtime matches cached mtime it is valid 103*0Sstevel@tonic-gate * NOTE: mtime is now a timestruc_t. 104*0Sstevel@tonic-gate * Caller should be holding the rnode r_statelock mutex. 105*0Sstevel@tonic-gate */ 106*0Sstevel@tonic-gate #define CACHE4_VALID(rp, mtime, fsize) \ 107*0Sstevel@tonic-gate ((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP || \ 108*0Sstevel@tonic-gate (((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec && \ 109*0Sstevel@tonic-gate (mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \ 110*0Sstevel@tonic-gate ((fsize) == (rp)->r_attr.va_size))) 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate /* 113*0Sstevel@tonic-gate * Macro to detect forced unmount or a zone shutdown. 114*0Sstevel@tonic-gate */ 115*0Sstevel@tonic-gate #define FS_OR_ZONE_GONE4(vfsp) \ 116*0Sstevel@tonic-gate (((vfsp)->vfs_flag & VFS_UNMOUNTED) || \ 117*0Sstevel@tonic-gate zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate /* 120*0Sstevel@tonic-gate * Macro to help determine whether a request failed because the underlying 121*0Sstevel@tonic-gate * filesystem has been forcibly unmounted or because of zone shutdown. 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate #define NFS4_FRC_UNMT_ERR(err, vfsp) \ 124*0Sstevel@tonic-gate ((err) == EIO && FS_OR_ZONE_GONE4((vfsp))) 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate /* 127*0Sstevel@tonic-gate * Due to the way the address space callbacks are used to execute a delmap, 128*0Sstevel@tonic-gate * we must keep track of how many times the same thread has called 129*0Sstevel@tonic-gate * VOP_DELMAP()->nfs4_delmap(). This is done by having a list of 130*0Sstevel@tonic-gate * nfs4_delmapcall_t's associated with each rnode4_t. This list is protected 131*0Sstevel@tonic-gate * by the rnode4_t's r_statelock. The individual elements do not need to be 132*0Sstevel@tonic-gate * protected as they will only ever be created, modified and destroyed by 133*0Sstevel@tonic-gate * one thread (the call_id). 134*0Sstevel@tonic-gate * See nfs4_delmap() for further explanation. 135*0Sstevel@tonic-gate */ 136*0Sstevel@tonic-gate typedef struct nfs4_delmapcall { 137*0Sstevel@tonic-gate kthread_t *call_id; 138*0Sstevel@tonic-gate int error; /* error from delmap */ 139*0Sstevel@tonic-gate list_node_t call_node; 140*0Sstevel@tonic-gate } nfs4_delmapcall_t; 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate /* 143*0Sstevel@tonic-gate * delmap address space callback args 144*0Sstevel@tonic-gate */ 145*0Sstevel@tonic-gate typedef struct nfs4_delmap_args { 146*0Sstevel@tonic-gate vnode_t *vp; 147*0Sstevel@tonic-gate offset_t off; 148*0Sstevel@tonic-gate caddr_t addr; 149*0Sstevel@tonic-gate size_t len; 150*0Sstevel@tonic-gate uint_t prot; 151*0Sstevel@tonic-gate uint_t maxprot; 152*0Sstevel@tonic-gate uint_t flags; 153*0Sstevel@tonic-gate cred_t *cr; 154*0Sstevel@tonic-gate nfs4_delmapcall_t *caller; /* to retrieve errors from the cb */ 155*0Sstevel@tonic-gate } nfs4_delmap_args_t; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate /* 158*0Sstevel@tonic-gate * client side statistics 159*0Sstevel@tonic-gate */ 160*0Sstevel@tonic-gate /* 161*0Sstevel@tonic-gate * Per-zone counters 162*0Sstevel@tonic-gate */ 163*0Sstevel@tonic-gate struct clstat4 { 164*0Sstevel@tonic-gate kstat_named_t calls; /* client requests */ 165*0Sstevel@tonic-gate kstat_named_t badcalls; /* rpc failures */ 166*0Sstevel@tonic-gate kstat_named_t clgets; /* client handle gets */ 167*0Sstevel@tonic-gate kstat_named_t cltoomany; /* client handle cache misses */ 168*0Sstevel@tonic-gate #ifdef DEBUG 169*0Sstevel@tonic-gate kstat_named_t clalloc; /* number of client handles */ 170*0Sstevel@tonic-gate kstat_named_t noresponse; /* server not responding cnt */ 171*0Sstevel@tonic-gate kstat_named_t failover; /* server failover count */ 172*0Sstevel@tonic-gate kstat_named_t remap; /* server remap count */ 173*0Sstevel@tonic-gate #endif 174*0Sstevel@tonic-gate }; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate #ifdef DEBUG 177*0Sstevel@tonic-gate /* 178*0Sstevel@tonic-gate * The following are statistics that describe the behavior of the system as a 179*0Sstevel@tonic-gate * whole and don't correspond to any particular zone. 180*0Sstevel@tonic-gate */ 181*0Sstevel@tonic-gate struct clstat4_debug { 182*0Sstevel@tonic-gate kstat_named_t nrnode; /* number of allocated rnodes */ 183*0Sstevel@tonic-gate kstat_named_t access; /* size of access cache */ 184*0Sstevel@tonic-gate kstat_named_t dirent; /* size of readdir cache */ 185*0Sstevel@tonic-gate kstat_named_t dirents; /* size of readdir buf cache */ 186*0Sstevel@tonic-gate kstat_named_t reclaim; /* number of reclaims */ 187*0Sstevel@tonic-gate kstat_named_t clreclaim; /* number of cl reclaims */ 188*0Sstevel@tonic-gate kstat_named_t f_reclaim; /* number of free reclaims */ 189*0Sstevel@tonic-gate kstat_named_t a_reclaim; /* number of active reclaims */ 190*0Sstevel@tonic-gate kstat_named_t r_reclaim; /* number of rnode reclaims */ 191*0Sstevel@tonic-gate kstat_named_t rpath; /* bytes used to store rpaths */ 192*0Sstevel@tonic-gate }; 193*0Sstevel@tonic-gate extern struct clstat4_debug clstat4_debug; 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate #endif 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate /* 198*0Sstevel@tonic-gate * The NFS specific async_reqs structure. 199*0Sstevel@tonic-gate */ 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate enum iotype4 { 202*0Sstevel@tonic-gate NFS4_READ_AHEAD, 203*0Sstevel@tonic-gate NFS4_PUTAPAGE, 204*0Sstevel@tonic-gate NFS4_PAGEIO, 205*0Sstevel@tonic-gate NFS4_READDIR, 206*0Sstevel@tonic-gate NFS4_INACTIVE, 207*0Sstevel@tonic-gate NFS4_COMMIT 208*0Sstevel@tonic-gate }; 209*0Sstevel@tonic-gate #define NFS4_ASYNC_TYPES (NFS4_COMMIT + 1) 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate struct nfs4_async_read_req { 212*0Sstevel@tonic-gate void (*readahead)(); /* pointer to readahead function */ 213*0Sstevel@tonic-gate u_offset_t blkoff; /* offset in file */ 214*0Sstevel@tonic-gate struct seg *seg; /* segment to do i/o to */ 215*0Sstevel@tonic-gate caddr_t addr; /* address to do i/o to */ 216*0Sstevel@tonic-gate }; 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate struct nfs4_pageio_req { 219*0Sstevel@tonic-gate int (*pageio)(); /* pointer to pageio function */ 220*0Sstevel@tonic-gate page_t *pp; /* page list */ 221*0Sstevel@tonic-gate u_offset_t io_off; /* offset in file */ 222*0Sstevel@tonic-gate uint_t io_len; /* size of request */ 223*0Sstevel@tonic-gate int flags; 224*0Sstevel@tonic-gate }; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate struct nfs4_readdir_req { 227*0Sstevel@tonic-gate int (*readdir)(); /* pointer to readdir function */ 228*0Sstevel@tonic-gate struct rddir4_cache *rdc; /* pointer to cache entry to fill */ 229*0Sstevel@tonic-gate }; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate struct nfs4_commit_req { 232*0Sstevel@tonic-gate void (*commit)(); /* pointer to commit function */ 233*0Sstevel@tonic-gate page_t *plist; /* page list */ 234*0Sstevel@tonic-gate offset4 offset; /* starting offset */ 235*0Sstevel@tonic-gate count4 count; /* size of range to be commited */ 236*0Sstevel@tonic-gate }; 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate struct nfs4_async_reqs { 239*0Sstevel@tonic-gate struct nfs4_async_reqs *a_next; /* pointer to next arg struct */ 240*0Sstevel@tonic-gate #ifdef DEBUG 241*0Sstevel@tonic-gate kthread_t *a_queuer; /* thread id of queueing thread */ 242*0Sstevel@tonic-gate #endif 243*0Sstevel@tonic-gate struct vnode *a_vp; /* vnode pointer */ 244*0Sstevel@tonic-gate struct cred *a_cred; /* cred pointer */ 245*0Sstevel@tonic-gate enum iotype4 a_io; /* i/o type */ 246*0Sstevel@tonic-gate union { 247*0Sstevel@tonic-gate struct nfs4_async_read_req a_read_args; 248*0Sstevel@tonic-gate struct nfs4_pageio_req a_pageio_args; 249*0Sstevel@tonic-gate struct nfs4_readdir_req a_readdir_args; 250*0Sstevel@tonic-gate struct nfs4_commit_req a_commit_args; 251*0Sstevel@tonic-gate } a_args; 252*0Sstevel@tonic-gate }; 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate #define a_nfs4_readahead a_args.a_read_args.readahead 255*0Sstevel@tonic-gate #define a_nfs4_blkoff a_args.a_read_args.blkoff 256*0Sstevel@tonic-gate #define a_nfs4_seg a_args.a_read_args.seg 257*0Sstevel@tonic-gate #define a_nfs4_addr a_args.a_read_args.addr 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate #define a_nfs4_putapage a_args.a_pageio_args.pageio 260*0Sstevel@tonic-gate #define a_nfs4_pageio a_args.a_pageio_args.pageio 261*0Sstevel@tonic-gate #define a_nfs4_pp a_args.a_pageio_args.pp 262*0Sstevel@tonic-gate #define a_nfs4_off a_args.a_pageio_args.io_off 263*0Sstevel@tonic-gate #define a_nfs4_len a_args.a_pageio_args.io_len 264*0Sstevel@tonic-gate #define a_nfs4_flags a_args.a_pageio_args.flags 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate #define a_nfs4_readdir a_args.a_readdir_args.readdir 267*0Sstevel@tonic-gate #define a_nfs4_rdc a_args.a_readdir_args.rdc 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate #define a_nfs4_commit a_args.a_commit_args.commit 270*0Sstevel@tonic-gate #define a_nfs4_plist a_args.a_commit_args.plist 271*0Sstevel@tonic-gate #define a_nfs4_offset a_args.a_commit_args.offset 272*0Sstevel@tonic-gate #define a_nfs4_count a_args.a_commit_args.count 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate /* 275*0Sstevel@tonic-gate * Security information 276*0Sstevel@tonic-gate */ 277*0Sstevel@tonic-gate typedef struct sv_secinfo { 278*0Sstevel@tonic-gate uint_t count; /* how many sdata there are */ 279*0Sstevel@tonic-gate uint_t index; /* which sdata[index] */ 280*0Sstevel@tonic-gate struct sec_data *sdata; 281*0Sstevel@tonic-gate } sv_secinfo_t; 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* 284*0Sstevel@tonic-gate * Hash bucket for the mi's open owner list (mi_oo_list). 285*0Sstevel@tonic-gate */ 286*0Sstevel@tonic-gate typedef struct nfs4_oo_hash_bucket { 287*0Sstevel@tonic-gate list_t b_oo_hash_list; 288*0Sstevel@tonic-gate kmutex_t b_lock; 289*0Sstevel@tonic-gate } nfs4_oo_hash_bucket_t; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate /* 292*0Sstevel@tonic-gate * Global array of ctags. 293*0Sstevel@tonic-gate */ 294*0Sstevel@tonic-gate extern ctag_t nfs4_ctags[]; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate typedef enum nfs4_tag_type { 297*0Sstevel@tonic-gate TAG_NONE, 298*0Sstevel@tonic-gate TAG_ACCESS, 299*0Sstevel@tonic-gate TAG_CLOSE, 300*0Sstevel@tonic-gate TAG_CLOSE_LOST, 301*0Sstevel@tonic-gate TAG_CLOSE_UNDO, 302*0Sstevel@tonic-gate TAG_COMMIT, 303*0Sstevel@tonic-gate TAG_DELEGRETURN, 304*0Sstevel@tonic-gate TAG_FSINFO, 305*0Sstevel@tonic-gate TAG_GET_SYMLINK, 306*0Sstevel@tonic-gate TAG_GETATTR, 307*0Sstevel@tonic-gate TAG_INACTIVE, 308*0Sstevel@tonic-gate TAG_LINK, 309*0Sstevel@tonic-gate TAG_LOCK, 310*0Sstevel@tonic-gate TAG_LOCK_RECLAIM, 311*0Sstevel@tonic-gate TAG_LOCK_RESEND, 312*0Sstevel@tonic-gate TAG_LOCK_REINSTATE, 313*0Sstevel@tonic-gate TAG_LOCK_UNKNOWN, 314*0Sstevel@tonic-gate TAG_LOCKT, 315*0Sstevel@tonic-gate TAG_LOCKU, 316*0Sstevel@tonic-gate TAG_LOCKU_RESEND, 317*0Sstevel@tonic-gate TAG_LOCKU_REINSTATE, 318*0Sstevel@tonic-gate TAG_LOOKUP, 319*0Sstevel@tonic-gate TAG_LOOKUP_PARENT, 320*0Sstevel@tonic-gate TAG_LOOKUP_VALID, 321*0Sstevel@tonic-gate TAG_LOOKUP_VPARENT, 322*0Sstevel@tonic-gate TAG_MKDIR, 323*0Sstevel@tonic-gate TAG_MKNOD, 324*0Sstevel@tonic-gate TAG_MOUNT, 325*0Sstevel@tonic-gate TAG_OPEN, 326*0Sstevel@tonic-gate TAG_OPEN_CONFIRM, 327*0Sstevel@tonic-gate TAG_OPEN_CONFIRM_LOST, 328*0Sstevel@tonic-gate TAG_OPEN_DG, 329*0Sstevel@tonic-gate TAG_OPEN_DG_LOST, 330*0Sstevel@tonic-gate TAG_OPEN_LOST, 331*0Sstevel@tonic-gate TAG_OPENATTR, 332*0Sstevel@tonic-gate TAG_PATHCONF, 333*0Sstevel@tonic-gate TAG_PUTROOTFH, 334*0Sstevel@tonic-gate TAG_READ, 335*0Sstevel@tonic-gate TAG_READAHEAD, 336*0Sstevel@tonic-gate TAG_READDIR, 337*0Sstevel@tonic-gate TAG_READLINK, 338*0Sstevel@tonic-gate TAG_RELOCK, 339*0Sstevel@tonic-gate TAG_REMAP_LOOKUP, 340*0Sstevel@tonic-gate TAG_REMAP_LOOKUP_AD, 341*0Sstevel@tonic-gate TAG_REMAP_LOOKUP_NA, 342*0Sstevel@tonic-gate TAG_REMAP_MOUNT, 343*0Sstevel@tonic-gate TAG_RMDIR, 344*0Sstevel@tonic-gate TAG_REMOVE, 345*0Sstevel@tonic-gate TAG_RENAME, 346*0Sstevel@tonic-gate TAG_RENAME_VFH, 347*0Sstevel@tonic-gate TAG_RENEW, 348*0Sstevel@tonic-gate TAG_REOPEN, 349*0Sstevel@tonic-gate TAG_REOPEN_LOST, 350*0Sstevel@tonic-gate TAG_SECINFO, 351*0Sstevel@tonic-gate TAG_SETATTR, 352*0Sstevel@tonic-gate TAG_SETCLIENTID, 353*0Sstevel@tonic-gate TAG_SETCLIENTID_CF, 354*0Sstevel@tonic-gate TAG_SYMLINK, 355*0Sstevel@tonic-gate TAG_WRITE 356*0Sstevel@tonic-gate } nfs4_tag_type_t; 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate #define NFS4_TAG_INITIALIZER { \ 359*0Sstevel@tonic-gate {TAG_NONE, "", \ 360*0Sstevel@tonic-gate {0x20202020, 0x20202020, 0x20202020}}, \ 361*0Sstevel@tonic-gate {TAG_ACCESS, "access", \ 362*0Sstevel@tonic-gate {0x61636365, 0x73732020, 0x20202020}}, \ 363*0Sstevel@tonic-gate {TAG_CLOSE, "close", \ 364*0Sstevel@tonic-gate {0x636c6f73, 0x65202020, 0x20202020}}, \ 365*0Sstevel@tonic-gate {TAG_CLOSE_LOST, "lost close", \ 366*0Sstevel@tonic-gate {0x6c6f7374, 0x20636c6f, 0x73652020}}, \ 367*0Sstevel@tonic-gate {TAG_CLOSE_UNDO, "undo close", \ 368*0Sstevel@tonic-gate {0x756e646f, 0x20636c6f, 0x73652020}}, \ 369*0Sstevel@tonic-gate {TAG_COMMIT, "commit", \ 370*0Sstevel@tonic-gate {0x636f6d6d, 0x69742020, 0x20202020}}, \ 371*0Sstevel@tonic-gate {TAG_DELEGRETURN, "delegreturn", \ 372*0Sstevel@tonic-gate {0x64656c65, 0x67726574, 0x75726e20}}, \ 373*0Sstevel@tonic-gate {TAG_FSINFO, "fsinfo", \ 374*0Sstevel@tonic-gate {0x6673696e, 0x666f2020, 0x20202020}}, \ 375*0Sstevel@tonic-gate {TAG_GET_SYMLINK, "get symlink text", \ 376*0Sstevel@tonic-gate {0x67657420, 0x736c6e6b, 0x20747874}}, \ 377*0Sstevel@tonic-gate {TAG_GETATTR, "getattr", \ 378*0Sstevel@tonic-gate {0x67657461, 0x74747220, 0x20202020}}, \ 379*0Sstevel@tonic-gate {TAG_INACTIVE, "inactive", \ 380*0Sstevel@tonic-gate {0x696e6163, 0x74697665, 0x20202020}}, \ 381*0Sstevel@tonic-gate {TAG_LINK, "link", \ 382*0Sstevel@tonic-gate {0x6c696e6b, 0x20202020, 0x20202020}}, \ 383*0Sstevel@tonic-gate {TAG_LOCK, "lock", \ 384*0Sstevel@tonic-gate {0x6c6f636b, 0x20202020, 0x20202020}}, \ 385*0Sstevel@tonic-gate {TAG_LOCK_RECLAIM, "reclaim lock", \ 386*0Sstevel@tonic-gate {0x7265636c, 0x61696d20, 0x6c6f636b}}, \ 387*0Sstevel@tonic-gate {TAG_LOCK_RESEND, "resend lock", \ 388*0Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b20}}, \ 389*0Sstevel@tonic-gate {TAG_LOCK_REINSTATE, "reinstate lock", \ 390*0Sstevel@tonic-gate {0x7265696e, 0x7374206c, 0x6f636b20}}, \ 391*0Sstevel@tonic-gate {TAG_LOCK_UNKNOWN, "unknown lock", \ 392*0Sstevel@tonic-gate {0x756e6b6e, 0x6f776e20, 0x6c6f636b}}, \ 393*0Sstevel@tonic-gate {TAG_LOCKT, "lock test", \ 394*0Sstevel@tonic-gate {0x6c6f636b, 0x5f746573, 0x74202020}}, \ 395*0Sstevel@tonic-gate {TAG_LOCKU, "unlock", \ 396*0Sstevel@tonic-gate {0x756e6c6f, 0x636b2020, 0x20202020}}, \ 397*0Sstevel@tonic-gate {TAG_LOCKU_RESEND, "resend locku", \ 398*0Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b75}}, \ 399*0Sstevel@tonic-gate {TAG_LOCKU_REINSTATE, "reinstate unlock", \ 400*0Sstevel@tonic-gate {0x7265696e, 0x73742075, 0x6e6c636b}}, \ 401*0Sstevel@tonic-gate {TAG_LOOKUP, "lookup", \ 402*0Sstevel@tonic-gate {0x6c6f6f6b, 0x75702020, 0x20202020}}, \ 403*0Sstevel@tonic-gate {TAG_LOOKUP_PARENT, "lookup parent", \ 404*0Sstevel@tonic-gate {0x6c6f6f6b, 0x75702070, 0x6172656e}}, \ 405*0Sstevel@tonic-gate {TAG_LOOKUP_VALID, "lookup valid", \ 406*0Sstevel@tonic-gate {0x6c6f6f6b, 0x75702076, 0x616c6964}}, \ 407*0Sstevel@tonic-gate {TAG_LOOKUP_VPARENT, "lookup valid parent", \ 408*0Sstevel@tonic-gate {0x6c6f6f6b, 0x766c6420, 0x7061726e}}, \ 409*0Sstevel@tonic-gate {TAG_MKDIR, "mkdir", \ 410*0Sstevel@tonic-gate {0x6d6b6469, 0x72202020, 0x20202020}}, \ 411*0Sstevel@tonic-gate {TAG_MKNOD, "mknod", \ 412*0Sstevel@tonic-gate {0x6d6b6e6f, 0x64202020, 0x20202020}}, \ 413*0Sstevel@tonic-gate {TAG_MOUNT, "mount", \ 414*0Sstevel@tonic-gate {0x6d6f756e, 0x74202020, 0x20202020}}, \ 415*0Sstevel@tonic-gate {TAG_OPEN, "open", \ 416*0Sstevel@tonic-gate {0x6f70656e, 0x20202020, 0x20202020}}, \ 417*0Sstevel@tonic-gate {TAG_OPEN_CONFIRM, "open confirm", \ 418*0Sstevel@tonic-gate {0x6f70656e, 0x5f636f6e, 0x6669726d}}, \ 419*0Sstevel@tonic-gate {TAG_OPEN_CONFIRM_LOST, "lost open confirm", \ 420*0Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e5f636f}}, \ 421*0Sstevel@tonic-gate {TAG_OPEN_DG, "open downgrade", \ 422*0Sstevel@tonic-gate {0x6f70656e, 0x20646772, 0x61646520}}, \ 423*0Sstevel@tonic-gate {TAG_OPEN_DG_LOST, "lost open downgrade", \ 424*0Sstevel@tonic-gate {0x6c737420, 0x6f70656e, 0x20646772}}, \ 425*0Sstevel@tonic-gate {TAG_OPEN_LOST, "lost open", \ 426*0Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e202020}}, \ 427*0Sstevel@tonic-gate {TAG_OPENATTR, "openattr", \ 428*0Sstevel@tonic-gate {0x6f70656e, 0x61747472, 0x20202020}}, \ 429*0Sstevel@tonic-gate {TAG_PATHCONF, "pathhconf", \ 430*0Sstevel@tonic-gate {0x70617468, 0x636f6e66, 0x20202020}}, \ 431*0Sstevel@tonic-gate {TAG_PUTROOTFH, "putrootfh", \ 432*0Sstevel@tonic-gate {0x70757472, 0x6f6f7466, 0x68202020}}, \ 433*0Sstevel@tonic-gate {TAG_READ, "read", \ 434*0Sstevel@tonic-gate {0x72656164, 0x20202020, 0x20202020}}, \ 435*0Sstevel@tonic-gate {TAG_READAHEAD, "readahead", \ 436*0Sstevel@tonic-gate {0x72656164, 0x61686561, 0x64202020}}, \ 437*0Sstevel@tonic-gate {TAG_READDIR, "readdir", \ 438*0Sstevel@tonic-gate {0x72656164, 0x64697220, 0x20202020}}, \ 439*0Sstevel@tonic-gate {TAG_READLINK, "readlink", \ 440*0Sstevel@tonic-gate {0x72656164, 0x6c696e6b, 0x20202020}}, \ 441*0Sstevel@tonic-gate {TAG_RELOCK, "relock", \ 442*0Sstevel@tonic-gate {0x72656c6f, 0x636b2020, 0x20202020}}, \ 443*0Sstevel@tonic-gate {TAG_REMAP_LOOKUP, "remap lookup", \ 444*0Sstevel@tonic-gate {0x72656d61, 0x70206c6f, 0x6f6b7570}}, \ 445*0Sstevel@tonic-gate {TAG_REMAP_LOOKUP_AD, "remap lookup attr dir", \ 446*0Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206164}}, \ 447*0Sstevel@tonic-gate {TAG_REMAP_LOOKUP_NA, "remap lookup named attrs", \ 448*0Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206e61}}, \ 449*0Sstevel@tonic-gate {TAG_REMAP_MOUNT, "remap mount", \ 450*0Sstevel@tonic-gate {0x72656d61, 0x70206d6f, 0x756e7420}}, \ 451*0Sstevel@tonic-gate {TAG_RMDIR, "rmdir", \ 452*0Sstevel@tonic-gate {0x726d6469, 0x72202020, 0x20202020}}, \ 453*0Sstevel@tonic-gate {TAG_REMOVE, "remove", \ 454*0Sstevel@tonic-gate {0x72656d6f, 0x76652020, 0x20202020}}, \ 455*0Sstevel@tonic-gate {TAG_RENAME, "rename", \ 456*0Sstevel@tonic-gate {0x72656e61, 0x6d652020, 0x20202020}}, \ 457*0Sstevel@tonic-gate {TAG_RENAME_VFH, "rename volatile fh", \ 458*0Sstevel@tonic-gate {0x72656e61, 0x6d652028, 0x76666829}}, \ 459*0Sstevel@tonic-gate {TAG_RENEW, "renew", \ 460*0Sstevel@tonic-gate {0x72656e65, 0x77202020, 0x20202020}}, \ 461*0Sstevel@tonic-gate {TAG_REOPEN, "reopen", \ 462*0Sstevel@tonic-gate {0x72656f70, 0x656e2020, 0x20202020}}, \ 463*0Sstevel@tonic-gate {TAG_REOPEN_LOST, "lost reopen", \ 464*0Sstevel@tonic-gate {0x6c6f7374, 0x2072656f, 0x70656e20}}, \ 465*0Sstevel@tonic-gate {TAG_SECINFO, "secinfo", \ 466*0Sstevel@tonic-gate {0x73656369, 0x6e666f20, 0x20202020}}, \ 467*0Sstevel@tonic-gate {TAG_SETATTR, "setattr", \ 468*0Sstevel@tonic-gate {0x73657461, 0x74747220, 0x20202020}}, \ 469*0Sstevel@tonic-gate {TAG_SETCLIENTID, "setclientid", \ 470*0Sstevel@tonic-gate {0x73657463, 0x6c69656e, 0x74696420}}, \ 471*0Sstevel@tonic-gate {TAG_SETCLIENTID_CF, "setclientid_confirm", \ 472*0Sstevel@tonic-gate {0x73636c6e, 0x7469645f, 0x636f6e66}}, \ 473*0Sstevel@tonic-gate {TAG_SYMLINK, "symlink", \ 474*0Sstevel@tonic-gate {0x73796d6c, 0x696e6b20, 0x20202020}}, \ 475*0Sstevel@tonic-gate {TAG_WRITE, "write", \ 476*0Sstevel@tonic-gate {0x77726974, 0x65202020, 0x20202020}} \ 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate /* 480*0Sstevel@tonic-gate * These flags are for differentiating the search criterian for 481*0Sstevel@tonic-gate * find_open_owner(). The comparison is done with the open_owners's 482*0Sstevel@tonic-gate * 'oo_just_created' flag. 483*0Sstevel@tonic-gate */ 484*0Sstevel@tonic-gate #define NFS4_PERM_CREATED 0x0 485*0Sstevel@tonic-gate #define NFS4_JUST_CREATED 0x1 486*0Sstevel@tonic-gate 487*0Sstevel@tonic-gate /* 488*0Sstevel@tonic-gate * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw' 489*0Sstevel@tonic-gate * is stored upon a successful OPEN. This is needed when the user's effective 490*0Sstevel@tonic-gate * and real uid's don't match. The 'oo_cred_otw' overrides the credential 491*0Sstevel@tonic-gate * passed down by VFS for async read/write, commit, lock, and close operations. 492*0Sstevel@tonic-gate * 493*0Sstevel@tonic-gate * The oo_ref_count keeps track the number of active references on this 494*0Sstevel@tonic-gate * data structure + number of nfs4_open_streams point to this structure. 495*0Sstevel@tonic-gate * 496*0Sstevel@tonic-gate * 'oo_valid' tells whether this stuct is about to be freed or not. 497*0Sstevel@tonic-gate * 498*0Sstevel@tonic-gate * 'oo_just_created' tells us whether this struct has just been created but 499*0Sstevel@tonic-gate * not been fully finalized (that is created upon an OPEN request and 500*0Sstevel@tonic-gate * finalized upon the OPEN success). 501*0Sstevel@tonic-gate * 502*0Sstevel@tonic-gate * The 'oo_seqid_inuse' is for the open seqid synchronization. If a thread 503*0Sstevel@tonic-gate * is currently using the open owner and it's open_seqid, then it sets the 504*0Sstevel@tonic-gate * oo_seqid_inuse to true if it currently is not set. If it is set then it 505*0Sstevel@tonic-gate * does a cv_wait on the oo_cv_seqid_sync condition variable. When the thread 506*0Sstevel@tonic-gate * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process 507*0Sstevel@tonic-gate * waiting on the condition variable. 508*0Sstevel@tonic-gate * 509*0Sstevel@tonic-gate * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW, 510*0Sstevel@tonic-gate * and 'oo_last_good_op' is the operation that issued the last valid seqid. 511*0Sstevel@tonic-gate * 512*0Sstevel@tonic-gate * Lock ordering: 513*0Sstevel@tonic-gate * mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list) 514*0Sstevel@tonic-gate * 515*0Sstevel@tonic-gate * oo_seqid_inuse > mntinfo4_t::mi_lock 516*0Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statelock 517*0Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statev4_lock 518*0Sstevel@tonic-gate * oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock 519*0Sstevel@tonic-gate * 520*0Sstevel@tonic-gate * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects: 521*0Sstevel@tonic-gate * oo_last_good_op 522*0Sstevel@tonic-gate * oo_last_good_seqid 523*0Sstevel@tonic-gate * oo_name 524*0Sstevel@tonic-gate * oo_seqid 525*0Sstevel@tonic-gate * 526*0Sstevel@tonic-gate * The 'oo_lock' protects: 527*0Sstevel@tonic-gate * oo_cred 528*0Sstevel@tonic-gate * oo_cred_otw 529*0Sstevel@tonic-gate * oo_foo_node 530*0Sstevel@tonic-gate * oo_hash_node 531*0Sstevel@tonic-gate * oo_just_created 532*0Sstevel@tonic-gate * oo_ref_count 533*0Sstevel@tonic-gate * oo_valid 534*0Sstevel@tonic-gate */ 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gate typedef struct nfs4_open_owner { 537*0Sstevel@tonic-gate cred_t *oo_cred; 538*0Sstevel@tonic-gate int oo_ref_count; 539*0Sstevel@tonic-gate int oo_valid; 540*0Sstevel@tonic-gate int oo_just_created; 541*0Sstevel@tonic-gate seqid4 oo_seqid; 542*0Sstevel@tonic-gate seqid4 oo_last_good_seqid; 543*0Sstevel@tonic-gate nfs4_tag_type_t oo_last_good_op; 544*0Sstevel@tonic-gate unsigned oo_seqid_inuse:1; 545*0Sstevel@tonic-gate cred_t *oo_cred_otw; 546*0Sstevel@tonic-gate kcondvar_t oo_cv_seqid_sync; 547*0Sstevel@tonic-gate /* 548*0Sstevel@tonic-gate * Fix this to always be 8 bytes 549*0Sstevel@tonic-gate */ 550*0Sstevel@tonic-gate uint64_t oo_name; 551*0Sstevel@tonic-gate list_node_t oo_hash_node; 552*0Sstevel@tonic-gate list_node_t oo_foo_node; 553*0Sstevel@tonic-gate kmutex_t oo_lock; 554*0Sstevel@tonic-gate } nfs4_open_owner_t; 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate /* 557*0Sstevel@tonic-gate * Static server information. 558*0Sstevel@tonic-gate * These fields are read-only once they are initialized: 559*0Sstevel@tonic-gate * sv_addr 560*0Sstevel@tonic-gate * sv_dhsec 561*0Sstevel@tonic-gate * sv_hostname 562*0Sstevel@tonic-gate * sv_hostnamelen 563*0Sstevel@tonic-gate * sv_knconf 564*0Sstevel@tonic-gate * sv_next 565*0Sstevel@tonic-gate * sv_origknconf 566*0Sstevel@tonic-gate * 567*0Sstevel@tonic-gate * These fields are protected by sv_lock: 568*0Sstevel@tonic-gate * sv_currsec 569*0Sstevel@tonic-gate * sv_fhandle 570*0Sstevel@tonic-gate * sv_flags 571*0Sstevel@tonic-gate * sv_fsid 572*0Sstevel@tonic-gate * sv_path 573*0Sstevel@tonic-gate * sv_pathlen 574*0Sstevel@tonic-gate * sv_pfhandle 575*0Sstevel@tonic-gate * sv_save_secinfo 576*0Sstevel@tonic-gate * sv_savesec 577*0Sstevel@tonic-gate * sv_secdata 578*0Sstevel@tonic-gate * sv_secinfo 579*0Sstevel@tonic-gate * sv_supp_attrs 580*0Sstevel@tonic-gate * 581*0Sstevel@tonic-gate * Lock ordering: 582*0Sstevel@tonic-gate * nfs_rtable4_lock > sv_lock 583*0Sstevel@tonic-gate * rnode4_t::r_statelock > sv_lock 584*0Sstevel@tonic-gate */ 585*0Sstevel@tonic-gate typedef struct servinfo4 { 586*0Sstevel@tonic-gate struct knetconfig *sv_knconf; /* bound TLI fd */ 587*0Sstevel@tonic-gate struct knetconfig *sv_origknconf; /* For RDMA save orig knconf */ 588*0Sstevel@tonic-gate struct netbuf sv_addr; /* server's address */ 589*0Sstevel@tonic-gate nfs4_fhandle_t sv_fhandle; /* this server's filehandle */ 590*0Sstevel@tonic-gate nfs4_fhandle_t sv_pfhandle; /* parent dir filehandle */ 591*0Sstevel@tonic-gate int sv_pathlen; /* Length of server path */ 592*0Sstevel@tonic-gate char *sv_path; /* Path name on server */ 593*0Sstevel@tonic-gate uint32_t sv_flags; /* flags for this server */ 594*0Sstevel@tonic-gate sec_data_t *sv_secdata; /* client initiated security data */ 595*0Sstevel@tonic-gate sv_secinfo_t *sv_secinfo; /* server security information */ 596*0Sstevel@tonic-gate sec_data_t *sv_currsec; /* security data currently used; */ 597*0Sstevel@tonic-gate /* points to one of the sec_data */ 598*0Sstevel@tonic-gate /* entries in sv_secinfo */ 599*0Sstevel@tonic-gate sv_secinfo_t *sv_save_secinfo; /* saved secinfo */ 600*0Sstevel@tonic-gate sec_data_t *sv_savesec; /* saved security data */ 601*0Sstevel@tonic-gate sec_data_t *sv_dhsec; /* AUTH_DH data from the user land */ 602*0Sstevel@tonic-gate char *sv_hostname; /* server's hostname */ 603*0Sstevel@tonic-gate int sv_hostnamelen; /* server's hostname length */ 604*0Sstevel@tonic-gate fattr4_fsid sv_fsid; /* fsid of shared obj */ 605*0Sstevel@tonic-gate fattr4_supported_attrs sv_supp_attrs; 606*0Sstevel@tonic-gate struct servinfo4 *sv_next; /* next in list */ 607*0Sstevel@tonic-gate nfs_rwlock_t sv_lock; 608*0Sstevel@tonic-gate } servinfo4_t; 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate /* sv_flags fields */ 611*0Sstevel@tonic-gate #define SV4_TRYSECINFO 0x001 /* try secinfo data from the server */ 612*0Sstevel@tonic-gate #define SV4_TRYSECDEFAULT 0x002 /* try a default flavor */ 613*0Sstevel@tonic-gate #define SV4_NOTINUSE 0x004 /* servinfo4_t had fatal errors */ 614*0Sstevel@tonic-gate #define SV4_ROOT_STALE 0x008 /* root vnode got ESTALE */ 615*0Sstevel@tonic-gate 616*0Sstevel@tonic-gate /* 617*0Sstevel@tonic-gate * Lock call types. See nfs4frlock(). 618*0Sstevel@tonic-gate */ 619*0Sstevel@tonic-gate typedef enum nfs4_lock_call_type { 620*0Sstevel@tonic-gate NFS4_LCK_CTYPE_NORM, 621*0Sstevel@tonic-gate NFS4_LCK_CTYPE_RECLAIM, 622*0Sstevel@tonic-gate NFS4_LCK_CTYPE_RESEND, 623*0Sstevel@tonic-gate NFS4_LCK_CTYPE_REINSTATE 624*0Sstevel@tonic-gate } nfs4_lock_call_type_t; 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate /* 627*0Sstevel@tonic-gate * This structure holds the information for a lost open/close/open downgrade/ 628*0Sstevel@tonic-gate * lock/locku request. It is also used for requests that are queued up so 629*0Sstevel@tonic-gate * that the recovery thread can release server state after a forced 630*0Sstevel@tonic-gate * unmount. 631*0Sstevel@tonic-gate * "lr_op" is 0 if the struct is uninitialized. Otherwise, it is set to 632*0Sstevel@tonic-gate * the proper OP_* nfs_opnum4 number. The other fields contain information 633*0Sstevel@tonic-gate * to reconstruct the call. 634*0Sstevel@tonic-gate * 635*0Sstevel@tonic-gate * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the 636*0Sstevel@tonic-gate * parent directroy without relying on vtodv (since we may not have a vp 637*0Sstevel@tonic-gate * for the file we wish to create). 638*0Sstevel@tonic-gate * 639*0Sstevel@tonic-gate * lr_putfirst means that the request should go to the front of the resend 640*0Sstevel@tonic-gate * queue, rather than the end. 641*0Sstevel@tonic-gate */ 642*0Sstevel@tonic-gate typedef struct nfs4_lost_rqst { 643*0Sstevel@tonic-gate list_node_t lr_node; 644*0Sstevel@tonic-gate nfs_opnum4 lr_op; 645*0Sstevel@tonic-gate vnode_t *lr_vp; 646*0Sstevel@tonic-gate vnode_t *lr_dvp; 647*0Sstevel@tonic-gate nfs4_open_owner_t *lr_oop; 648*0Sstevel@tonic-gate struct nfs4_open_stream *lr_osp; 649*0Sstevel@tonic-gate struct nfs4_lock_owner *lr_lop; 650*0Sstevel@tonic-gate cred_t *lr_cr; 651*0Sstevel@tonic-gate flock64_t *lr_flk; 652*0Sstevel@tonic-gate bool_t lr_putfirst; 653*0Sstevel@tonic-gate union { 654*0Sstevel@tonic-gate struct { 655*0Sstevel@tonic-gate nfs4_lock_call_type_t lru_ctype; 656*0Sstevel@tonic-gate nfs_lock_type4 lru_locktype; 657*0Sstevel@tonic-gate } lru_lockargs; /* LOCK, LOCKU */ 658*0Sstevel@tonic-gate struct { 659*0Sstevel@tonic-gate uint32_t lru_oaccess; 660*0Sstevel@tonic-gate uint32_t lru_odeny; 661*0Sstevel@tonic-gate enum open_claim_type4 lru_oclaim; 662*0Sstevel@tonic-gate stateid4 lru_ostateid; /* reopen only */ 663*0Sstevel@tonic-gate component4 lru_ofile; 664*0Sstevel@tonic-gate } lru_open_args; 665*0Sstevel@tonic-gate struct { 666*0Sstevel@tonic-gate uint32_t lru_dg_access; 667*0Sstevel@tonic-gate uint32_t lru_dg_deny; 668*0Sstevel@tonic-gate } lru_open_dg_args; 669*0Sstevel@tonic-gate } nfs4_lr_u; 670*0Sstevel@tonic-gate } nfs4_lost_rqst_t; 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate #define lr_oacc nfs4_lr_u.lru_open_args.lru_oaccess 673*0Sstevel@tonic-gate #define lr_odeny nfs4_lr_u.lru_open_args.lru_odeny 674*0Sstevel@tonic-gate #define lr_oclaim nfs4_lr_u.lru_open_args.lru_oclaim 675*0Sstevel@tonic-gate #define lr_ostateid nfs4_lr_u.lru_open_args.lru_ostateid 676*0Sstevel@tonic-gate #define lr_ofile nfs4_lr_u.lru_open_args.lru_ofile 677*0Sstevel@tonic-gate #define lr_dg_acc nfs4_lr_u.lru_open_dg_args.lru_dg_access 678*0Sstevel@tonic-gate #define lr_dg_deny nfs4_lr_u.lru_open_dg_args.lru_dg_deny 679*0Sstevel@tonic-gate #define lr_ctype nfs4_lr_u.lru_lockargs.lru_ctype 680*0Sstevel@tonic-gate #define lr_locktype nfs4_lr_u.lru_lockargs.lru_locktype 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate /* 683*0Sstevel@tonic-gate * Recovery actions. Some actions can imply further recovery using a 684*0Sstevel@tonic-gate * different recovery action (e.g., recovering the clientid leads to 685*0Sstevel@tonic-gate * recovering open files and locks). 686*0Sstevel@tonic-gate */ 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate typedef enum { 689*0Sstevel@tonic-gate NR_UNUSED, 690*0Sstevel@tonic-gate NR_CLIENTID, 691*0Sstevel@tonic-gate NR_OPENFILES, 692*0Sstevel@tonic-gate NR_FHEXPIRED, 693*0Sstevel@tonic-gate NR_FAILOVER, 694*0Sstevel@tonic-gate NR_WRONGSEC, 695*0Sstevel@tonic-gate NR_EXPIRED, 696*0Sstevel@tonic-gate NR_BAD_STATEID, 697*0Sstevel@tonic-gate NR_BADHANDLE, 698*0Sstevel@tonic-gate NR_BAD_SEQID, 699*0Sstevel@tonic-gate NR_OLDSTATEID, 700*0Sstevel@tonic-gate NR_GRACE, 701*0Sstevel@tonic-gate NR_DELAY, 702*0Sstevel@tonic-gate NR_LOST_LOCK, 703*0Sstevel@tonic-gate NR_LOST_STATE_RQST, 704*0Sstevel@tonic-gate NR_STALE 705*0Sstevel@tonic-gate } nfs4_recov_t; 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate /* 708*0Sstevel@tonic-gate * Administrative and debug message framework. 709*0Sstevel@tonic-gate */ 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gate #define NFS4_MSG_MAX 100 712*0Sstevel@tonic-gate extern int nfs4_msg_max; 713*0Sstevel@tonic-gate 714*0Sstevel@tonic-gate typedef enum { 715*0Sstevel@tonic-gate RE_BAD_SEQID, 716*0Sstevel@tonic-gate RE_BADHANDLE, 717*0Sstevel@tonic-gate RE_CLIENTID, 718*0Sstevel@tonic-gate RE_DEAD_FILE, 719*0Sstevel@tonic-gate RE_END, 720*0Sstevel@tonic-gate RE_FAIL_RELOCK, 721*0Sstevel@tonic-gate RE_FAIL_REMAP_LEN, 722*0Sstevel@tonic-gate RE_FAIL_REMAP_OP, 723*0Sstevel@tonic-gate RE_FAILOVER, 724*0Sstevel@tonic-gate RE_FILE_DIFF, 725*0Sstevel@tonic-gate RE_LOST_STATE, 726*0Sstevel@tonic-gate RE_OPENS_CHANGED, 727*0Sstevel@tonic-gate RE_SIGLOST, 728*0Sstevel@tonic-gate RE_SIGLOST_NO_DUMP, 729*0Sstevel@tonic-gate RE_START, 730*0Sstevel@tonic-gate RE_UNEXPECTED_ACTION, 731*0Sstevel@tonic-gate RE_UNEXPECTED_ERRNO, 732*0Sstevel@tonic-gate RE_UNEXPECTED_STATUS, 733*0Sstevel@tonic-gate RE_WRONGSEC, 734*0Sstevel@tonic-gate RE_LOST_STATE_BAD_OP 735*0Sstevel@tonic-gate } nfs4_event_type_t; 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate typedef enum { 738*0Sstevel@tonic-gate RFS_NO_INSPECT, 739*0Sstevel@tonic-gate RFS_INSPECT 740*0Sstevel@tonic-gate } nfs4_fact_status_t; 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate typedef enum { 743*0Sstevel@tonic-gate RF_BADOWNER, 744*0Sstevel@tonic-gate RF_ERR, 745*0Sstevel@tonic-gate RF_RENEW_EXPIRED, 746*0Sstevel@tonic-gate RF_SRV_NOT_RESPOND, 747*0Sstevel@tonic-gate RF_SRV_OK, 748*0Sstevel@tonic-gate RF_SRVS_NOT_RESPOND, 749*0Sstevel@tonic-gate RF_SRVS_OK, 750*0Sstevel@tonic-gate RF_DELMAP_CB_ERR 751*0Sstevel@tonic-gate } nfs4_fact_type_t; 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate typedef enum { 754*0Sstevel@tonic-gate NFS4_MS_DUMP, 755*0Sstevel@tonic-gate NFS4_MS_NO_DUMP 756*0Sstevel@tonic-gate } nfs4_msg_status_t; 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate typedef struct nfs4_rfact { 759*0Sstevel@tonic-gate nfs4_fact_type_t rf_type; 760*0Sstevel@tonic-gate nfs4_fact_status_t rf_status; 761*0Sstevel@tonic-gate bool_t rf_reboot; 762*0Sstevel@tonic-gate nfs4_recov_t rf_action; 763*0Sstevel@tonic-gate nfs_opnum4 rf_op; 764*0Sstevel@tonic-gate nfsstat4 rf_stat4; 765*0Sstevel@tonic-gate timespec_t rf_time; 766*0Sstevel@tonic-gate int rf_error; 767*0Sstevel@tonic-gate struct rnode4 *rf_rp1; 768*0Sstevel@tonic-gate char *rf_char1; 769*0Sstevel@tonic-gate } nfs4_rfact_t; 770*0Sstevel@tonic-gate 771*0Sstevel@tonic-gate typedef struct nfs4_revent { 772*0Sstevel@tonic-gate nfs4_event_type_t re_type; 773*0Sstevel@tonic-gate nfsstat4 re_stat4; 774*0Sstevel@tonic-gate uint_t re_uint; 775*0Sstevel@tonic-gate pid_t re_pid; 776*0Sstevel@tonic-gate struct mntinfo4 *re_mi; 777*0Sstevel@tonic-gate struct rnode4 *re_rp1; 778*0Sstevel@tonic-gate struct rnode4 *re_rp2; 779*0Sstevel@tonic-gate char *re_char1; 780*0Sstevel@tonic-gate char *re_char2; 781*0Sstevel@tonic-gate nfs4_tag_type_t re_tag1; 782*0Sstevel@tonic-gate nfs4_tag_type_t re_tag2; 783*0Sstevel@tonic-gate seqid4 re_seqid1; 784*0Sstevel@tonic-gate seqid4 re_seqid2; 785*0Sstevel@tonic-gate } nfs4_revent_t; 786*0Sstevel@tonic-gate 787*0Sstevel@tonic-gate typedef enum { 788*0Sstevel@tonic-gate RM_EVENT, 789*0Sstevel@tonic-gate RM_FACT 790*0Sstevel@tonic-gate } nfs4_msg_type_t; 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate typedef struct nfs4_debug_msg { 793*0Sstevel@tonic-gate timespec_t msg_time; 794*0Sstevel@tonic-gate nfs4_msg_type_t msg_type; 795*0Sstevel@tonic-gate char *msg_srv; 796*0Sstevel@tonic-gate char *msg_mntpt; 797*0Sstevel@tonic-gate union { 798*0Sstevel@tonic-gate nfs4_rfact_t msg_fact; 799*0Sstevel@tonic-gate nfs4_revent_t msg_event; 800*0Sstevel@tonic-gate } rmsg_u; 801*0Sstevel@tonic-gate nfs4_msg_status_t msg_status; 802*0Sstevel@tonic-gate list_node_t msg_node; 803*0Sstevel@tonic-gate } nfs4_debug_msg_t; 804*0Sstevel@tonic-gate 805*0Sstevel@tonic-gate /* 806*0Sstevel@tonic-gate * NFS private data per mounted file system 807*0Sstevel@tonic-gate * The mi_lock mutex protects the following fields: 808*0Sstevel@tonic-gate * mi_flags 809*0Sstevel@tonic-gate * mi_in_recovery 810*0Sstevel@tonic-gate * mi_recovflags 811*0Sstevel@tonic-gate * mi_recovthread 812*0Sstevel@tonic-gate * mi_error 813*0Sstevel@tonic-gate * mi_printed 814*0Sstevel@tonic-gate * mi_down 815*0Sstevel@tonic-gate * mi_stsize 816*0Sstevel@tonic-gate * mi_curread 817*0Sstevel@tonic-gate * mi_curwrite 818*0Sstevel@tonic-gate * mi_timers 819*0Sstevel@tonic-gate * mi_curr_serv 820*0Sstevel@tonic-gate * mi_klmconfig 821*0Sstevel@tonic-gate * mi_oo_list 822*0Sstevel@tonic-gate * mi_foo_list 823*0Sstevel@tonic-gate * mi_foo_num 824*0Sstevel@tonic-gate * mi_foo_max 825*0Sstevel@tonic-gate * mi_lost_state 826*0Sstevel@tonic-gate * mi_bseqid_list 827*0Sstevel@tonic-gate * 828*0Sstevel@tonic-gate * Normally the netconfig information for the mount comes from 829*0Sstevel@tonic-gate * mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a 830*0Sstevel@tonic-gate * different transport, mi_klmconfig contains the necessary netconfig 831*0Sstevel@tonic-gate * information. 832*0Sstevel@tonic-gate * 833*0Sstevel@tonic-gate * The mi_async_lock mutex protects the following fields: 834*0Sstevel@tonic-gate * mi_async_reqs 835*0Sstevel@tonic-gate * mi_async_req_count 836*0Sstevel@tonic-gate * mi_async_tail 837*0Sstevel@tonic-gate * mi_async_curr 838*0Sstevel@tonic-gate * mi_async_clusters 839*0Sstevel@tonic-gate * mi_async_init_clusters 840*0Sstevel@tonic-gate * mi_threads 841*0Sstevel@tonic-gate * mi_inactive_thread 842*0Sstevel@tonic-gate * mi_manager_thread 843*0Sstevel@tonic-gate * 844*0Sstevel@tonic-gate * The nfs4_server_t::s_lock protects the following fields: 845*0Sstevel@tonic-gate * mi_clientid 846*0Sstevel@tonic-gate * mi_clientid_next 847*0Sstevel@tonic-gate * mi_clientid_prev 848*0Sstevel@tonic-gate * mi_open_files 849*0Sstevel@tonic-gate * mi_srvsettime 850*0Sstevel@tonic-gate * 851*0Sstevel@tonic-gate * Locking order: 852*0Sstevel@tonic-gate * mi4_globals::mig_lock > mi_async_lock 853*0Sstevel@tonic-gate * mi_async_lock > nfs4_server_t::s_lock > mi_lock 854*0Sstevel@tonic-gate * mi_recovlock > mi_rename_lock > nfs_rtable4_lock 855*0Sstevel@tonic-gate * nfs4_server_t::s_recovlock > mi_recovlock 856*0Sstevel@tonic-gate * rnode4_t::r_rwlock > mi_rename_lock 857*0Sstevel@tonic-gate * nfs_rtable4_lock > mi_lock 858*0Sstevel@tonic-gate * nfs4_server_t::s_lock > mi_msg_list_lock 859*0Sstevel@tonic-gate * 860*0Sstevel@tonic-gate * The 'mi_oo_list' represents the hash buckets that contain the 861*0Sstevel@tonic-gate * nfs4_open_owenrs for this particular mntinfo4. 862*0Sstevel@tonic-gate * 863*0Sstevel@tonic-gate * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4. 864*0Sstevel@tonic-gate * 'mi_foo_num' is the current number of freed open owners on the list, 865*0Sstevel@tonic-gate * 'mi_foo_max' is the maximum number of freed open owners that are allowable 866*0Sstevel@tonic-gate * on the list. 867*0Sstevel@tonic-gate * 868*0Sstevel@tonic-gate * mi_rootfh and mi_srvparentfh are read-only once created, but that just 869*0Sstevel@tonic-gate * refers to the pointer. The contents must be updated to keep in sync 870*0Sstevel@tonic-gate * with mi_curr_serv. 871*0Sstevel@tonic-gate * 872*0Sstevel@tonic-gate * The mi_msg_list_lock protects against adding/deleting entries to the 873*0Sstevel@tonic-gate * mi_msg_list, and also the updating/retrieving of mi_lease_period; 874*0Sstevel@tonic-gate * 875*0Sstevel@tonic-gate * 'mi_zone' is initialized at structure creation time, and never 876*0Sstevel@tonic-gate * changes; it may be read without a lock. 877*0Sstevel@tonic-gate * 878*0Sstevel@tonic-gate * mi_zone_node is linkage into the mi4_globals.mig_list, and is 879*0Sstevel@tonic-gate * protected by mi4_globals.mig_list_lock. 880*0Sstevel@tonic-gate */ 881*0Sstevel@tonic-gate struct zone; 882*0Sstevel@tonic-gate typedef struct mntinfo4 { 883*0Sstevel@tonic-gate kmutex_t mi_lock; /* protects mntinfo4 fields */ 884*0Sstevel@tonic-gate struct servinfo4 *mi_servers; /* server list */ 885*0Sstevel@tonic-gate struct servinfo4 *mi_curr_serv; /* current server */ 886*0Sstevel@tonic-gate struct nfs4_sharedfh *mi_rootfh; /* root filehandle */ 887*0Sstevel@tonic-gate struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */ 888*0Sstevel@tonic-gate kcondvar_t mi_failover_cv; /* failover synchronization */ 889*0Sstevel@tonic-gate struct vfs *mi_vfsp; /* back pointer to vfs */ 890*0Sstevel@tonic-gate enum vtype mi_type; /* file type of the root vnode */ 891*0Sstevel@tonic-gate uint_t mi_flags; /* see below */ 892*0Sstevel@tonic-gate uint_t mi_recovflags; /* if recovery active; see below */ 893*0Sstevel@tonic-gate kthread_t *mi_recovthread; /* active recov thread or NULL */ 894*0Sstevel@tonic-gate uint_t mi_error; /* only set/valid when MI4_RECOV_FAIL */ 895*0Sstevel@tonic-gate /* is set in mi_flags */ 896*0Sstevel@tonic-gate int mi_tsize; /* transfer size (bytes) */ 897*0Sstevel@tonic-gate /* really read size */ 898*0Sstevel@tonic-gate int mi_stsize; /* server's max transfer size (bytes) */ 899*0Sstevel@tonic-gate /* really write size */ 900*0Sstevel@tonic-gate int mi_timeo; /* inital timeout in 10th sec */ 901*0Sstevel@tonic-gate int mi_retrans; /* times to retry request */ 902*0Sstevel@tonic-gate hrtime_t mi_acregmin; /* min time to hold cached file attr */ 903*0Sstevel@tonic-gate hrtime_t mi_acregmax; /* max time to hold cached file attr */ 904*0Sstevel@tonic-gate hrtime_t mi_acdirmin; /* min time to hold cached dir attr */ 905*0Sstevel@tonic-gate hrtime_t mi_acdirmax; /* max time to hold cached dir attr */ 906*0Sstevel@tonic-gate len_t mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */ 907*0Sstevel@tonic-gate int mi_curread; /* current read size */ 908*0Sstevel@tonic-gate int mi_curwrite; /* current write size */ 909*0Sstevel@tonic-gate /* 910*0Sstevel@tonic-gate * async I/O management. There may be a pool of threads to handle 911*0Sstevel@tonic-gate * async I/O requests, etc., plus there is always one thread that 912*0Sstevel@tonic-gate * handles over-the-wire requests for VOP_INACTIVE. The async pool 913*0Sstevel@tonic-gate * can also help out with VOP_INACTIVE. 914*0Sstevel@tonic-gate */ 915*0Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES]; 916*0Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES]; 917*0Sstevel@tonic-gate struct nfs4_async_reqs **mi_async_curr; /* current async queue */ 918*0Sstevel@tonic-gate uint_t mi_async_clusters[NFS4_ASYNC_TYPES]; 919*0Sstevel@tonic-gate uint_t mi_async_init_clusters; 920*0Sstevel@tonic-gate uint_t mi_async_req_count; /* # outstanding work requests */ 921*0Sstevel@tonic-gate kcondvar_t mi_async_reqs_cv; /* signaled when there's work */ 922*0Sstevel@tonic-gate ushort_t mi_threads; /* number of active async threads */ 923*0Sstevel@tonic-gate ushort_t mi_max_threads; /* max number of async threads */ 924*0Sstevel@tonic-gate kthread_t *mi_manager_thread; /* async manager thread id */ 925*0Sstevel@tonic-gate kthread_t *mi_inactive_thread; /* inactive thread id */ 926*0Sstevel@tonic-gate kcondvar_t mi_inact_req_cv; /* notify VOP_INACTIVE thread */ 927*0Sstevel@tonic-gate kcondvar_t mi_async_work_cv; /* tell workers to work */ 928*0Sstevel@tonic-gate kcondvar_t mi_async_cv; /* all pool threads exited */ 929*0Sstevel@tonic-gate kmutex_t mi_async_lock; 930*0Sstevel@tonic-gate /* 931*0Sstevel@tonic-gate * Other stuff 932*0Sstevel@tonic-gate */ 933*0Sstevel@tonic-gate struct pathcnf *mi_pathconf; /* static pathconf kludge */ 934*0Sstevel@tonic-gate rpcprog_t mi_prog; /* RPC program number */ 935*0Sstevel@tonic-gate rpcvers_t mi_vers; /* RPC program version number */ 936*0Sstevel@tonic-gate char **mi_rfsnames; /* mapping to proc names */ 937*0Sstevel@tonic-gate kstat_named_t *mi_reqs; /* count of requests */ 938*0Sstevel@tonic-gate clock_t mi_printftime; /* last error printf time */ 939*0Sstevel@tonic-gate nfs_rwlock_t mi_recovlock; /* separate ops from recovery (v4) */ 940*0Sstevel@tonic-gate time_t mi_grace_wait; /* non-zero represents time to wait */ 941*0Sstevel@tonic-gate time_t mi_srvsettime; /* when we switched nfs4_server_t */ 942*0Sstevel@tonic-gate nfs_rwlock_t mi_rename_lock; /* atomic volfh rename */ 943*0Sstevel@tonic-gate struct nfs4_fname *mi_fname; /* root fname */ 944*0Sstevel@tonic-gate list_t mi_lost_state; /* resend list */ 945*0Sstevel@tonic-gate list_t mi_bseqid_list; /* bad seqid list */ 946*0Sstevel@tonic-gate /* 947*0Sstevel@tonic-gate * Client Side Failover stats 948*0Sstevel@tonic-gate */ 949*0Sstevel@tonic-gate uint_t mi_noresponse; /* server not responding count */ 950*0Sstevel@tonic-gate uint_t mi_failover; /* failover to new server count */ 951*0Sstevel@tonic-gate uint_t mi_remap; /* remap to new server count */ 952*0Sstevel@tonic-gate /* 953*0Sstevel@tonic-gate * Kstat statistics 954*0Sstevel@tonic-gate */ 955*0Sstevel@tonic-gate struct kstat *mi_io_kstats; 956*0Sstevel@tonic-gate struct kstat *mi_ro_kstats; 957*0Sstevel@tonic-gate kstat_t *mi_recov_ksp; /* ptr to the recovery kstat */ 958*0Sstevel@tonic-gate 959*0Sstevel@tonic-gate /* 960*0Sstevel@tonic-gate * Volatile fh flags (nfsv4) 961*0Sstevel@tonic-gate */ 962*0Sstevel@tonic-gate uint32_t mi_fh_expire_type; 963*0Sstevel@tonic-gate /* 964*0Sstevel@tonic-gate * Lease Management 965*0Sstevel@tonic-gate */ 966*0Sstevel@tonic-gate struct mntinfo4 *mi_clientid_next; 967*0Sstevel@tonic-gate struct mntinfo4 *mi_clientid_prev; 968*0Sstevel@tonic-gate clientid4 mi_clientid; /* redundant info found in nfs4_server */ 969*0Sstevel@tonic-gate int mi_open_files; /* count of open files */ 970*0Sstevel@tonic-gate int mi_in_recovery; /* count of recovery instances */ 971*0Sstevel@tonic-gate kcondvar_t mi_cv_in_recov; /* cv for recovery threads */ 972*0Sstevel@tonic-gate /* 973*0Sstevel@tonic-gate * Open owner stuff. 974*0Sstevel@tonic-gate */ 975*0Sstevel@tonic-gate struct nfs4_oo_hash_bucket mi_oo_list[NFS4_NUM_OO_BUCKETS]; 976*0Sstevel@tonic-gate list_t mi_foo_list; 977*0Sstevel@tonic-gate int mi_foo_num; 978*0Sstevel@tonic-gate int mi_foo_max; 979*0Sstevel@tonic-gate /* 980*0Sstevel@tonic-gate * Shared filehandle pool. 981*0Sstevel@tonic-gate */ 982*0Sstevel@tonic-gate nfs_rwlock_t mi_fh_lock; 983*0Sstevel@tonic-gate avl_tree_t mi_filehandles; 984*0Sstevel@tonic-gate /* 985*0Sstevel@tonic-gate * fileid map 986*0Sstevel@tonic-gate * 987*0Sstevel@tonic-gate * Used on servers with volatile filehandles, to check for 988*0Sstevel@tonic-gate * pre-existing rnodes with a given fileid, before we create 989*0Sstevel@tonic-gate * another rnode for the same file on the server. 990*0Sstevel@tonic-gate */ 991*0Sstevel@tonic-gate kmutex_t mi_fileid_lock; 992*0Sstevel@tonic-gate avl_tree_t mi_fileid_map; 993*0Sstevel@tonic-gate 994*0Sstevel@tonic-gate /* 995*0Sstevel@tonic-gate * Debug message queue. 996*0Sstevel@tonic-gate */ 997*0Sstevel@tonic-gate list_t mi_msg_list; 998*0Sstevel@tonic-gate int mi_msg_count; 999*0Sstevel@tonic-gate time_t mi_lease_period; 1000*0Sstevel@tonic-gate /* 1001*0Sstevel@tonic-gate * not guaranteed to be accurate. 1002*0Sstevel@tonic-gate * only should be used by debug queue. 1003*0Sstevel@tonic-gate */ 1004*0Sstevel@tonic-gate kmutex_t mi_msg_list_lock; 1005*0Sstevel@tonic-gate /* 1006*0Sstevel@tonic-gate * Zones support. 1007*0Sstevel@tonic-gate */ 1008*0Sstevel@tonic-gate struct zone *mi_zone; /* Zone mounted in */ 1009*0Sstevel@tonic-gate list_node_t mi_zone_node; /* linkage into per-zone mi list */ 1010*0Sstevel@tonic-gate } mntinfo4_t; 1011*0Sstevel@tonic-gate 1012*0Sstevel@tonic-gate /* 1013*0Sstevel@tonic-gate * The values for mi_flags. 1014*0Sstevel@tonic-gate * 1015*0Sstevel@tonic-gate * MI4_HARD hard or soft mount 1016*0Sstevel@tonic-gate * MI4_PRINTED responding message printed 1017*0Sstevel@tonic-gate * MI4_INT allow INTR on hard mount 1018*0Sstevel@tonic-gate * MI4_DOWN server is down 1019*0Sstevel@tonic-gate * MI4_NOAC don't cache attributes 1020*0Sstevel@tonic-gate * MI4_NOCTO no close-to-open consistency 1021*0Sstevel@tonic-gate * MI4_LLOCK local locking only (no lockmgr) 1022*0Sstevel@tonic-gate * MI4_GRPID System V group id inheritance 1023*0Sstevel@tonic-gate * MI4_SHUTDOWN System is rebooting or shutting down 1024*0Sstevel@tonic-gate * MI4_LINK server supports link 1025*0Sstevel@tonic-gate * MI4_SYMLINK server supports symlink 1026*0Sstevel@tonic-gate * MI4_ACL server supports NFSv4 ACLs 1027*0Sstevel@tonic-gate * MI4_NOPRINT don't print messages 1028*0Sstevel@tonic-gate * MI4_DIRECTIO do direct I/O 1029*0Sstevel@tonic-gate * MI4_RECOV_ACTIV filesystem has recovery a thread 1030*0Sstevel@tonic-gate * MI4_REMOVE_ON_LAST_CLOSE remove from server's list 1031*0Sstevel@tonic-gate * MI4_RECOV_FAIL client recovery failed 1032*0Sstevel@tonic-gate * MI4_PUBLIC public/url option used 1033*0Sstevel@tonic-gate * MI4_MOUNTING mount in progress, don't failover 1034*0Sstevel@tonic-gate * MI4_POSIX_LOCK if server is using POSIX locking 1035*0Sstevel@tonic-gate * MI4_LOCK_DEBUG cmn_err'd posix lock err msg 1036*0Sstevel@tonic-gate * MI4_DEAD last VFS_RELE() called on mount 1037*0Sstevel@tonic-gate * MI4_INACTIVE_IDLE inactive thread idle 1038*0Sstevel@tonic-gate * MI4_BADOWNER_DEBUG badowner error msg per mount 1039*0Sstevel@tonic-gate * MI4_ASYNC_MGR_STOP tell async manager to die 1040*0Sstevel@tonic-gate * MI4_TIMEDOUT saw a timeout during zone shutdown 1041*0Sstevel@tonic-gate */ 1042*0Sstevel@tonic-gate #define MI4_HARD 0x1 1043*0Sstevel@tonic-gate #define MI4_PRINTED 0x2 1044*0Sstevel@tonic-gate #define MI4_INT 0x4 1045*0Sstevel@tonic-gate #define MI4_DOWN 0x8 1046*0Sstevel@tonic-gate #define MI4_NOAC 0x10 1047*0Sstevel@tonic-gate #define MI4_NOCTO 0x20 1048*0Sstevel@tonic-gate #define MI4_LLOCK 0x80 1049*0Sstevel@tonic-gate #define MI4_GRPID 0x100 1050*0Sstevel@tonic-gate #define MI4_SHUTDOWN 0x200 1051*0Sstevel@tonic-gate #define MI4_LINK 0x400 1052*0Sstevel@tonic-gate #define MI4_SYMLINK 0x800 1053*0Sstevel@tonic-gate /* 0x1000 is available */ 1054*0Sstevel@tonic-gate #define MI4_ACL 0x2000 1055*0Sstevel@tonic-gate /* 0x4000 is available */ 1056*0Sstevel@tonic-gate /* 0x8000 is available */ 1057*0Sstevel@tonic-gate /* 0x10000 is available */ 1058*0Sstevel@tonic-gate #define MI4_NOPRINT 0x20000 1059*0Sstevel@tonic-gate #define MI4_DIRECTIO 0x40000 1060*0Sstevel@tonic-gate /* 0x80000 is available */ 1061*0Sstevel@tonic-gate #define MI4_RECOV_ACTIV 0x100000 1062*0Sstevel@tonic-gate #define MI4_REMOVE_ON_LAST_CLOSE 0x200000 1063*0Sstevel@tonic-gate #define MI4_RECOV_FAIL 0x400000 1064*0Sstevel@tonic-gate #define MI4_PUBLIC 0x800000 1065*0Sstevel@tonic-gate #define MI4_MOUNTING 0x1000000 1066*0Sstevel@tonic-gate #define MI4_POSIX_LOCK 0x2000000 1067*0Sstevel@tonic-gate #define MI4_LOCK_DEBUG 0x4000000 1068*0Sstevel@tonic-gate #define MI4_DEAD 0x8000000 1069*0Sstevel@tonic-gate #define MI4_INACTIVE_IDLE 0x10000000 1070*0Sstevel@tonic-gate #define MI4_BADOWNER_DEBUG 0x20000000 1071*0Sstevel@tonic-gate #define MI4_ASYNC_MGR_STOP 0x40000000 1072*0Sstevel@tonic-gate #define MI4_TIMEDOUT 0x80000000 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate #define INTR4(vp) (VTOMI4(vp)->mi_flags & MI4_INT) 1075*0Sstevel@tonic-gate 1076*0Sstevel@tonic-gate #define FAILOVER_MOUNT4(mi) (mi->mi_servers->sv_next) 1077*0Sstevel@tonic-gate 1078*0Sstevel@tonic-gate /* 1079*0Sstevel@tonic-gate * Recovery flags. 1080*0Sstevel@tonic-gate * 1081*0Sstevel@tonic-gate * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag 1082*0Sstevel@tonic-gate * that's important), but some flag is needed to indicate that recovery is 1083*0Sstevel@tonic-gate * going on for the filesystem. 1084*0Sstevel@tonic-gate */ 1085*0Sstevel@tonic-gate #define MI4R_NEED_CLIENTID 0x1 1086*0Sstevel@tonic-gate #define MI4R_REOPEN_FILES 0x2 1087*0Sstevel@tonic-gate #define MI4R_NEED_SECINFO 0x4 1088*0Sstevel@tonic-gate #define MI4R_NEED_NEW_SERVER 0x8 1089*0Sstevel@tonic-gate #define MI4R_REMAP_FILES 0x10 1090*0Sstevel@tonic-gate #define MI4R_SRV_REBOOT 0x20 /* server has rebooted */ 1091*0Sstevel@tonic-gate #define MI4R_LOST_STATE 0x40 1092*0Sstevel@tonic-gate #define MI4R_BAD_SEQID 0x80 1093*0Sstevel@tonic-gate 1094*0Sstevel@tonic-gate /* 1095*0Sstevel@tonic-gate * vfs pointer to mount info 1096*0Sstevel@tonic-gate */ 1097*0Sstevel@tonic-gate #define VFTOMI4(vfsp) ((mntinfo4_t *)((vfsp)->vfs_data)) 1098*0Sstevel@tonic-gate 1099*0Sstevel@tonic-gate /* 1100*0Sstevel@tonic-gate * vnode pointer to mount info 1101*0Sstevel@tonic-gate */ 1102*0Sstevel@tonic-gate #define VTOMI4(vp) ((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data)) 1103*0Sstevel@tonic-gate 1104*0Sstevel@tonic-gate /* 1105*0Sstevel@tonic-gate * Lease Management 1106*0Sstevel@tonic-gate * 1107*0Sstevel@tonic-gate * lease_valid is initially set to NFS4_LEASE_NOT_STARTED. This is when the 1108*0Sstevel@tonic-gate * nfs4_server is first created. lease_valid is then set to 1109*0Sstevel@tonic-gate * NFS4_LEASE_UNITIALIZED when the renew thread is started. The extra state of 1110*0Sstevel@tonic-gate * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread 1111*0Sstevel@tonic-gate * already exists when we do SETCLIENTID). lease_valid is then set to 1112*0Sstevel@tonic-gate * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating 1113*0Sstevel@tonic-gate * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as 1114*0Sstevel@tonic-gate * the lease is renewed. It is set to NFS4_LEASE_INVALID when the lease 1115*0Sstevel@tonic-gate * expires. Client recovery is needed to set the lease back to 1116*0Sstevel@tonic-gate * NFS4_LEASE_VALID from NFS4_LEASE_INVALID. 1117*0Sstevel@tonic-gate * 1118*0Sstevel@tonic-gate * The s_cred is the credential used to mount the first file system for this 1119*0Sstevel@tonic-gate * server. It used as the credential for the renew thread's calls to the 1120*0Sstevel@tonic-gate * server. 1121*0Sstevel@tonic-gate * 1122*0Sstevel@tonic-gate * The renew thread waits on the condition variable cv_thread_exit. If the cv 1123*0Sstevel@tonic-gate * is signalled, then the thread knows it must check s_thread_exit to see if 1124*0Sstevel@tonic-gate * it should exit. The cv is signaled when the last file system is unmounted 1125*0Sstevel@tonic-gate * from a particular server. s_thread_exit is set to 0 upon thread startup, 1126*0Sstevel@tonic-gate * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby 1127*0Sstevel@tonic-gate * telling the thread to exit. s_thread_exit is needed to avoid spurious 1128*0Sstevel@tonic-gate * wakeups. 1129*0Sstevel@tonic-gate * 1130*0Sstevel@tonic-gate * state_ref_count is incremented every time a new file is opened and 1131*0Sstevel@tonic-gate * decremented every time a file is closed otw. This keeps track of whether 1132*0Sstevel@tonic-gate * the nfs4_server has state associated with it or not. 1133*0Sstevel@tonic-gate * 1134*0Sstevel@tonic-gate * s_refcnt is the reference count for storage management of the struct 1135*0Sstevel@tonic-gate * itself. 1136*0Sstevel@tonic-gate * 1137*0Sstevel@tonic-gate * mntinfo4_list points to the doubly linked list of mntinfo4s that share 1138*0Sstevel@tonic-gate * this nfs4_server (ie: <clientid, saddr> pair) in the current zone. This is 1139*0Sstevel@tonic-gate * needed for a nfs4_server to get a mntinfo4 for use in rfs4call. 1140*0Sstevel@tonic-gate * 1141*0Sstevel@tonic-gate * s_recovlock is used to synchronize recovery operations. The thread 1142*0Sstevel@tonic-gate * that is recovering the client must acquire it as a writer. If the 1143*0Sstevel@tonic-gate * thread is using the clientid (including recovery operations on other 1144*0Sstevel@tonic-gate * state), acquire it as a reader. 1145*0Sstevel@tonic-gate * 1146*0Sstevel@tonic-gate * The 's_otw_call_count' keeps track of the number of outstanding over the 1147*0Sstevel@tonic-gate * wire requests for this structure. The struct will not go away as long 1148*0Sstevel@tonic-gate * as this is non-zero (or s_refcnt is non-zero). 1149*0Sstevel@tonic-gate * 1150*0Sstevel@tonic-gate * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count' 1151*0Sstevel@tonic-gate * variable to let the renew thread when an outstanding otw request has 1152*0Sstevel@tonic-gate * finished. 1153*0Sstevel@tonic-gate * 1154*0Sstevel@tonic-gate * 'zoneid' and 'zone_globals' are set at creation of this structure 1155*0Sstevel@tonic-gate * and are read-only after that; no lock is required to read them. 1156*0Sstevel@tonic-gate * 1157*0Sstevel@tonic-gate * s_lock protects: everything except cv_thread_exit and s_recovlock. 1158*0Sstevel@tonic-gate * 1159*0Sstevel@tonic-gate * s_program is used as the index into the nfs4_callback_globals's 1160*0Sstevel@tonic-gate * nfs4prog2server table. When a callback request comes in, we can 1161*0Sstevel@tonic-gate * use that request's program number (minus NFS4_CALLBACK) as an index 1162*0Sstevel@tonic-gate * into the nfs4prog2server. That entry will hold the nfs4_server_t ptr. 1163*0Sstevel@tonic-gate * We can then access that nfs4_server_t and its 's_deleg_list' (its list of 1164*0Sstevel@tonic-gate * delegated rnode4_ts). 1165*0Sstevel@tonic-gate * 1166*0Sstevel@tonic-gate * Lock order: 1167*0Sstevel@tonic-gate * nfs4_server::s_lock > mntinfo4::mi_lock 1168*0Sstevel@tonic-gate * nfs_rtable4_lock > s_lock 1169*0Sstevel@tonic-gate * nfs4_server_lst_lock > s_lock 1170*0Sstevel@tonic-gate * s_recovlock > s_lock 1171*0Sstevel@tonic-gate */ 1172*0Sstevel@tonic-gate struct nfs4_callback_globals; 1173*0Sstevel@tonic-gate 1174*0Sstevel@tonic-gate typedef struct nfs4_server { 1175*0Sstevel@tonic-gate struct nfs4_server *forw; 1176*0Sstevel@tonic-gate struct nfs4_server *back; 1177*0Sstevel@tonic-gate struct netbuf saddr; 1178*0Sstevel@tonic-gate uint_t s_flags; /* see below */ 1179*0Sstevel@tonic-gate uint_t s_refcnt; 1180*0Sstevel@tonic-gate clientid4 clientid; /* what we get from server */ 1181*0Sstevel@tonic-gate nfs_client_id4 clidtosend; /* what we send to server */ 1182*0Sstevel@tonic-gate mntinfo4_t *mntinfo4_list; 1183*0Sstevel@tonic-gate int lease_valid; 1184*0Sstevel@tonic-gate time_t s_lease_time; 1185*0Sstevel@tonic-gate time_t last_renewal_time; 1186*0Sstevel@tonic-gate timespec_t propagation_delay; 1187*0Sstevel@tonic-gate cred_t *s_cred; 1188*0Sstevel@tonic-gate kcondvar_t cv_thread_exit; 1189*0Sstevel@tonic-gate int s_thread_exit; 1190*0Sstevel@tonic-gate int state_ref_count; 1191*0Sstevel@tonic-gate int s_otw_call_count; 1192*0Sstevel@tonic-gate kcondvar_t s_cv_otw_count; 1193*0Sstevel@tonic-gate kmutex_t s_lock; 1194*0Sstevel@tonic-gate list_t s_deleg_list; 1195*0Sstevel@tonic-gate rpcprog_t s_program; 1196*0Sstevel@tonic-gate nfs_rwlock_t s_recovlock; 1197*0Sstevel@tonic-gate kcondvar_t wait_cb_null; /* used to wait for CB_NULL */ 1198*0Sstevel@tonic-gate zoneid_t zoneid; /* zone using this nfs4_server_t */ 1199*0Sstevel@tonic-gate struct nfs4_callback_globals *zone_globals; /* globals */ 1200*0Sstevel@tonic-gate } nfs4_server_t; 1201*0Sstevel@tonic-gate 1202*0Sstevel@tonic-gate /* nfs4_server flags */ 1203*0Sstevel@tonic-gate #define N4S_CLIENTID_SET 1 /* server has our clientid */ 1204*0Sstevel@tonic-gate #define N4S_INSERTED 0x2 /* server has been put in global list */ 1205*0Sstevel@tonic-gate #define N4S_CB_PINGED 0x4 /* server has sent us a CB_NULL */ 1206*0Sstevel@tonic-gate #define N4S_CB_WAITER 0x8 /* is/has wait{ing/ed} for cb_null */ 1207*0Sstevel@tonic-gate #define N4S_BADOWNER_DEBUG 0x10 /* bad owner err msg per client */ 1208*0Sstevel@tonic-gate 1209*0Sstevel@tonic-gate #define N4S_CB_PAUSE_TIME 10000 /* Amount of time to pause (10ms) */ 1210*0Sstevel@tonic-gate 1211*0Sstevel@tonic-gate struct lease_time_arg { 1212*0Sstevel@tonic-gate time_t lease_time; 1213*0Sstevel@tonic-gate }; 1214*0Sstevel@tonic-gate 1215*0Sstevel@tonic-gate enum nfs4_delegreturn_policy { 1216*0Sstevel@tonic-gate IMMEDIATE, 1217*0Sstevel@tonic-gate FIRSTCLOSE, 1218*0Sstevel@tonic-gate LASTCLOSE, 1219*0Sstevel@tonic-gate INACTIVE 1220*0Sstevel@tonic-gate }; 1221*0Sstevel@tonic-gate 1222*0Sstevel@tonic-gate /* 1223*0Sstevel@tonic-gate * Operation hints for the recovery framework (mostly). 1224*0Sstevel@tonic-gate * 1225*0Sstevel@tonic-gate * EXCEPTIONS: 1226*0Sstevel@tonic-gate * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR 1227*0Sstevel@tonic-gate * These hints exist to allow user visit/readdir a R4SRVSTUB dir. 1228*0Sstevel@tonic-gate * (dir represents the root of a server fs that has not yet been 1229*0Sstevel@tonic-gate * mounted at client) 1230*0Sstevel@tonic-gate */ 1231*0Sstevel@tonic-gate typedef enum { 1232*0Sstevel@tonic-gate OH_OTHER, 1233*0Sstevel@tonic-gate OH_READ, 1234*0Sstevel@tonic-gate OH_WRITE, 1235*0Sstevel@tonic-gate OH_COMMIT, 1236*0Sstevel@tonic-gate OH_VFH_RENAME, 1237*0Sstevel@tonic-gate OH_MOUNT, 1238*0Sstevel@tonic-gate OH_CLOSE, 1239*0Sstevel@tonic-gate OH_LOCKU, 1240*0Sstevel@tonic-gate OH_DELEGRETURN, 1241*0Sstevel@tonic-gate OH_ACCESS, 1242*0Sstevel@tonic-gate OH_GETACL, 1243*0Sstevel@tonic-gate OH_GETATTR, 1244*0Sstevel@tonic-gate OH_LOOKUP, 1245*0Sstevel@tonic-gate OH_READDIR 1246*0Sstevel@tonic-gate } nfs4_op_hint_t; 1247*0Sstevel@tonic-gate 1248*0Sstevel@tonic-gate /* 1249*0Sstevel@tonic-gate * This macro evaluates to non-zero if the given op releases state at the 1250*0Sstevel@tonic-gate * server. 1251*0Sstevel@tonic-gate */ 1252*0Sstevel@tonic-gate #define OH_IS_STATE_RELE(op) ((op) == OH_CLOSE || (op) == OH_LOCKU || \ 1253*0Sstevel@tonic-gate (op) == OH_DELEGRETURN) 1254*0Sstevel@tonic-gate 1255*0Sstevel@tonic-gate #ifdef _KERNEL 1256*0Sstevel@tonic-gate 1257*0Sstevel@tonic-gate extern void nfs4_async_manager(struct vfs *); 1258*0Sstevel@tonic-gate extern void nfs4_async_manager_stop(struct vfs *); 1259*0Sstevel@tonic-gate extern void nfs4_async_stop(struct vfs *); 1260*0Sstevel@tonic-gate extern int nfs4_async_stop_sig(struct vfs *); 1261*0Sstevel@tonic-gate extern int nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t, 1262*0Sstevel@tonic-gate struct seg *, cred_t *, 1263*0Sstevel@tonic-gate void (*)(vnode_t *, u_offset_t, 1264*0Sstevel@tonic-gate caddr_t, struct seg *, cred_t *)); 1265*0Sstevel@tonic-gate extern int nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t, 1266*0Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 1267*0Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 1268*0Sstevel@tonic-gate extern int nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t, 1269*0Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 1270*0Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 1271*0Sstevel@tonic-gate extern void nfs4_async_commit(vnode_t *, page_t *, offset3, count3, 1272*0Sstevel@tonic-gate cred_t *, void (*)(vnode_t *, page_t *, 1273*0Sstevel@tonic-gate offset3, count3, cred_t *)); 1274*0Sstevel@tonic-gate extern void nfs4_async_inactive(vnode_t *, cred_t *); 1275*0Sstevel@tonic-gate extern void nfs4_inactive_thread(mntinfo4_t *mi); 1276*0Sstevel@tonic-gate extern void nfs4_inactive_otw(vnode_t *, cred_t *); 1277*0Sstevel@tonic-gate extern int nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *); 1278*0Sstevel@tonic-gate 1279*0Sstevel@tonic-gate extern int nfs4_setopts(vnode_t *, model_t, struct nfs_args *); 1280*0Sstevel@tonic-gate extern void nfs4_mnt_kstat_init(struct vfs *); 1281*0Sstevel@tonic-gate 1282*0Sstevel@tonic-gate extern void rfs4call(struct mntinfo4 *, struct COMPOUND4args_clnt *, 1283*0Sstevel@tonic-gate struct COMPOUND4res_clnt *, cred_t *, int *, int, 1284*0Sstevel@tonic-gate nfs4_error_t *); 1285*0Sstevel@tonic-gate extern void nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *); 1286*0Sstevel@tonic-gate extern int nfs4_attr_otw(vnode_t *, nfs4_tag_type_t, 1287*0Sstevel@tonic-gate nfs4_ga_res_t *, bitmap4, cred_t *); 1288*0Sstevel@tonic-gate 1289*0Sstevel@tonic-gate extern void nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t); 1290*0Sstevel@tonic-gate extern void nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *, 1291*0Sstevel@tonic-gate hrtime_t, cred_t *, int, 1292*0Sstevel@tonic-gate change_info4 *); 1293*0Sstevel@tonic-gate extern void nfs4_purge_rddir_cache(vnode_t *); 1294*0Sstevel@tonic-gate extern void nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *); 1295*0Sstevel@tonic-gate extern void nfs4_purge_caches(vnode_t *, int, cred_t *, int); 1296*0Sstevel@tonic-gate extern void nfs4_purge_stale_fh(int, vnode_t *, cred_t *); 1297*0Sstevel@tonic-gate 1298*0Sstevel@tonic-gate extern void nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *); 1299*0Sstevel@tonic-gate extern void nfs4_update_paths(vnode_t *, char *, vnode_t *, char *, 1300*0Sstevel@tonic-gate vnode_t *); 1301*0Sstevel@tonic-gate 1302*0Sstevel@tonic-gate extern void nfs4args_lookup_free(nfs_argop4 *, int); 1303*0Sstevel@tonic-gate extern void nfs4args_copen_free(OPEN4cargs *); 1304*0Sstevel@tonic-gate 1305*0Sstevel@tonic-gate extern void nfs4_printfhandle(nfs4_fhandle_t *); 1306*0Sstevel@tonic-gate 1307*0Sstevel@tonic-gate extern void nfs_free_mi4(mntinfo4_t *); 1308*0Sstevel@tonic-gate extern void sv4_free(servinfo4_t *); 1309*0Sstevel@tonic-gate extern void nfs4_mi_zonelist_add(mntinfo4_t *); 1310*0Sstevel@tonic-gate extern int nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *); 1311*0Sstevel@tonic-gate extern void nfs4_secinfo_init(void); 1312*0Sstevel@tonic-gate extern void nfs4_secinfo_fini(void); 1313*0Sstevel@tonic-gate extern int nfs4_secinfo_path(mntinfo4_t *, cred_t *, int); 1314*0Sstevel@tonic-gate extern int nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *); 1315*0Sstevel@tonic-gate extern void secinfo_free(sv_secinfo_t *); 1316*0Sstevel@tonic-gate extern void save_mnt_secinfo(servinfo4_t *); 1317*0Sstevel@tonic-gate extern void check_mnt_secinfo(servinfo4_t *, vnode_t *); 1318*0Sstevel@tonic-gate extern int vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int, 1319*0Sstevel@tonic-gate enum nfs_opnum4, bitmap4 supp_mask); 1320*0Sstevel@tonic-gate extern int nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *, 1321*0Sstevel@tonic-gate int, cred_t *); 1322*0Sstevel@tonic-gate extern void nfs4_write_error(vnode_t *, int, cred_t *); 1323*0Sstevel@tonic-gate extern void nfs4_lockcompletion(vnode_t *, int); 1324*0Sstevel@tonic-gate extern bool_t nfs4_map_lost_lock_conflict(vnode_t *); 1325*0Sstevel@tonic-gate extern int vtodv(vnode_t *, vnode_t **, cred_t *, bool_t); 1326*0Sstevel@tonic-gate extern void nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *, 1327*0Sstevel@tonic-gate bool_t, bool_t *, nfs4_open_owner_t *, bool_t, 1328*0Sstevel@tonic-gate nfs4_error_t *, int *); 1329*0Sstevel@tonic-gate extern void nfs4_error_zinit(nfs4_error_t *); 1330*0Sstevel@tonic-gate extern void nfs4_error_init(nfs4_error_t *, int); 1331*0Sstevel@tonic-gate #ifdef DEBUG 1332*0Sstevel@tonic-gate extern int nfs4_consistent_type(vnode_t *); 1333*0Sstevel@tonic-gate #endif 1334*0Sstevel@tonic-gate 1335*0Sstevel@tonic-gate extern void nfs4_init_dot_entries(void); 1336*0Sstevel@tonic-gate extern void nfs4_destroy_dot_entries(void); 1337*0Sstevel@tonic-gate extern struct nfs4_callback_globals *nfs4_get_callback_globals(void); 1338*0Sstevel@tonic-gate 1339*0Sstevel@tonic-gate extern struct nfs4_server nfs4_server_lst; 1340*0Sstevel@tonic-gate 1341*0Sstevel@tonic-gate extern clock_t nfs_write_error_interval; 1342*0Sstevel@tonic-gate 1343*0Sstevel@tonic-gate #endif /* _KERNEL */ 1344*0Sstevel@tonic-gate 1345*0Sstevel@tonic-gate /* 1346*0Sstevel@tonic-gate * Flags for nfs4getfh_otw. 1347*0Sstevel@tonic-gate */ 1348*0Sstevel@tonic-gate 1349*0Sstevel@tonic-gate #define NFS4_GETFH_PUBLIC 0x01 1350*0Sstevel@tonic-gate #define NFS4_GETFH_NEEDSOP 0x02 1351*0Sstevel@tonic-gate 1352*0Sstevel@tonic-gate /* 1353*0Sstevel@tonic-gate * Found through rnodes. 1354*0Sstevel@tonic-gate * 1355*0Sstevel@tonic-gate * The os_open_ref_count keeps track the number of open file descriptor 1356*0Sstevel@tonic-gate * refernces on this data structure. It will be bumped for any successful 1357*0Sstevel@tonic-gate * OTW OPEN call and any OPEN call that determines the OTW call is not 1358*0Sstevel@tonic-gate * necessary and the open stream hasn't just been created (see 1359*0Sstevel@tonic-gate * nfs4_is_otw_open_necessary). 1360*0Sstevel@tonic-gate * 1361*0Sstevel@tonic-gate * os_mapcnt is a count of the number of mmapped pages for a particular 1362*0Sstevel@tonic-gate * open stream; this in conjunction w/ os_open_ref_count is used to 1363*0Sstevel@tonic-gate * determine when to do a close to the server. This is necessary because 1364*0Sstevel@tonic-gate * of the semantics of doing open, mmap, close; the OTW close must be wait 1365*0Sstevel@tonic-gate * until all open and mmap references have vanished. 1366*0Sstevel@tonic-gate * 1367*0Sstevel@tonic-gate * 'os_valid' tells us whether this structure is about to be freed or not, 1368*0Sstevel@tonic-gate * if it is then don't return it in find_open_stream(). 1369*0Sstevel@tonic-gate * 1370*0Sstevel@tonic-gate * 'os_final_close' is set when a CLOSE OTW was attempted. This is needed 1371*0Sstevel@tonic-gate * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE 1372*0Sstevel@tonic-gate * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE. It 1373*0Sstevel@tonic-gate * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE 1374*0Sstevel@tonic-gate * that tried to close OTW but failed, and left the state cleanup to 1375*0Sstevel@tonic-gate * nfs4_inactive/CLOSE_FORCE. 1376*0Sstevel@tonic-gate * 1377*0Sstevel@tonic-gate * 'os_force_close' is used to let us know if an intervening thread came 1378*0Sstevel@tonic-gate * and reopened the open stream after we decided to issue a CLOSE_FORCE, 1379*0Sstevel@tonic-gate * but before we could actually process the CLOSE_FORCE. 1380*0Sstevel@tonic-gate * 1381*0Sstevel@tonic-gate * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the 1382*0Sstevel@tonic-gate * lost state queue. 1383*0Sstevel@tonic-gate * 1384*0Sstevel@tonic-gate * 'open_stateid' is set the last open stateid returned by the server unless 1385*0Sstevel@tonic-gate * 'os_delegation' is 1, in which case 'open_stateid' refers to the 1386*0Sstevel@tonic-gate * delegation stateid returned by the server. This is used in cases where the 1387*0Sstevel@tonic-gate * client tries to OPEN a file but already has a suitable delegation, so we 1388*0Sstevel@tonic-gate * just stick the delegation stateid in the open stream. 1389*0Sstevel@tonic-gate * 1390*0Sstevel@tonic-gate * os_dc_openacc are open access bits which have been granted to the 1391*0Sstevel@tonic-gate * open stream by virtue of a delegation, but which have not been seen 1392*0Sstevel@tonic-gate * by the server. This applies even if the open stream does not have 1393*0Sstevel@tonic-gate * os_delegation set. These bits are used when setting file locks to 1394*0Sstevel@tonic-gate * determine whether an open with CLAIM_DELEGATE_CUR needs to be done 1395*0Sstevel@tonic-gate * before the lock request can be sent to the server. See 1396*0Sstevel@tonic-gate * nfs4frlock_check_deleg(). 1397*0Sstevel@tonic-gate * 1398*0Sstevel@tonic-gate * 'os_mmap_read/write' keep track of the read and write access our memory 1399*0Sstevel@tonic-gate * maps require. We need to keep track of this so we can provide the proper 1400*0Sstevel@tonic-gate * access bits in the open/mmap/close/reboot/reopen case. 1401*0Sstevel@tonic-gate * 1402*0Sstevel@tonic-gate * 'os_failed_reopen' tells us that we failed to successfully reopen this 1403*0Sstevel@tonic-gate * open stream; therefore, we should not use this open stateid as it is 1404*0Sstevel@tonic-gate * not valid anymore. This flag is also used to indicate an unsuccessful 1405*0Sstevel@tonic-gate * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR. 1406*0Sstevel@tonic-gate * 1407*0Sstevel@tonic-gate * If 'os_orig_oo_name' is different than os_open_owner's oo_name 1408*0Sstevel@tonic-gate * then this tells us that this open stream's open owner used a 1409*0Sstevel@tonic-gate * bad seqid (that is, got NFS4ERR_BAD_SEQID). If different, this open 1410*0Sstevel@tonic-gate * stream will no longer be used for future OTW state releasing calls. 1411*0Sstevel@tonic-gate * 1412*0Sstevel@tonic-gate * Lock ordering: 1413*0Sstevel@tonic-gate * rnode4_t::r_os_lock > os_sync_lock 1414*0Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statelock 1415*0Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statev4_lock 1416*0Sstevel@tonic-gate * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call) 1417*0Sstevel@tonic-gate * 1418*0Sstevel@tonic-gate * The 'os_sync_lock' protects: 1419*0Sstevel@tonic-gate * open_stateid 1420*0Sstevel@tonic-gate * os_dc_openacc 1421*0Sstevel@tonic-gate * os_delegation 1422*0Sstevel@tonic-gate * os_failed_reopen 1423*0Sstevel@tonic-gate * os_final_close 1424*0Sstevel@tonic-gate * os_force_close 1425*0Sstevel@tonic-gate * os_mapcnt 1426*0Sstevel@tonic-gate * os_mmap_read 1427*0Sstevel@tonic-gate * os_mmap_write 1428*0Sstevel@tonic-gate * os_open_ref_count 1429*0Sstevel@tonic-gate * os_pending_close 1430*0Sstevel@tonic-gate * os_share_acc_read 1431*0Sstevel@tonic-gate * os_share_acc_write 1432*0Sstevel@tonic-gate * os_share_deny_none 1433*0Sstevel@tonic-gate * os_share_deny_read 1434*0Sstevel@tonic-gate * os_share_deny_write 1435*0Sstevel@tonic-gate * os_ref_count 1436*0Sstevel@tonic-gate * os_valid 1437*0Sstevel@tonic-gate * 1438*0Sstevel@tonic-gate * The rnode4_t::r_os_lock protects: 1439*0Sstevel@tonic-gate * os_node 1440*0Sstevel@tonic-gate * 1441*0Sstevel@tonic-gate * These fields are set at creation time and 1442*0Sstevel@tonic-gate * read only after that: 1443*0Sstevel@tonic-gate * os_open_owner 1444*0Sstevel@tonic-gate * os_orig_oo_name 1445*0Sstevel@tonic-gate */ 1446*0Sstevel@tonic-gate typedef struct nfs4_open_stream { 1447*0Sstevel@tonic-gate uint64_t os_share_acc_read; 1448*0Sstevel@tonic-gate uint64_t os_share_acc_write; 1449*0Sstevel@tonic-gate uint64_t os_mmap_read; 1450*0Sstevel@tonic-gate uint64_t os_mmap_write; 1451*0Sstevel@tonic-gate uint32_t os_share_deny_none; 1452*0Sstevel@tonic-gate uint32_t os_share_deny_read; 1453*0Sstevel@tonic-gate uint32_t os_share_deny_write; 1454*0Sstevel@tonic-gate stateid4 open_stateid; 1455*0Sstevel@tonic-gate int os_dc_openacc; 1456*0Sstevel@tonic-gate int os_ref_count; 1457*0Sstevel@tonic-gate unsigned os_valid:1; 1458*0Sstevel@tonic-gate unsigned os_delegation:1; 1459*0Sstevel@tonic-gate unsigned os_final_close:1; 1460*0Sstevel@tonic-gate unsigned os_pending_close:1; 1461*0Sstevel@tonic-gate unsigned os_failed_reopen:1; 1462*0Sstevel@tonic-gate unsigned os_force_close:1; 1463*0Sstevel@tonic-gate int os_open_ref_count; 1464*0Sstevel@tonic-gate long os_mapcnt; 1465*0Sstevel@tonic-gate list_node_t os_node; 1466*0Sstevel@tonic-gate struct nfs4_open_owner *os_open_owner; 1467*0Sstevel@tonic-gate uint64_t os_orig_oo_name; 1468*0Sstevel@tonic-gate kmutex_t os_sync_lock; 1469*0Sstevel@tonic-gate } nfs4_open_stream_t; 1470*0Sstevel@tonic-gate 1471*0Sstevel@tonic-gate /* 1472*0Sstevel@tonic-gate * This structure describes the format of the lock_owner_name 1473*0Sstevel@tonic-gate * field of the lock owner. 1474*0Sstevel@tonic-gate */ 1475*0Sstevel@tonic-gate 1476*0Sstevel@tonic-gate typedef struct nfs4_lo_name { 1477*0Sstevel@tonic-gate uint64_t ln_seq_num; 1478*0Sstevel@tonic-gate pid_t ln_pid; 1479*0Sstevel@tonic-gate } nfs4_lo_name_t; 1480*0Sstevel@tonic-gate 1481*0Sstevel@tonic-gate /* 1482*0Sstevel@tonic-gate * Flags for lo_flags. 1483*0Sstevel@tonic-gate */ 1484*0Sstevel@tonic-gate #define NFS4_LOCK_SEQID_INUSE 0x1 1485*0Sstevel@tonic-gate #define NFS4_BAD_SEQID_LOCK 0x2 1486*0Sstevel@tonic-gate 1487*0Sstevel@tonic-gate /* 1488*0Sstevel@tonic-gate * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs 1489*0Sstevel@tonic-gate * off the rnode. If the links are NULL it means this object is not on the 1490*0Sstevel@tonic-gate * list. 1491*0Sstevel@tonic-gate * 1492*0Sstevel@tonic-gate * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and 1493*0Sstevel@tonic-gate * didn't get a response back. This is used to figure out if we have 1494*0Sstevel@tonic-gate * possible remote v4 locks, so that we can clean up at process exit. In 1495*0Sstevel@tonic-gate * theory, the client should be able to figure out if the server received 1496*0Sstevel@tonic-gate * the request (based on what seqid works), so maybe we can get rid of this 1497*0Sstevel@tonic-gate * flag someday. 1498*0Sstevel@tonic-gate * 1499*0Sstevel@tonic-gate * 'lo_ref_count' tells us how many processes/threads are using this data 1500*0Sstevel@tonic-gate * structure. The rnode's list accounts for one reference. 1501*0Sstevel@tonic-gate * 1502*0Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the 1503*0Sstevel@tonic-gate * data structure. It is then set to NFS4_PERM_CREATED when a lock request 1504*0Sstevel@tonic-gate * is successful using this lock owner structure. We need to keep 'temporary' 1505*0Sstevel@tonic-gate * lock owners around so we can properly keep the lock seqid synchronization 1506*0Sstevel@tonic-gate * when multiple processes/threads are trying to create the lock owner for the 1507*0Sstevel@tonic-gate * first time (especially with the DENIED error case). Once 1508*0Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change. 1509*0Sstevel@tonic-gate * 1510*0Sstevel@tonic-gate * 'lo_valid' tells us whether this structure is about to be freed or not, 1511*0Sstevel@tonic-gate * if it is then don't return it from find_lock_owner(). 1512*0Sstevel@tonic-gate * 1513*0Sstevel@tonic-gate * Retrieving and setting of 'lock_seqid' is protected by the 1514*0Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag. Waiters for NFS4_LOCK_SEQID_INUSE should 1515*0Sstevel@tonic-gate * use 'lo_cv_seqid_sync'. 1516*0Sstevel@tonic-gate * 1517*0Sstevel@tonic-gate * The setting of 'lock_stateid' is protected by the 1518*0Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'. The retrieving of the 1519*0Sstevel@tonic-gate * 'lock_stateid' is protected by 'lo_lock', with the additional 1520*0Sstevel@tonic-gate * requirement that the calling function can handle NFS4ERR_OLD_STATEID and 1521*0Sstevel@tonic-gate * NFS4ERR_BAD_STATEID as appropiate. 1522*0Sstevel@tonic-gate * 1523*0Sstevel@tonic-gate * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock 1524*0Sstevel@tonic-gate * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID). With this set, 1525*0Sstevel@tonic-gate * this lock owner will no longer be used for future OTW calls. Once set, 1526*0Sstevel@tonic-gate * it is never unset. 1527*0Sstevel@tonic-gate * 1528*0Sstevel@tonic-gate * Lock ordering: 1529*0Sstevel@tonic-gate * rnode4_t::r_statev4_lock > lo_lock 1530*0Sstevel@tonic-gate */ 1531*0Sstevel@tonic-gate typedef struct nfs4_lock_owner { 1532*0Sstevel@tonic-gate struct nfs4_lock_owner *lo_next_rnode; 1533*0Sstevel@tonic-gate struct nfs4_lock_owner *lo_prev_rnode; 1534*0Sstevel@tonic-gate int lo_pid; 1535*0Sstevel@tonic-gate stateid4 lock_stateid; 1536*0Sstevel@tonic-gate seqid4 lock_seqid; 1537*0Sstevel@tonic-gate /* 1538*0Sstevel@tonic-gate * Fix this to always be 12 bytes 1539*0Sstevel@tonic-gate */ 1540*0Sstevel@tonic-gate nfs4_lo_name_t lock_owner_name; 1541*0Sstevel@tonic-gate int lo_ref_count; 1542*0Sstevel@tonic-gate int lo_valid; 1543*0Sstevel@tonic-gate int lo_pending_rqsts; 1544*0Sstevel@tonic-gate int lo_just_created; 1545*0Sstevel@tonic-gate int lo_flags; 1546*0Sstevel@tonic-gate kcondvar_t lo_cv_seqid_sync; 1547*0Sstevel@tonic-gate kmutex_t lo_lock; 1548*0Sstevel@tonic-gate kthread_t *lo_seqid_holder; /* debugging aid */ 1549*0Sstevel@tonic-gate } nfs4_lock_owner_t; 1550*0Sstevel@tonic-gate 1551*0Sstevel@tonic-gate /* for nfs4_lock_owner_t lookups */ 1552*0Sstevel@tonic-gate typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t; 1553*0Sstevel@tonic-gate 1554*0Sstevel@tonic-gate /* Number of times to retry a call that fails with state independent error */ 1555*0Sstevel@tonic-gate #define NFS4_NUM_RECOV_RETRIES 3 1556*0Sstevel@tonic-gate 1557*0Sstevel@tonic-gate typedef enum { 1558*0Sstevel@tonic-gate NO_SID, 1559*0Sstevel@tonic-gate DEL_SID, 1560*0Sstevel@tonic-gate LOCK_SID, 1561*0Sstevel@tonic-gate OPEN_SID, 1562*0Sstevel@tonic-gate SPEC_SID 1563*0Sstevel@tonic-gate } nfs4_stateid_type_t; 1564*0Sstevel@tonic-gate 1565*0Sstevel@tonic-gate typedef struct nfs4_stateid_types { 1566*0Sstevel@tonic-gate stateid4 d_sid; 1567*0Sstevel@tonic-gate stateid4 l_sid; 1568*0Sstevel@tonic-gate stateid4 o_sid; 1569*0Sstevel@tonic-gate nfs4_stateid_type_t cur_sid_type; 1570*0Sstevel@tonic-gate } nfs4_stateid_types_t; 1571*0Sstevel@tonic-gate 1572*0Sstevel@tonic-gate /* 1573*0Sstevel@tonic-gate * Per-zone data for dealing with callbacks. Included here solely for the 1574*0Sstevel@tonic-gate * benefit of MDB. 1575*0Sstevel@tonic-gate */ 1576*0Sstevel@tonic-gate struct nfs4_callback_stats { 1577*0Sstevel@tonic-gate kstat_named_t delegations; 1578*0Sstevel@tonic-gate kstat_named_t cb_getattr; 1579*0Sstevel@tonic-gate kstat_named_t cb_recall; 1580*0Sstevel@tonic-gate kstat_named_t cb_null; 1581*0Sstevel@tonic-gate kstat_named_t cb_dispatch; 1582*0Sstevel@tonic-gate kstat_named_t delegaccept_r; 1583*0Sstevel@tonic-gate kstat_named_t delegaccept_rw; 1584*0Sstevel@tonic-gate kstat_named_t delegreturn; 1585*0Sstevel@tonic-gate kstat_named_t callbacks; 1586*0Sstevel@tonic-gate kstat_named_t claim_cur; 1587*0Sstevel@tonic-gate kstat_named_t claim_cur_ok; 1588*0Sstevel@tonic-gate kstat_named_t recall_trunc; 1589*0Sstevel@tonic-gate kstat_named_t recall_failed; 1590*0Sstevel@tonic-gate kstat_named_t return_limit_write; 1591*0Sstevel@tonic-gate kstat_named_t return_limit_addmap; 1592*0Sstevel@tonic-gate kstat_named_t deleg_recover; 1593*0Sstevel@tonic-gate kstat_named_t cb_illegal; 1594*0Sstevel@tonic-gate }; 1595*0Sstevel@tonic-gate 1596*0Sstevel@tonic-gate struct nfs4_callback_globals { 1597*0Sstevel@tonic-gate kmutex_t nfs4_cb_lock; 1598*0Sstevel@tonic-gate kmutex_t nfs4_dlist_lock; 1599*0Sstevel@tonic-gate int nfs4_program_hint; 1600*0Sstevel@tonic-gate /* this table maps the program number to the nfs4_server structure */ 1601*0Sstevel@tonic-gate struct nfs4_server **nfs4prog2server; 1602*0Sstevel@tonic-gate list_t nfs4_dlist; 1603*0Sstevel@tonic-gate list_t nfs4_cb_ports; 1604*0Sstevel@tonic-gate struct nfs4_callback_stats nfs4_callback_stats; 1605*0Sstevel@tonic-gate #ifdef DEBUG 1606*0Sstevel@tonic-gate int nfs4_dlistadd_c; 1607*0Sstevel@tonic-gate int nfs4_dlistclean_c; 1608*0Sstevel@tonic-gate #endif 1609*0Sstevel@tonic-gate }; 1610*0Sstevel@tonic-gate 1611*0Sstevel@tonic-gate typedef enum { 1612*0Sstevel@tonic-gate CLOSE_NORM, 1613*0Sstevel@tonic-gate CLOSE_DELMAP, 1614*0Sstevel@tonic-gate CLOSE_FORCE, 1615*0Sstevel@tonic-gate CLOSE_RESEND, 1616*0Sstevel@tonic-gate CLOSE_AFTER_RESEND 1617*0Sstevel@tonic-gate } nfs4_close_type_t; 1618*0Sstevel@tonic-gate 1619*0Sstevel@tonic-gate /* 1620*0Sstevel@tonic-gate * Structure to hold the bad seqid information that is passed 1621*0Sstevel@tonic-gate * to the recovery framework. 1622*0Sstevel@tonic-gate */ 1623*0Sstevel@tonic-gate typedef struct nfs4_bseqid_entry { 1624*0Sstevel@tonic-gate nfs4_open_owner_t *bs_oop; 1625*0Sstevel@tonic-gate nfs4_lock_owner_t *bs_lop; 1626*0Sstevel@tonic-gate vnode_t *bs_vp; 1627*0Sstevel@tonic-gate pid_t bs_pid; 1628*0Sstevel@tonic-gate nfs4_tag_type_t bs_tag; 1629*0Sstevel@tonic-gate seqid4 bs_seqid; 1630*0Sstevel@tonic-gate list_node_t bs_node; 1631*0Sstevel@tonic-gate } nfs4_bseqid_entry_t; 1632*0Sstevel@tonic-gate 1633*0Sstevel@tonic-gate #ifdef _KERNEL 1634*0Sstevel@tonic-gate 1635*0Sstevel@tonic-gate extern void nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int, 1636*0Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t, 1637*0Sstevel@tonic-gate size_t, uint_t, uint_t); 1638*0Sstevel@tonic-gate extern void nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *); 1639*0Sstevel@tonic-gate extern void nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4); 1640*0Sstevel@tonic-gate extern void open_owner_hold(nfs4_open_owner_t *); 1641*0Sstevel@tonic-gate extern void open_owner_rele(nfs4_open_owner_t *); 1642*0Sstevel@tonic-gate extern nfs4_open_stream_t *find_or_create_open_stream(nfs4_open_owner_t *, 1643*0Sstevel@tonic-gate struct rnode4 *, int *); 1644*0Sstevel@tonic-gate extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *, 1645*0Sstevel@tonic-gate struct rnode4 *); 1646*0Sstevel@tonic-gate extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop, 1647*0Sstevel@tonic-gate struct rnode4 *rp); 1648*0Sstevel@tonic-gate extern void open_stream_hold(nfs4_open_stream_t *); 1649*0Sstevel@tonic-gate extern void open_stream_rele(nfs4_open_stream_t *, struct rnode4 *); 1650*0Sstevel@tonic-gate extern int nfs4close_all(vnode_t *, cred_t *); 1651*0Sstevel@tonic-gate extern void lock_owner_hold(nfs4_lock_owner_t *); 1652*0Sstevel@tonic-gate extern void lock_owner_rele(nfs4_lock_owner_t *); 1653*0Sstevel@tonic-gate extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t); 1654*0Sstevel@tonic-gate extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t); 1655*0Sstevel@tonic-gate extern void nfs4_rnode_remove_lock_owner(struct rnode4 *, 1656*0Sstevel@tonic-gate nfs4_lock_owner_t *); 1657*0Sstevel@tonic-gate extern void nfs4_flush_lock_owners(struct rnode4 *); 1658*0Sstevel@tonic-gate extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t); 1659*0Sstevel@tonic-gate extern void nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *, 1660*0Sstevel@tonic-gate nfs4_tag_type_t); 1661*0Sstevel@tonic-gate extern void nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *); 1662*0Sstevel@tonic-gate extern void nfs4_get_and_set_next_open_seqid(nfs4_open_owner_t *, 1663*0Sstevel@tonic-gate nfs4_tag_type_t); 1664*0Sstevel@tonic-gate extern void nfs4_end_open_seqid_sync(nfs4_open_owner_t *); 1665*0Sstevel@tonic-gate extern int nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *); 1666*0Sstevel@tonic-gate extern void nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *); 1667*0Sstevel@tonic-gate extern int nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *); 1668*0Sstevel@tonic-gate extern void nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *, 1669*0Sstevel@tonic-gate nfs4_open_stream_t *, clientid4, locker4 *); 1670*0Sstevel@tonic-gate extern void nfs4_destroy_open_owner(nfs4_open_owner_t *); 1671*0Sstevel@tonic-gate 1672*0Sstevel@tonic-gate extern void nfs4_renew_lease_thread(nfs4_server_t *); 1673*0Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server(mntinfo4_t *); 1674*0Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server_all(mntinfo4_t *, int all); 1675*0Sstevel@tonic-gate extern nfs4_server_t *new_nfs4_server(servinfo4_t *, cred_t *); 1676*0Sstevel@tonic-gate extern void nfs4_mark_srv_dead(nfs4_server_t *); 1677*0Sstevel@tonic-gate extern nfs4_server_t *servinfo4_to_nfs4_server(servinfo4_t *); 1678*0Sstevel@tonic-gate extern void nfs4_inc_state_ref_count(mntinfo4_t *); 1679*0Sstevel@tonic-gate extern void nfs4_inc_state_ref_count_nolock(nfs4_server_t *, 1680*0Sstevel@tonic-gate mntinfo4_t *); 1681*0Sstevel@tonic-gate extern void nfs4_dec_state_ref_count(mntinfo4_t *); 1682*0Sstevel@tonic-gate extern void nfs4_dec_state_ref_count_nolock(nfs4_server_t *, 1683*0Sstevel@tonic-gate mntinfo4_t *); 1684*0Sstevel@tonic-gate extern clientid4 mi2clientid(mntinfo4_t *); 1685*0Sstevel@tonic-gate extern int nfs4_server_in_recovery(nfs4_server_t *); 1686*0Sstevel@tonic-gate extern bool_t nfs4_server_vlock(nfs4_server_t *, int); 1687*0Sstevel@tonic-gate extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *); 1688*0Sstevel@tonic-gate extern uint64_t nfs4_get_new_oo_name(void); 1689*0Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *); 1690*0Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *); 1691*0Sstevel@tonic-gate extern void nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *, 1692*0Sstevel@tonic-gate int, u_offset_t, cred_t *, nfs4_error_t *, 1693*0Sstevel@tonic-gate nfs4_lost_rqst_t *, int *); 1694*0Sstevel@tonic-gate extern void nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *, 1695*0Sstevel@tonic-gate nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *, 1696*0Sstevel@tonic-gate vnode_t *, int, int); 1697*0Sstevel@tonic-gate extern void nfs4_open_downgrade(int, int, nfs4_open_owner_t *, 1698*0Sstevel@tonic-gate nfs4_open_stream_t *, vnode_t *, cred_t *, 1699*0Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *); 1700*0Sstevel@tonic-gate extern seqid4 nfs4_get_open_seqid(nfs4_open_owner_t *); 1701*0Sstevel@tonic-gate extern cred_t *nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *); 1702*0Sstevel@tonic-gate extern void nfs4_init_stateid_types(nfs4_stateid_types_t *); 1703*0Sstevel@tonic-gate extern void nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *); 1704*0Sstevel@tonic-gate 1705*0Sstevel@tonic-gate extern kmutex_t nfs4_server_lst_lock; 1706*0Sstevel@tonic-gate 1707*0Sstevel@tonic-gate extern void nfs4callback_destroy(nfs4_server_t *); 1708*0Sstevel@tonic-gate extern void nfs4_callback_init(void); 1709*0Sstevel@tonic-gate extern void nfs4_callback_fini(void); 1710*0Sstevel@tonic-gate extern void nfs4_cb_args(nfs4_server_t *, struct knetconfig *, 1711*0Sstevel@tonic-gate SETCLIENTID4args *); 1712*0Sstevel@tonic-gate extern void nfs4delegreturn_async(struct rnode4 *, int, bool_t); 1713*0Sstevel@tonic-gate 1714*0Sstevel@tonic-gate extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy; 1715*0Sstevel@tonic-gate 1716*0Sstevel@tonic-gate extern void nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *); 1717*0Sstevel@tonic-gate extern void nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *); 1718*0Sstevel@tonic-gate extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *); 1719*0Sstevel@tonic-gate extern bool_t nfs4_fs_active(nfs4_server_t *); 1720*0Sstevel@tonic-gate extern void nfs4_server_rele(nfs4_server_t *); 1721*0Sstevel@tonic-gate extern bool_t inlease(nfs4_server_t *); 1722*0Sstevel@tonic-gate extern bool_t nfs4_has_pages(vnode_t *); 1723*0Sstevel@tonic-gate extern void nfs4_log_badowner(mntinfo4_t *, nfs_opnum4); 1724*0Sstevel@tonic-gate 1725*0Sstevel@tonic-gate #endif /* _KERNEL */ 1726*0Sstevel@tonic-gate 1727*0Sstevel@tonic-gate /* 1728*0Sstevel@tonic-gate * Client State Recovery 1729*0Sstevel@tonic-gate */ 1730*0Sstevel@tonic-gate 1731*0Sstevel@tonic-gate /* 1732*0Sstevel@tonic-gate * The following defines are used for rs_flags in 1733*0Sstevel@tonic-gate * a nfs4_recov_state_t structure. 1734*0Sstevel@tonic-gate * 1735*0Sstevel@tonic-gate * NFS4_RS_RENAME_HELD Indicates that the mi_rename_lock was held. 1736*0Sstevel@tonic-gate * NFS4_RS_GRACE_MSG Set once we have uprintf'ed a grace message. 1737*0Sstevel@tonic-gate * NFS4_RS_DELAY_MSG Set once we have uprintf'ed a delay message. 1738*0Sstevel@tonic-gate * NFS4_RS_RECALL_HELD1 r_deleg_recall_lock for vp1 was held. 1739*0Sstevel@tonic-gate * NFS4_RS_RECALL_HELD2 r_deleg_recall_lock for vp2 was held. 1740*0Sstevel@tonic-gate */ 1741*0Sstevel@tonic-gate #define NFS4_RS_RENAME_HELD 0x000000001 1742*0Sstevel@tonic-gate #define NFS4_RS_GRACE_MSG 0x000000002 1743*0Sstevel@tonic-gate #define NFS4_RS_DELAY_MSG 0x000000004 1744*0Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD1 0x000000008 1745*0Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD2 0x000000010 1746*0Sstevel@tonic-gate 1747*0Sstevel@tonic-gate /* 1748*0Sstevel@tonic-gate * Information that is retrieved from nfs4_start_op() and that is 1749*0Sstevel@tonic-gate * passed into nfs4_end_op(). 1750*0Sstevel@tonic-gate * 1751*0Sstevel@tonic-gate * rs_sp is a reference to the nfs4_server that was found, or NULL. 1752*0Sstevel@tonic-gate * 1753*0Sstevel@tonic-gate * rs_num_retry_despite_err is the number times client retried an 1754*0Sstevel@tonic-gate * OTW op despite a recovery error. It is only incremented for hints 1755*0Sstevel@tonic-gate * exempt to normal R4RECOVERR processing 1756*0Sstevel@tonic-gate * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN). (XXX this special-case code 1757*0Sstevel@tonic-gate * needs review for possible removal.) 1758*0Sstevel@tonic-gate * It is initialized wherever nfs4_recov_state_t is declared -- usually 1759*0Sstevel@tonic-gate * very near initialization of rs_flags. 1760*0Sstevel@tonic-gate */ 1761*0Sstevel@tonic-gate typedef struct { 1762*0Sstevel@tonic-gate nfs4_server_t *rs_sp; 1763*0Sstevel@tonic-gate int rs_flags; 1764*0Sstevel@tonic-gate int rs_num_retry_despite_err; 1765*0Sstevel@tonic-gate } nfs4_recov_state_t; 1766*0Sstevel@tonic-gate 1767*0Sstevel@tonic-gate /* 1768*0Sstevel@tonic-gate * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root. 1769*0Sstevel@tonic-gate */ 1770*0Sstevel@tonic-gate 1771*0Sstevel@tonic-gate #define NFS4_REMAP_CKATTRS 1 1772*0Sstevel@tonic-gate #define NFS4_REMAP_NEEDSOP 2 1773*0Sstevel@tonic-gate 1774*0Sstevel@tonic-gate #ifdef _KERNEL 1775*0Sstevel@tonic-gate 1776*0Sstevel@tonic-gate extern int nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int, 1777*0Sstevel@tonic-gate vnode_t *, int, int *, int, nfs4_recov_state_t *); 1778*0Sstevel@tonic-gate extern void nfs4setclientid(struct mntinfo4 *, struct cred *, bool_t, 1779*0Sstevel@tonic-gate nfs4_error_t *); 1780*0Sstevel@tonic-gate extern void nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *, 1781*0Sstevel@tonic-gate open_claim_type4, bool_t, bool_t); 1782*0Sstevel@tonic-gate extern void nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int); 1783*0Sstevel@tonic-gate extern void nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int, 1784*0Sstevel@tonic-gate nfs4_error_t *); 1785*0Sstevel@tonic-gate extern void nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int, 1786*0Sstevel@tonic-gate nfs4_error_t *); 1787*0Sstevel@tonic-gate extern int nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t, 1788*0Sstevel@tonic-gate vnode_t *, cred_t *, vnode_t **, int); 1789*0Sstevel@tonic-gate extern void nfs4_fail_recov(vnode_t *, char *, int, nfsstat4); 1790*0Sstevel@tonic-gate 1791*0Sstevel@tonic-gate extern int nfs4_needs_recovery(nfs4_error_t *, bool_t, vfs_t *); 1792*0Sstevel@tonic-gate extern int nfs4_recov_marks_dead(nfsstat4); 1793*0Sstevel@tonic-gate extern bool_t nfs4_start_recovery(nfs4_error_t *, struct mntinfo4 *, 1794*0Sstevel@tonic-gate vnode_t *, vnode_t *, stateid4 *, 1795*0Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs_opnum4, nfs4_bseqid_entry_t *); 1796*0Sstevel@tonic-gate extern int nfs4_start_op(struct mntinfo4 *, vnode_t *, vnode_t *, 1797*0Sstevel@tonic-gate nfs4_recov_state_t *); 1798*0Sstevel@tonic-gate extern void nfs4_end_op(struct mntinfo4 *, vnode_t *, vnode_t *, 1799*0Sstevel@tonic-gate nfs4_recov_state_t *, bool_t); 1800*0Sstevel@tonic-gate extern int nfs4_start_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 1801*0Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t *); 1802*0Sstevel@tonic-gate extern void nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 1803*0Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t); 1804*0Sstevel@tonic-gate extern char *nfs4_recov_action_to_str(nfs4_recov_t); 1805*0Sstevel@tonic-gate 1806*0Sstevel@tonic-gate extern int wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t, 1807*0Sstevel@tonic-gate nfs4_recov_state_t *); 1808*0Sstevel@tonic-gate extern void nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *); 1809*0Sstevel@tonic-gate extern void nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t, 1810*0Sstevel@tonic-gate int, nfsstat4); 1811*0Sstevel@tonic-gate extern time_t nfs4err_delay_time; 1812*0Sstevel@tonic-gate extern void nfs4_set_grace_wait(mntinfo4_t *); 1813*0Sstevel@tonic-gate extern void nfs4_set_delay_wait(vnode_t *); 1814*0Sstevel@tonic-gate extern int nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *); 1815*0Sstevel@tonic-gate extern int nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *); 1816*0Sstevel@tonic-gate extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *, 1817*0Sstevel@tonic-gate nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t, 1818*0Sstevel@tonic-gate seqid4); 1819*0Sstevel@tonic-gate 1820*0Sstevel@tonic-gate extern void nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *, 1821*0Sstevel@tonic-gate nfs4_error_t *); 1822*0Sstevel@tonic-gate extern void nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *, 1823*0Sstevel@tonic-gate nfs4_server_t *); 1824*0Sstevel@tonic-gate extern int nfs4_rpc_retry_error(int); 1825*0Sstevel@tonic-gate extern int nfs4_try_failover(nfs4_error_t *); 1826*0Sstevel@tonic-gate extern void nfs4_free_msg(nfs4_debug_msg_t *); 1827*0Sstevel@tonic-gate extern void nfs4_mnt_recov_kstat_init(vfs_t *); 1828*0Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_delay(mntinfo4_t *); 1829*0Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_no_grace(mntinfo4_t *); 1830*0Sstevel@tonic-gate extern char *nfs4_stat_to_str(nfsstat4); 1831*0Sstevel@tonic-gate extern char *nfs4_op_to_str(nfs_opnum4); 1832*0Sstevel@tonic-gate 1833*0Sstevel@tonic-gate extern void nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *, 1834*0Sstevel@tonic-gate uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t, 1835*0Sstevel@tonic-gate nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4); 1836*0Sstevel@tonic-gate extern void nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4, 1837*0Sstevel@tonic-gate nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *); 1838*0Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_event) 1839*0Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_fact) 1840*0Sstevel@tonic-gate 1841*0Sstevel@tonic-gate /* Used for preformed "." and ".." dirents */ 1842*0Sstevel@tonic-gate extern char *nfs4_dot_entries; 1843*0Sstevel@tonic-gate extern char *nfs4_dot_dot_entry; 1844*0Sstevel@tonic-gate 1845*0Sstevel@tonic-gate #ifdef DEBUG 1846*0Sstevel@tonic-gate extern uint_t nfs4_tsd_key; 1847*0Sstevel@tonic-gate #endif 1848*0Sstevel@tonic-gate 1849*0Sstevel@tonic-gate #endif /* _KERNEL */ 1850*0Sstevel@tonic-gate 1851*0Sstevel@tonic-gate /* 1852*0Sstevel@tonic-gate * Filehandle management. 1853*0Sstevel@tonic-gate * 1854*0Sstevel@tonic-gate * Filehandles can change in v4, so rather than storing the filehandle 1855*0Sstevel@tonic-gate * directly in the rnode, etc., we manage the filehandle through one of 1856*0Sstevel@tonic-gate * these objects. 1857*0Sstevel@tonic-gate * Locking: sfh_fh and sfh_tree is protected by the filesystem's 1858*0Sstevel@tonic-gate * mi_fh_lock. The reference count and flags are protected by sfh_lock. 1859*0Sstevel@tonic-gate * sfh_mi is read-only. 1860*0Sstevel@tonic-gate * 1861*0Sstevel@tonic-gate * mntinfo4_t::mi_fh_lock > sfh_lock. 1862*0Sstevel@tonic-gate */ 1863*0Sstevel@tonic-gate 1864*0Sstevel@tonic-gate typedef struct nfs4_sharedfh { 1865*0Sstevel@tonic-gate nfs_fh4 sfh_fh; /* key and current filehandle */ 1866*0Sstevel@tonic-gate kmutex_t sfh_lock; 1867*0Sstevel@tonic-gate uint_t sfh_refcnt; /* reference count */ 1868*0Sstevel@tonic-gate uint_t sfh_flags; 1869*0Sstevel@tonic-gate mntinfo4_t *sfh_mi; /* backptr to filesystem */ 1870*0Sstevel@tonic-gate avl_node_t sfh_tree; /* used by avl package */ 1871*0Sstevel@tonic-gate } nfs4_sharedfh_t; 1872*0Sstevel@tonic-gate 1873*0Sstevel@tonic-gate #define SFH4_SAME(sfh1, sfh2) ((sfh1) == (sfh2)) 1874*0Sstevel@tonic-gate 1875*0Sstevel@tonic-gate /* 1876*0Sstevel@tonic-gate * Flags. 1877*0Sstevel@tonic-gate */ 1878*0Sstevel@tonic-gate #define SFH4_IN_TREE 0x1 /* currently in an AVL tree */ 1879*0Sstevel@tonic-gate 1880*0Sstevel@tonic-gate #ifdef _KERNEL 1881*0Sstevel@tonic-gate 1882*0Sstevel@tonic-gate extern void sfh4_createtab(avl_tree_t *); 1883*0Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *); 1884*0Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *, 1885*0Sstevel@tonic-gate nfs4_sharedfh_t *); 1886*0Sstevel@tonic-gate extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *); 1887*0Sstevel@tonic-gate extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *); 1888*0Sstevel@tonic-gate extern void sfh4_hold(nfs4_sharedfh_t *); 1889*0Sstevel@tonic-gate extern void sfh4_rele(nfs4_sharedfh_t **); 1890*0Sstevel@tonic-gate extern void sfh4_printfhandle(const nfs4_sharedfh_t *); 1891*0Sstevel@tonic-gate 1892*0Sstevel@tonic-gate #endif 1893*0Sstevel@tonic-gate 1894*0Sstevel@tonic-gate /* 1895*0Sstevel@tonic-gate * Path and file name management. 1896*0Sstevel@tonic-gate * 1897*0Sstevel@tonic-gate * This type stores the name of an entry in the filesystem and keeps enough 1898*0Sstevel@tonic-gate * information that it can provide a complete path. All fields are 1899*0Sstevel@tonic-gate * protected by fn_lock, except for the reference count, which is managed 1900*0Sstevel@tonic-gate * using atomic add/subtract. 1901*0Sstevel@tonic-gate * 1902*0Sstevel@tonic-gate * Lock order: child and then parent. 1903*0Sstevel@tonic-gate */ 1904*0Sstevel@tonic-gate 1905*0Sstevel@tonic-gate typedef struct nfs4_fname { 1906*0Sstevel@tonic-gate struct nfs4_fname *fn_parent; /* parent name; null if fs root */ 1907*0Sstevel@tonic-gate char *fn_name; /* the actual name */ 1908*0Sstevel@tonic-gate ssize_t fn_len; /* strlen(fn_name) */ 1909*0Sstevel@tonic-gate uint32_t fn_refcnt; /* reference count */ 1910*0Sstevel@tonic-gate kmutex_t fn_lock; 1911*0Sstevel@tonic-gate avl_node_t fn_tree; 1912*0Sstevel@tonic-gate avl_tree_t fn_children; /* children, if any */ 1913*0Sstevel@tonic-gate } nfs4_fname_t; 1914*0Sstevel@tonic-gate 1915*0Sstevel@tonic-gate #ifdef _KERNEL 1916*0Sstevel@tonic-gate 1917*0Sstevel@tonic-gate extern vnode_t nfs4_xattr_notsupp_vnode; 1918*0Sstevel@tonic-gate #define NFS4_XATTR_DIR_NOTSUPP &nfs4_xattr_notsupp_vnode 1919*0Sstevel@tonic-gate 1920*0Sstevel@tonic-gate extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *); 1921*0Sstevel@tonic-gate extern void fn_hold(nfs4_fname_t *); 1922*0Sstevel@tonic-gate extern void fn_rele(nfs4_fname_t **); 1923*0Sstevel@tonic-gate extern char *fn_name(nfs4_fname_t *); 1924*0Sstevel@tonic-gate extern char *fn_path(nfs4_fname_t *); 1925*0Sstevel@tonic-gate extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *); 1926*0Sstevel@tonic-gate extern nfs4_fname_t *fn_parent(nfs4_fname_t *); 1927*0Sstevel@tonic-gate 1928*0Sstevel@tonic-gate #endif 1929*0Sstevel@tonic-gate 1930*0Sstevel@tonic-gate /* 1931*0Sstevel@tonic-gate * Per-zone data for managing client handles, included in this file for the 1932*0Sstevel@tonic-gate * benefit of MDB. 1933*0Sstevel@tonic-gate */ 1934*0Sstevel@tonic-gate struct nfs4_clnt { 1935*0Sstevel@tonic-gate struct chhead *nfscl_chtable4; 1936*0Sstevel@tonic-gate kmutex_t nfscl_chtable4_lock; 1937*0Sstevel@tonic-gate zoneid_t nfscl_zoneid; 1938*0Sstevel@tonic-gate list_node_t nfscl_node; 1939*0Sstevel@tonic-gate struct clstat4 nfscl_stat; 1940*0Sstevel@tonic-gate }; 1941*0Sstevel@tonic-gate 1942*0Sstevel@tonic-gate #ifdef __cplusplus 1943*0Sstevel@tonic-gate } 1944*0Sstevel@tonic-gate #endif 1945*0Sstevel@tonic-gate 1946*0Sstevel@tonic-gate #endif /* _NFS4_CLNT_H */ 1947