10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51649Sdm120769 * Common Development and Distribution License (the "License"). 61649Sdm120769 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 226218Sth199096 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 270Sstevel@tonic-gate /* All Rights Reserved */ 280Sstevel@tonic-gate 290Sstevel@tonic-gate /* 300Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 310Sstevel@tonic-gate * under license from the Regents of the University of California. 320Sstevel@tonic-gate */ 330Sstevel@tonic-gate 340Sstevel@tonic-gate #ifndef _NFS4_CLNT_H 350Sstevel@tonic-gate #define _NFS4_CLNT_H 360Sstevel@tonic-gate 370Sstevel@tonic-gate #include <sys/errno.h> 380Sstevel@tonic-gate #include <sys/types.h> 390Sstevel@tonic-gate #include <sys/kstat.h> 400Sstevel@tonic-gate #include <sys/time.h> 410Sstevel@tonic-gate #include <sys/flock.h> 420Sstevel@tonic-gate #include <vm/page.h> 430Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 440Sstevel@tonic-gate #include <nfs/nfs4.h> 450Sstevel@tonic-gate #include <nfs/rnode.h> 460Sstevel@tonic-gate #include <sys/avl.h> 470Sstevel@tonic-gate #include <sys/list.h> 485302Sth199096 #include <rpc/auth.h> 490Sstevel@tonic-gate 500Sstevel@tonic-gate #ifdef __cplusplus 510Sstevel@tonic-gate extern "C" { 520Sstevel@tonic-gate #endif 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define NFS4_SIZE_OK(size) ((size) <= MAXOFFSET_T) 550Sstevel@tonic-gate 560Sstevel@tonic-gate /* Four states of nfs4_server's lease_valid */ 570Sstevel@tonic-gate #define NFS4_LEASE_INVALID 0 580Sstevel@tonic-gate #define NFS4_LEASE_VALID 1 590Sstevel@tonic-gate #define NFS4_LEASE_UNINITIALIZED 2 600Sstevel@tonic-gate #define NFS4_LEASE_NOT_STARTED 3 610Sstevel@tonic-gate 620Sstevel@tonic-gate /* flag to tell the renew thread it should exit */ 630Sstevel@tonic-gate #define NFS4_THREAD_EXIT 1 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* Default number of seconds to wait on GRACE and DELAY errors */ 660Sstevel@tonic-gate #define NFS4ERR_DELAY_TIME 10 670Sstevel@tonic-gate 680Sstevel@tonic-gate /* Number of hash buckets for open owners for each nfs4_server */ 690Sstevel@tonic-gate #define NFS4_NUM_OO_BUCKETS 53 700Sstevel@tonic-gate 710Sstevel@tonic-gate /* Number of freed open owners (per mntinfo4_t) to keep around */ 720Sstevel@tonic-gate #define NFS4_NUM_FREED_OPEN_OWNERS 8 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */ 750Sstevel@tonic-gate #define NFS4_RETRY_SCLID_DELAY 10 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */ 780Sstevel@tonic-gate #define NFS4_NUM_SCLID_RETRIES 3 790Sstevel@tonic-gate 800Sstevel@tonic-gate /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */ 810Sstevel@tonic-gate #define NFS4_NUM_RETRY_BAD_SEQID 3 820Sstevel@tonic-gate 830Sstevel@tonic-gate /* 840Sstevel@tonic-gate * Is the attribute cache valid? If client holds a delegation, then attrs 850Sstevel@tonic-gate * are by definition valid. If not, then check to see if attrs have timed out. 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate #define ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \ 880Sstevel@tonic-gate gethrtime() < VTOR4(vp)->r_time_attr_inval) 890Sstevel@tonic-gate 900Sstevel@tonic-gate /* 910Sstevel@tonic-gate * Flags to indicate whether to purge the DNLC for non-directory vnodes 920Sstevel@tonic-gate * in a call to nfs_purge_caches. 930Sstevel@tonic-gate */ 940Sstevel@tonic-gate #define NFS4_NOPURGE_DNLC 0 950Sstevel@tonic-gate #define NFS4_PURGE_DNLC 1 960Sstevel@tonic-gate 970Sstevel@tonic-gate /* 980Sstevel@tonic-gate * Is cache valid? 990Sstevel@tonic-gate * Swap is always valid, if no attributes (attrtime == 0) or 1000Sstevel@tonic-gate * if mtime matches cached mtime it is valid 1010Sstevel@tonic-gate * NOTE: mtime is now a timestruc_t. 1020Sstevel@tonic-gate * Caller should be holding the rnode r_statelock mutex. 1030Sstevel@tonic-gate */ 1040Sstevel@tonic-gate #define CACHE4_VALID(rp, mtime, fsize) \ 1050Sstevel@tonic-gate ((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP || \ 1060Sstevel@tonic-gate (((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec && \ 1070Sstevel@tonic-gate (mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \ 1080Sstevel@tonic-gate ((fsize) == (rp)->r_attr.va_size))) 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate /* 1110Sstevel@tonic-gate * Macro to detect forced unmount or a zone shutdown. 1120Sstevel@tonic-gate */ 1130Sstevel@tonic-gate #define FS_OR_ZONE_GONE4(vfsp) \ 1140Sstevel@tonic-gate (((vfsp)->vfs_flag & VFS_UNMOUNTED) || \ 1150Sstevel@tonic-gate zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* 1180Sstevel@tonic-gate * Macro to help determine whether a request failed because the underlying 1190Sstevel@tonic-gate * filesystem has been forcibly unmounted or because of zone shutdown. 1200Sstevel@tonic-gate */ 1210Sstevel@tonic-gate #define NFS4_FRC_UNMT_ERR(err, vfsp) \ 1220Sstevel@tonic-gate ((err) == EIO && FS_OR_ZONE_GONE4((vfsp))) 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate /* 1250Sstevel@tonic-gate * Due to the way the address space callbacks are used to execute a delmap, 1260Sstevel@tonic-gate * we must keep track of how many times the same thread has called 1270Sstevel@tonic-gate * VOP_DELMAP()->nfs4_delmap(). This is done by having a list of 1280Sstevel@tonic-gate * nfs4_delmapcall_t's associated with each rnode4_t. This list is protected 1290Sstevel@tonic-gate * by the rnode4_t's r_statelock. The individual elements do not need to be 1300Sstevel@tonic-gate * protected as they will only ever be created, modified and destroyed by 1310Sstevel@tonic-gate * one thread (the call_id). 1320Sstevel@tonic-gate * See nfs4_delmap() for further explanation. 1330Sstevel@tonic-gate */ 1340Sstevel@tonic-gate typedef struct nfs4_delmapcall { 1350Sstevel@tonic-gate kthread_t *call_id; 1360Sstevel@tonic-gate int error; /* error from delmap */ 1370Sstevel@tonic-gate list_node_t call_node; 1380Sstevel@tonic-gate } nfs4_delmapcall_t; 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate /* 1410Sstevel@tonic-gate * delmap address space callback args 1420Sstevel@tonic-gate */ 1430Sstevel@tonic-gate typedef struct nfs4_delmap_args { 1440Sstevel@tonic-gate vnode_t *vp; 1450Sstevel@tonic-gate offset_t off; 1460Sstevel@tonic-gate caddr_t addr; 1470Sstevel@tonic-gate size_t len; 1480Sstevel@tonic-gate uint_t prot; 1490Sstevel@tonic-gate uint_t maxprot; 1500Sstevel@tonic-gate uint_t flags; 1510Sstevel@tonic-gate cred_t *cr; 1520Sstevel@tonic-gate nfs4_delmapcall_t *caller; /* to retrieve errors from the cb */ 1530Sstevel@tonic-gate } nfs4_delmap_args_t; 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* 1560Sstevel@tonic-gate * client side statistics 1570Sstevel@tonic-gate */ 1580Sstevel@tonic-gate /* 1590Sstevel@tonic-gate * Per-zone counters 1600Sstevel@tonic-gate */ 1610Sstevel@tonic-gate struct clstat4 { 1620Sstevel@tonic-gate kstat_named_t calls; /* client requests */ 1630Sstevel@tonic-gate kstat_named_t badcalls; /* rpc failures */ 1640Sstevel@tonic-gate kstat_named_t clgets; /* client handle gets */ 1650Sstevel@tonic-gate kstat_named_t cltoomany; /* client handle cache misses */ 1660Sstevel@tonic-gate #ifdef DEBUG 1670Sstevel@tonic-gate kstat_named_t clalloc; /* number of client handles */ 1680Sstevel@tonic-gate kstat_named_t noresponse; /* server not responding cnt */ 1690Sstevel@tonic-gate kstat_named_t failover; /* server failover count */ 1700Sstevel@tonic-gate kstat_named_t remap; /* server remap count */ 1710Sstevel@tonic-gate #endif 1720Sstevel@tonic-gate }; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate #ifdef DEBUG 1750Sstevel@tonic-gate /* 1760Sstevel@tonic-gate * The following are statistics that describe the behavior of the system as a 1770Sstevel@tonic-gate * whole and don't correspond to any particular zone. 1780Sstevel@tonic-gate */ 1790Sstevel@tonic-gate struct clstat4_debug { 1800Sstevel@tonic-gate kstat_named_t nrnode; /* number of allocated rnodes */ 1810Sstevel@tonic-gate kstat_named_t access; /* size of access cache */ 1820Sstevel@tonic-gate kstat_named_t dirent; /* size of readdir cache */ 1830Sstevel@tonic-gate kstat_named_t dirents; /* size of readdir buf cache */ 1840Sstevel@tonic-gate kstat_named_t reclaim; /* number of reclaims */ 1850Sstevel@tonic-gate kstat_named_t clreclaim; /* number of cl reclaims */ 1860Sstevel@tonic-gate kstat_named_t f_reclaim; /* number of free reclaims */ 1870Sstevel@tonic-gate kstat_named_t a_reclaim; /* number of active reclaims */ 1880Sstevel@tonic-gate kstat_named_t r_reclaim; /* number of rnode reclaims */ 1890Sstevel@tonic-gate kstat_named_t rpath; /* bytes used to store rpaths */ 1900Sstevel@tonic-gate }; 1910Sstevel@tonic-gate extern struct clstat4_debug clstat4_debug; 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate #endif 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate /* 1960Sstevel@tonic-gate * The NFS specific async_reqs structure. 1970Sstevel@tonic-gate */ 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate enum iotype4 { 2000Sstevel@tonic-gate NFS4_READ_AHEAD, 2010Sstevel@tonic-gate NFS4_PUTAPAGE, 2020Sstevel@tonic-gate NFS4_PAGEIO, 2030Sstevel@tonic-gate NFS4_READDIR, 2040Sstevel@tonic-gate NFS4_INACTIVE, 2050Sstevel@tonic-gate NFS4_COMMIT 2060Sstevel@tonic-gate }; 2070Sstevel@tonic-gate #define NFS4_ASYNC_TYPES (NFS4_COMMIT + 1) 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate struct nfs4_async_read_req { 2100Sstevel@tonic-gate void (*readahead)(); /* pointer to readahead function */ 2110Sstevel@tonic-gate u_offset_t blkoff; /* offset in file */ 2120Sstevel@tonic-gate struct seg *seg; /* segment to do i/o to */ 2130Sstevel@tonic-gate caddr_t addr; /* address to do i/o to */ 2140Sstevel@tonic-gate }; 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate struct nfs4_pageio_req { 2170Sstevel@tonic-gate int (*pageio)(); /* pointer to pageio function */ 2180Sstevel@tonic-gate page_t *pp; /* page list */ 2190Sstevel@tonic-gate u_offset_t io_off; /* offset in file */ 2200Sstevel@tonic-gate uint_t io_len; /* size of request */ 2210Sstevel@tonic-gate int flags; 2220Sstevel@tonic-gate }; 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate struct nfs4_readdir_req { 2250Sstevel@tonic-gate int (*readdir)(); /* pointer to readdir function */ 2260Sstevel@tonic-gate struct rddir4_cache *rdc; /* pointer to cache entry to fill */ 2270Sstevel@tonic-gate }; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate struct nfs4_commit_req { 2300Sstevel@tonic-gate void (*commit)(); /* pointer to commit function */ 2310Sstevel@tonic-gate page_t *plist; /* page list */ 2320Sstevel@tonic-gate offset4 offset; /* starting offset */ 2330Sstevel@tonic-gate count4 count; /* size of range to be commited */ 2340Sstevel@tonic-gate }; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate struct nfs4_async_reqs { 2370Sstevel@tonic-gate struct nfs4_async_reqs *a_next; /* pointer to next arg struct */ 2380Sstevel@tonic-gate #ifdef DEBUG 2390Sstevel@tonic-gate kthread_t *a_queuer; /* thread id of queueing thread */ 2400Sstevel@tonic-gate #endif 2410Sstevel@tonic-gate struct vnode *a_vp; /* vnode pointer */ 2420Sstevel@tonic-gate struct cred *a_cred; /* cred pointer */ 2430Sstevel@tonic-gate enum iotype4 a_io; /* i/o type */ 2440Sstevel@tonic-gate union { 2450Sstevel@tonic-gate struct nfs4_async_read_req a_read_args; 2460Sstevel@tonic-gate struct nfs4_pageio_req a_pageio_args; 2470Sstevel@tonic-gate struct nfs4_readdir_req a_readdir_args; 2480Sstevel@tonic-gate struct nfs4_commit_req a_commit_args; 2490Sstevel@tonic-gate } a_args; 2500Sstevel@tonic-gate }; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate #define a_nfs4_readahead a_args.a_read_args.readahead 2530Sstevel@tonic-gate #define a_nfs4_blkoff a_args.a_read_args.blkoff 2540Sstevel@tonic-gate #define a_nfs4_seg a_args.a_read_args.seg 2550Sstevel@tonic-gate #define a_nfs4_addr a_args.a_read_args.addr 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate #define a_nfs4_putapage a_args.a_pageio_args.pageio 2580Sstevel@tonic-gate #define a_nfs4_pageio a_args.a_pageio_args.pageio 2590Sstevel@tonic-gate #define a_nfs4_pp a_args.a_pageio_args.pp 2600Sstevel@tonic-gate #define a_nfs4_off a_args.a_pageio_args.io_off 2610Sstevel@tonic-gate #define a_nfs4_len a_args.a_pageio_args.io_len 2620Sstevel@tonic-gate #define a_nfs4_flags a_args.a_pageio_args.flags 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate #define a_nfs4_readdir a_args.a_readdir_args.readdir 2650Sstevel@tonic-gate #define a_nfs4_rdc a_args.a_readdir_args.rdc 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate #define a_nfs4_commit a_args.a_commit_args.commit 2680Sstevel@tonic-gate #define a_nfs4_plist a_args.a_commit_args.plist 2690Sstevel@tonic-gate #define a_nfs4_offset a_args.a_commit_args.offset 2700Sstevel@tonic-gate #define a_nfs4_count a_args.a_commit_args.count 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate /* 2730Sstevel@tonic-gate * Security information 2740Sstevel@tonic-gate */ 2750Sstevel@tonic-gate typedef struct sv_secinfo { 2760Sstevel@tonic-gate uint_t count; /* how many sdata there are */ 2770Sstevel@tonic-gate uint_t index; /* which sdata[index] */ 2780Sstevel@tonic-gate struct sec_data *sdata; 2790Sstevel@tonic-gate } sv_secinfo_t; 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate /* 2820Sstevel@tonic-gate * Hash bucket for the mi's open owner list (mi_oo_list). 2830Sstevel@tonic-gate */ 2840Sstevel@tonic-gate typedef struct nfs4_oo_hash_bucket { 2850Sstevel@tonic-gate list_t b_oo_hash_list; 2860Sstevel@tonic-gate kmutex_t b_lock; 2870Sstevel@tonic-gate } nfs4_oo_hash_bucket_t; 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate /* 2900Sstevel@tonic-gate * Global array of ctags. 2910Sstevel@tonic-gate */ 2920Sstevel@tonic-gate extern ctag_t nfs4_ctags[]; 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate typedef enum nfs4_tag_type { 2950Sstevel@tonic-gate TAG_NONE, 2960Sstevel@tonic-gate TAG_ACCESS, 2970Sstevel@tonic-gate TAG_CLOSE, 2980Sstevel@tonic-gate TAG_CLOSE_LOST, 2990Sstevel@tonic-gate TAG_CLOSE_UNDO, 3000Sstevel@tonic-gate TAG_COMMIT, 3010Sstevel@tonic-gate TAG_DELEGRETURN, 3020Sstevel@tonic-gate TAG_FSINFO, 3030Sstevel@tonic-gate TAG_GET_SYMLINK, 3040Sstevel@tonic-gate TAG_GETATTR, 3050Sstevel@tonic-gate TAG_INACTIVE, 3060Sstevel@tonic-gate TAG_LINK, 3070Sstevel@tonic-gate TAG_LOCK, 3080Sstevel@tonic-gate TAG_LOCK_RECLAIM, 3090Sstevel@tonic-gate TAG_LOCK_RESEND, 3100Sstevel@tonic-gate TAG_LOCK_REINSTATE, 3110Sstevel@tonic-gate TAG_LOCK_UNKNOWN, 3120Sstevel@tonic-gate TAG_LOCKT, 3130Sstevel@tonic-gate TAG_LOCKU, 3140Sstevel@tonic-gate TAG_LOCKU_RESEND, 3150Sstevel@tonic-gate TAG_LOCKU_REINSTATE, 3160Sstevel@tonic-gate TAG_LOOKUP, 3170Sstevel@tonic-gate TAG_LOOKUP_PARENT, 3180Sstevel@tonic-gate TAG_LOOKUP_VALID, 3190Sstevel@tonic-gate TAG_LOOKUP_VPARENT, 3200Sstevel@tonic-gate TAG_MKDIR, 3210Sstevel@tonic-gate TAG_MKNOD, 3220Sstevel@tonic-gate TAG_MOUNT, 3230Sstevel@tonic-gate TAG_OPEN, 3240Sstevel@tonic-gate TAG_OPEN_CONFIRM, 3250Sstevel@tonic-gate TAG_OPEN_CONFIRM_LOST, 3260Sstevel@tonic-gate TAG_OPEN_DG, 3270Sstevel@tonic-gate TAG_OPEN_DG_LOST, 3280Sstevel@tonic-gate TAG_OPEN_LOST, 3290Sstevel@tonic-gate TAG_OPENATTR, 3300Sstevel@tonic-gate TAG_PATHCONF, 3310Sstevel@tonic-gate TAG_PUTROOTFH, 3320Sstevel@tonic-gate TAG_READ, 3330Sstevel@tonic-gate TAG_READAHEAD, 3340Sstevel@tonic-gate TAG_READDIR, 3350Sstevel@tonic-gate TAG_READLINK, 3360Sstevel@tonic-gate TAG_RELOCK, 3370Sstevel@tonic-gate TAG_REMAP_LOOKUP, 3380Sstevel@tonic-gate TAG_REMAP_LOOKUP_AD, 3390Sstevel@tonic-gate TAG_REMAP_LOOKUP_NA, 3400Sstevel@tonic-gate TAG_REMAP_MOUNT, 3410Sstevel@tonic-gate TAG_RMDIR, 3420Sstevel@tonic-gate TAG_REMOVE, 3430Sstevel@tonic-gate TAG_RENAME, 3440Sstevel@tonic-gate TAG_RENAME_VFH, 3450Sstevel@tonic-gate TAG_RENEW, 3460Sstevel@tonic-gate TAG_REOPEN, 3470Sstevel@tonic-gate TAG_REOPEN_LOST, 3480Sstevel@tonic-gate TAG_SECINFO, 3490Sstevel@tonic-gate TAG_SETATTR, 3500Sstevel@tonic-gate TAG_SETCLIENTID, 3510Sstevel@tonic-gate TAG_SETCLIENTID_CF, 3520Sstevel@tonic-gate TAG_SYMLINK, 3530Sstevel@tonic-gate TAG_WRITE 3540Sstevel@tonic-gate } nfs4_tag_type_t; 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate #define NFS4_TAG_INITIALIZER { \ 3570Sstevel@tonic-gate {TAG_NONE, "", \ 3580Sstevel@tonic-gate {0x20202020, 0x20202020, 0x20202020}}, \ 3590Sstevel@tonic-gate {TAG_ACCESS, "access", \ 3600Sstevel@tonic-gate {0x61636365, 0x73732020, 0x20202020}}, \ 3610Sstevel@tonic-gate {TAG_CLOSE, "close", \ 3620Sstevel@tonic-gate {0x636c6f73, 0x65202020, 0x20202020}}, \ 3630Sstevel@tonic-gate {TAG_CLOSE_LOST, "lost close", \ 3640Sstevel@tonic-gate {0x6c6f7374, 0x20636c6f, 0x73652020}}, \ 3650Sstevel@tonic-gate {TAG_CLOSE_UNDO, "undo close", \ 3660Sstevel@tonic-gate {0x756e646f, 0x20636c6f, 0x73652020}}, \ 3670Sstevel@tonic-gate {TAG_COMMIT, "commit", \ 3680Sstevel@tonic-gate {0x636f6d6d, 0x69742020, 0x20202020}}, \ 3690Sstevel@tonic-gate {TAG_DELEGRETURN, "delegreturn", \ 3700Sstevel@tonic-gate {0x64656c65, 0x67726574, 0x75726e20}}, \ 3710Sstevel@tonic-gate {TAG_FSINFO, "fsinfo", \ 3720Sstevel@tonic-gate {0x6673696e, 0x666f2020, 0x20202020}}, \ 3730Sstevel@tonic-gate {TAG_GET_SYMLINK, "get symlink text", \ 3740Sstevel@tonic-gate {0x67657420, 0x736c6e6b, 0x20747874}}, \ 3750Sstevel@tonic-gate {TAG_GETATTR, "getattr", \ 3760Sstevel@tonic-gate {0x67657461, 0x74747220, 0x20202020}}, \ 3770Sstevel@tonic-gate {TAG_INACTIVE, "inactive", \ 3780Sstevel@tonic-gate {0x696e6163, 0x74697665, 0x20202020}}, \ 3790Sstevel@tonic-gate {TAG_LINK, "link", \ 3800Sstevel@tonic-gate {0x6c696e6b, 0x20202020, 0x20202020}}, \ 3810Sstevel@tonic-gate {TAG_LOCK, "lock", \ 3820Sstevel@tonic-gate {0x6c6f636b, 0x20202020, 0x20202020}}, \ 3830Sstevel@tonic-gate {TAG_LOCK_RECLAIM, "reclaim lock", \ 3840Sstevel@tonic-gate {0x7265636c, 0x61696d20, 0x6c6f636b}}, \ 3850Sstevel@tonic-gate {TAG_LOCK_RESEND, "resend lock", \ 3860Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b20}}, \ 3870Sstevel@tonic-gate {TAG_LOCK_REINSTATE, "reinstate lock", \ 3880Sstevel@tonic-gate {0x7265696e, 0x7374206c, 0x6f636b20}}, \ 3890Sstevel@tonic-gate {TAG_LOCK_UNKNOWN, "unknown lock", \ 3900Sstevel@tonic-gate {0x756e6b6e, 0x6f776e20, 0x6c6f636b}}, \ 3910Sstevel@tonic-gate {TAG_LOCKT, "lock test", \ 3920Sstevel@tonic-gate {0x6c6f636b, 0x5f746573, 0x74202020}}, \ 3930Sstevel@tonic-gate {TAG_LOCKU, "unlock", \ 3940Sstevel@tonic-gate {0x756e6c6f, 0x636b2020, 0x20202020}}, \ 3950Sstevel@tonic-gate {TAG_LOCKU_RESEND, "resend locku", \ 3960Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b75}}, \ 3970Sstevel@tonic-gate {TAG_LOCKU_REINSTATE, "reinstate unlock", \ 3980Sstevel@tonic-gate {0x7265696e, 0x73742075, 0x6e6c636b}}, \ 3990Sstevel@tonic-gate {TAG_LOOKUP, "lookup", \ 4000Sstevel@tonic-gate {0x6c6f6f6b, 0x75702020, 0x20202020}}, \ 4010Sstevel@tonic-gate {TAG_LOOKUP_PARENT, "lookup parent", \ 4020Sstevel@tonic-gate {0x6c6f6f6b, 0x75702070, 0x6172656e}}, \ 4030Sstevel@tonic-gate {TAG_LOOKUP_VALID, "lookup valid", \ 4040Sstevel@tonic-gate {0x6c6f6f6b, 0x75702076, 0x616c6964}}, \ 4050Sstevel@tonic-gate {TAG_LOOKUP_VPARENT, "lookup valid parent", \ 4060Sstevel@tonic-gate {0x6c6f6f6b, 0x766c6420, 0x7061726e}}, \ 4070Sstevel@tonic-gate {TAG_MKDIR, "mkdir", \ 4080Sstevel@tonic-gate {0x6d6b6469, 0x72202020, 0x20202020}}, \ 4090Sstevel@tonic-gate {TAG_MKNOD, "mknod", \ 4100Sstevel@tonic-gate {0x6d6b6e6f, 0x64202020, 0x20202020}}, \ 4110Sstevel@tonic-gate {TAG_MOUNT, "mount", \ 4120Sstevel@tonic-gate {0x6d6f756e, 0x74202020, 0x20202020}}, \ 4130Sstevel@tonic-gate {TAG_OPEN, "open", \ 4140Sstevel@tonic-gate {0x6f70656e, 0x20202020, 0x20202020}}, \ 4150Sstevel@tonic-gate {TAG_OPEN_CONFIRM, "open confirm", \ 4160Sstevel@tonic-gate {0x6f70656e, 0x5f636f6e, 0x6669726d}}, \ 4170Sstevel@tonic-gate {TAG_OPEN_CONFIRM_LOST, "lost open confirm", \ 4180Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e5f636f}}, \ 4190Sstevel@tonic-gate {TAG_OPEN_DG, "open downgrade", \ 4200Sstevel@tonic-gate {0x6f70656e, 0x20646772, 0x61646520}}, \ 4210Sstevel@tonic-gate {TAG_OPEN_DG_LOST, "lost open downgrade", \ 4220Sstevel@tonic-gate {0x6c737420, 0x6f70656e, 0x20646772}}, \ 4230Sstevel@tonic-gate {TAG_OPEN_LOST, "lost open", \ 4240Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e202020}}, \ 4250Sstevel@tonic-gate {TAG_OPENATTR, "openattr", \ 4260Sstevel@tonic-gate {0x6f70656e, 0x61747472, 0x20202020}}, \ 4270Sstevel@tonic-gate {TAG_PATHCONF, "pathhconf", \ 4280Sstevel@tonic-gate {0x70617468, 0x636f6e66, 0x20202020}}, \ 4290Sstevel@tonic-gate {TAG_PUTROOTFH, "putrootfh", \ 4300Sstevel@tonic-gate {0x70757472, 0x6f6f7466, 0x68202020}}, \ 4310Sstevel@tonic-gate {TAG_READ, "read", \ 4320Sstevel@tonic-gate {0x72656164, 0x20202020, 0x20202020}}, \ 4330Sstevel@tonic-gate {TAG_READAHEAD, "readahead", \ 4340Sstevel@tonic-gate {0x72656164, 0x61686561, 0x64202020}}, \ 4350Sstevel@tonic-gate {TAG_READDIR, "readdir", \ 4360Sstevel@tonic-gate {0x72656164, 0x64697220, 0x20202020}}, \ 4370Sstevel@tonic-gate {TAG_READLINK, "readlink", \ 4380Sstevel@tonic-gate {0x72656164, 0x6c696e6b, 0x20202020}}, \ 4390Sstevel@tonic-gate {TAG_RELOCK, "relock", \ 4400Sstevel@tonic-gate {0x72656c6f, 0x636b2020, 0x20202020}}, \ 4410Sstevel@tonic-gate {TAG_REMAP_LOOKUP, "remap lookup", \ 4420Sstevel@tonic-gate {0x72656d61, 0x70206c6f, 0x6f6b7570}}, \ 4430Sstevel@tonic-gate {TAG_REMAP_LOOKUP_AD, "remap lookup attr dir", \ 4440Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206164}}, \ 4450Sstevel@tonic-gate {TAG_REMAP_LOOKUP_NA, "remap lookup named attrs", \ 4460Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206e61}}, \ 4470Sstevel@tonic-gate {TAG_REMAP_MOUNT, "remap mount", \ 4480Sstevel@tonic-gate {0x72656d61, 0x70206d6f, 0x756e7420}}, \ 4490Sstevel@tonic-gate {TAG_RMDIR, "rmdir", \ 4500Sstevel@tonic-gate {0x726d6469, 0x72202020, 0x20202020}}, \ 4510Sstevel@tonic-gate {TAG_REMOVE, "remove", \ 4520Sstevel@tonic-gate {0x72656d6f, 0x76652020, 0x20202020}}, \ 4530Sstevel@tonic-gate {TAG_RENAME, "rename", \ 4540Sstevel@tonic-gate {0x72656e61, 0x6d652020, 0x20202020}}, \ 4550Sstevel@tonic-gate {TAG_RENAME_VFH, "rename volatile fh", \ 4560Sstevel@tonic-gate {0x72656e61, 0x6d652028, 0x76666829}}, \ 4570Sstevel@tonic-gate {TAG_RENEW, "renew", \ 4580Sstevel@tonic-gate {0x72656e65, 0x77202020, 0x20202020}}, \ 4590Sstevel@tonic-gate {TAG_REOPEN, "reopen", \ 4600Sstevel@tonic-gate {0x72656f70, 0x656e2020, 0x20202020}}, \ 4610Sstevel@tonic-gate {TAG_REOPEN_LOST, "lost reopen", \ 4620Sstevel@tonic-gate {0x6c6f7374, 0x2072656f, 0x70656e20}}, \ 4630Sstevel@tonic-gate {TAG_SECINFO, "secinfo", \ 4640Sstevel@tonic-gate {0x73656369, 0x6e666f20, 0x20202020}}, \ 4650Sstevel@tonic-gate {TAG_SETATTR, "setattr", \ 4660Sstevel@tonic-gate {0x73657461, 0x74747220, 0x20202020}}, \ 4670Sstevel@tonic-gate {TAG_SETCLIENTID, "setclientid", \ 4680Sstevel@tonic-gate {0x73657463, 0x6c69656e, 0x74696420}}, \ 4690Sstevel@tonic-gate {TAG_SETCLIENTID_CF, "setclientid_confirm", \ 4700Sstevel@tonic-gate {0x73636c6e, 0x7469645f, 0x636f6e66}}, \ 4710Sstevel@tonic-gate {TAG_SYMLINK, "symlink", \ 4720Sstevel@tonic-gate {0x73796d6c, 0x696e6b20, 0x20202020}}, \ 4730Sstevel@tonic-gate {TAG_WRITE, "write", \ 4740Sstevel@tonic-gate {0x77726974, 0x65202020, 0x20202020}} \ 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate /* 4780Sstevel@tonic-gate * These flags are for differentiating the search criterian for 4790Sstevel@tonic-gate * find_open_owner(). The comparison is done with the open_owners's 4800Sstevel@tonic-gate * 'oo_just_created' flag. 4810Sstevel@tonic-gate */ 4820Sstevel@tonic-gate #define NFS4_PERM_CREATED 0x0 4830Sstevel@tonic-gate #define NFS4_JUST_CREATED 0x1 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate /* 4860Sstevel@tonic-gate * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw' 4870Sstevel@tonic-gate * is stored upon a successful OPEN. This is needed when the user's effective 4880Sstevel@tonic-gate * and real uid's don't match. The 'oo_cred_otw' overrides the credential 4890Sstevel@tonic-gate * passed down by VFS for async read/write, commit, lock, and close operations. 4900Sstevel@tonic-gate * 4910Sstevel@tonic-gate * The oo_ref_count keeps track the number of active references on this 4920Sstevel@tonic-gate * data structure + number of nfs4_open_streams point to this structure. 4930Sstevel@tonic-gate * 4940Sstevel@tonic-gate * 'oo_valid' tells whether this stuct is about to be freed or not. 4950Sstevel@tonic-gate * 4960Sstevel@tonic-gate * 'oo_just_created' tells us whether this struct has just been created but 4970Sstevel@tonic-gate * not been fully finalized (that is created upon an OPEN request and 4980Sstevel@tonic-gate * finalized upon the OPEN success). 4990Sstevel@tonic-gate * 5000Sstevel@tonic-gate * The 'oo_seqid_inuse' is for the open seqid synchronization. If a thread 5010Sstevel@tonic-gate * is currently using the open owner and it's open_seqid, then it sets the 5020Sstevel@tonic-gate * oo_seqid_inuse to true if it currently is not set. If it is set then it 5030Sstevel@tonic-gate * does a cv_wait on the oo_cv_seqid_sync condition variable. When the thread 5040Sstevel@tonic-gate * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process 5050Sstevel@tonic-gate * waiting on the condition variable. 5060Sstevel@tonic-gate * 5070Sstevel@tonic-gate * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW, 5080Sstevel@tonic-gate * and 'oo_last_good_op' is the operation that issued the last valid seqid. 5090Sstevel@tonic-gate * 5100Sstevel@tonic-gate * Lock ordering: 5110Sstevel@tonic-gate * mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list) 5120Sstevel@tonic-gate * 5130Sstevel@tonic-gate * oo_seqid_inuse > mntinfo4_t::mi_lock 5140Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statelock 5150Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statev4_lock 5160Sstevel@tonic-gate * oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock 5170Sstevel@tonic-gate * 5180Sstevel@tonic-gate * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects: 5190Sstevel@tonic-gate * oo_last_good_op 5200Sstevel@tonic-gate * oo_last_good_seqid 5210Sstevel@tonic-gate * oo_name 5220Sstevel@tonic-gate * oo_seqid 5230Sstevel@tonic-gate * 5240Sstevel@tonic-gate * The 'oo_lock' protects: 5250Sstevel@tonic-gate * oo_cred 5260Sstevel@tonic-gate * oo_cred_otw 5270Sstevel@tonic-gate * oo_foo_node 5280Sstevel@tonic-gate * oo_hash_node 5290Sstevel@tonic-gate * oo_just_created 5300Sstevel@tonic-gate * oo_ref_count 5310Sstevel@tonic-gate * oo_valid 5320Sstevel@tonic-gate */ 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate typedef struct nfs4_open_owner { 5350Sstevel@tonic-gate cred_t *oo_cred; 5360Sstevel@tonic-gate int oo_ref_count; 5370Sstevel@tonic-gate int oo_valid; 5380Sstevel@tonic-gate int oo_just_created; 5390Sstevel@tonic-gate seqid4 oo_seqid; 5400Sstevel@tonic-gate seqid4 oo_last_good_seqid; 5410Sstevel@tonic-gate nfs4_tag_type_t oo_last_good_op; 5420Sstevel@tonic-gate unsigned oo_seqid_inuse:1; 5430Sstevel@tonic-gate cred_t *oo_cred_otw; 5440Sstevel@tonic-gate kcondvar_t oo_cv_seqid_sync; 5450Sstevel@tonic-gate /* 5460Sstevel@tonic-gate * Fix this to always be 8 bytes 5470Sstevel@tonic-gate */ 5480Sstevel@tonic-gate uint64_t oo_name; 5490Sstevel@tonic-gate list_node_t oo_hash_node; 5500Sstevel@tonic-gate list_node_t oo_foo_node; 5510Sstevel@tonic-gate kmutex_t oo_lock; 5520Sstevel@tonic-gate } nfs4_open_owner_t; 5530Sstevel@tonic-gate 5540Sstevel@tonic-gate /* 5550Sstevel@tonic-gate * Static server information. 5560Sstevel@tonic-gate * These fields are read-only once they are initialized: 5570Sstevel@tonic-gate * sv_addr 5580Sstevel@tonic-gate * sv_dhsec 5590Sstevel@tonic-gate * sv_hostname 5600Sstevel@tonic-gate * sv_hostnamelen 5610Sstevel@tonic-gate * sv_knconf 5620Sstevel@tonic-gate * sv_next 5630Sstevel@tonic-gate * sv_origknconf 5640Sstevel@tonic-gate * 5650Sstevel@tonic-gate * These fields are protected by sv_lock: 5660Sstevel@tonic-gate * sv_currsec 5670Sstevel@tonic-gate * sv_fhandle 5680Sstevel@tonic-gate * sv_flags 5690Sstevel@tonic-gate * sv_fsid 5700Sstevel@tonic-gate * sv_path 5710Sstevel@tonic-gate * sv_pathlen 5720Sstevel@tonic-gate * sv_pfhandle 5730Sstevel@tonic-gate * sv_save_secinfo 5740Sstevel@tonic-gate * sv_savesec 5750Sstevel@tonic-gate * sv_secdata 5760Sstevel@tonic-gate * sv_secinfo 5770Sstevel@tonic-gate * sv_supp_attrs 5780Sstevel@tonic-gate * 5790Sstevel@tonic-gate * Lock ordering: 5800Sstevel@tonic-gate * nfs_rtable4_lock > sv_lock 5810Sstevel@tonic-gate * rnode4_t::r_statelock > sv_lock 5820Sstevel@tonic-gate */ 5830Sstevel@tonic-gate typedef struct servinfo4 { 5840Sstevel@tonic-gate struct knetconfig *sv_knconf; /* bound TLI fd */ 5850Sstevel@tonic-gate struct knetconfig *sv_origknconf; /* For RDMA save orig knconf */ 5860Sstevel@tonic-gate struct netbuf sv_addr; /* server's address */ 5870Sstevel@tonic-gate nfs4_fhandle_t sv_fhandle; /* this server's filehandle */ 5880Sstevel@tonic-gate nfs4_fhandle_t sv_pfhandle; /* parent dir filehandle */ 5890Sstevel@tonic-gate int sv_pathlen; /* Length of server path */ 5900Sstevel@tonic-gate char *sv_path; /* Path name on server */ 5910Sstevel@tonic-gate uint32_t sv_flags; /* flags for this server */ 5920Sstevel@tonic-gate sec_data_t *sv_secdata; /* client initiated security data */ 5930Sstevel@tonic-gate sv_secinfo_t *sv_secinfo; /* server security information */ 5940Sstevel@tonic-gate sec_data_t *sv_currsec; /* security data currently used; */ 5950Sstevel@tonic-gate /* points to one of the sec_data */ 5960Sstevel@tonic-gate /* entries in sv_secinfo */ 5970Sstevel@tonic-gate sv_secinfo_t *sv_save_secinfo; /* saved secinfo */ 5980Sstevel@tonic-gate sec_data_t *sv_savesec; /* saved security data */ 5990Sstevel@tonic-gate sec_data_t *sv_dhsec; /* AUTH_DH data from the user land */ 6000Sstevel@tonic-gate char *sv_hostname; /* server's hostname */ 6010Sstevel@tonic-gate int sv_hostnamelen; /* server's hostname length */ 6020Sstevel@tonic-gate fattr4_fsid sv_fsid; /* fsid of shared obj */ 6030Sstevel@tonic-gate fattr4_supported_attrs sv_supp_attrs; 6040Sstevel@tonic-gate struct servinfo4 *sv_next; /* next in list */ 6050Sstevel@tonic-gate nfs_rwlock_t sv_lock; 6060Sstevel@tonic-gate } servinfo4_t; 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate /* sv_flags fields */ 6090Sstevel@tonic-gate #define SV4_TRYSECINFO 0x001 /* try secinfo data from the server */ 6100Sstevel@tonic-gate #define SV4_TRYSECDEFAULT 0x002 /* try a default flavor */ 6110Sstevel@tonic-gate #define SV4_NOTINUSE 0x004 /* servinfo4_t had fatal errors */ 6120Sstevel@tonic-gate #define SV4_ROOT_STALE 0x008 /* root vnode got ESTALE */ 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate /* 6150Sstevel@tonic-gate * Lock call types. See nfs4frlock(). 6160Sstevel@tonic-gate */ 6170Sstevel@tonic-gate typedef enum nfs4_lock_call_type { 6180Sstevel@tonic-gate NFS4_LCK_CTYPE_NORM, 6190Sstevel@tonic-gate NFS4_LCK_CTYPE_RECLAIM, 6200Sstevel@tonic-gate NFS4_LCK_CTYPE_RESEND, 6210Sstevel@tonic-gate NFS4_LCK_CTYPE_REINSTATE 6220Sstevel@tonic-gate } nfs4_lock_call_type_t; 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate /* 6250Sstevel@tonic-gate * This structure holds the information for a lost open/close/open downgrade/ 6260Sstevel@tonic-gate * lock/locku request. It is also used for requests that are queued up so 6270Sstevel@tonic-gate * that the recovery thread can release server state after a forced 6280Sstevel@tonic-gate * unmount. 6290Sstevel@tonic-gate * "lr_op" is 0 if the struct is uninitialized. Otherwise, it is set to 6300Sstevel@tonic-gate * the proper OP_* nfs_opnum4 number. The other fields contain information 6310Sstevel@tonic-gate * to reconstruct the call. 6320Sstevel@tonic-gate * 6330Sstevel@tonic-gate * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the 6340Sstevel@tonic-gate * parent directroy without relying on vtodv (since we may not have a vp 6350Sstevel@tonic-gate * for the file we wish to create). 6360Sstevel@tonic-gate * 6370Sstevel@tonic-gate * lr_putfirst means that the request should go to the front of the resend 6380Sstevel@tonic-gate * queue, rather than the end. 6390Sstevel@tonic-gate */ 6400Sstevel@tonic-gate typedef struct nfs4_lost_rqst { 6410Sstevel@tonic-gate list_node_t lr_node; 6420Sstevel@tonic-gate nfs_opnum4 lr_op; 6430Sstevel@tonic-gate vnode_t *lr_vp; 6440Sstevel@tonic-gate vnode_t *lr_dvp; 6450Sstevel@tonic-gate nfs4_open_owner_t *lr_oop; 6460Sstevel@tonic-gate struct nfs4_open_stream *lr_osp; 6470Sstevel@tonic-gate struct nfs4_lock_owner *lr_lop; 6480Sstevel@tonic-gate cred_t *lr_cr; 6490Sstevel@tonic-gate flock64_t *lr_flk; 6500Sstevel@tonic-gate bool_t lr_putfirst; 6510Sstevel@tonic-gate union { 6520Sstevel@tonic-gate struct { 6530Sstevel@tonic-gate nfs4_lock_call_type_t lru_ctype; 6540Sstevel@tonic-gate nfs_lock_type4 lru_locktype; 6550Sstevel@tonic-gate } lru_lockargs; /* LOCK, LOCKU */ 6560Sstevel@tonic-gate struct { 6570Sstevel@tonic-gate uint32_t lru_oaccess; 6580Sstevel@tonic-gate uint32_t lru_odeny; 6590Sstevel@tonic-gate enum open_claim_type4 lru_oclaim; 6600Sstevel@tonic-gate stateid4 lru_ostateid; /* reopen only */ 6610Sstevel@tonic-gate component4 lru_ofile; 6620Sstevel@tonic-gate } lru_open_args; 6630Sstevel@tonic-gate struct { 6640Sstevel@tonic-gate uint32_t lru_dg_access; 6650Sstevel@tonic-gate uint32_t lru_dg_deny; 6660Sstevel@tonic-gate } lru_open_dg_args; 6670Sstevel@tonic-gate } nfs4_lr_u; 6680Sstevel@tonic-gate } nfs4_lost_rqst_t; 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate #define lr_oacc nfs4_lr_u.lru_open_args.lru_oaccess 6710Sstevel@tonic-gate #define lr_odeny nfs4_lr_u.lru_open_args.lru_odeny 6720Sstevel@tonic-gate #define lr_oclaim nfs4_lr_u.lru_open_args.lru_oclaim 6730Sstevel@tonic-gate #define lr_ostateid nfs4_lr_u.lru_open_args.lru_ostateid 6740Sstevel@tonic-gate #define lr_ofile nfs4_lr_u.lru_open_args.lru_ofile 6750Sstevel@tonic-gate #define lr_dg_acc nfs4_lr_u.lru_open_dg_args.lru_dg_access 6760Sstevel@tonic-gate #define lr_dg_deny nfs4_lr_u.lru_open_dg_args.lru_dg_deny 6770Sstevel@tonic-gate #define lr_ctype nfs4_lr_u.lru_lockargs.lru_ctype 6780Sstevel@tonic-gate #define lr_locktype nfs4_lr_u.lru_lockargs.lru_locktype 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate /* 6810Sstevel@tonic-gate * Recovery actions. Some actions can imply further recovery using a 6820Sstevel@tonic-gate * different recovery action (e.g., recovering the clientid leads to 6830Sstevel@tonic-gate * recovering open files and locks). 6840Sstevel@tonic-gate */ 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate typedef enum { 6870Sstevel@tonic-gate NR_UNUSED, 6880Sstevel@tonic-gate NR_CLIENTID, 6890Sstevel@tonic-gate NR_OPENFILES, 6900Sstevel@tonic-gate NR_FHEXPIRED, 6910Sstevel@tonic-gate NR_FAILOVER, 6920Sstevel@tonic-gate NR_WRONGSEC, 6930Sstevel@tonic-gate NR_EXPIRED, 6940Sstevel@tonic-gate NR_BAD_STATEID, 6950Sstevel@tonic-gate NR_BADHANDLE, 6960Sstevel@tonic-gate NR_BAD_SEQID, 6970Sstevel@tonic-gate NR_OLDSTATEID, 6980Sstevel@tonic-gate NR_GRACE, 6990Sstevel@tonic-gate NR_DELAY, 7000Sstevel@tonic-gate NR_LOST_LOCK, 7010Sstevel@tonic-gate NR_LOST_STATE_RQST, 7020Sstevel@tonic-gate NR_STALE 7030Sstevel@tonic-gate } nfs4_recov_t; 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate /* 7060Sstevel@tonic-gate * Administrative and debug message framework. 7070Sstevel@tonic-gate */ 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate #define NFS4_MSG_MAX 100 7100Sstevel@tonic-gate extern int nfs4_msg_max; 7110Sstevel@tonic-gate 7120Sstevel@tonic-gate typedef enum { 7130Sstevel@tonic-gate RE_BAD_SEQID, 7140Sstevel@tonic-gate RE_BADHANDLE, 7150Sstevel@tonic-gate RE_CLIENTID, 7160Sstevel@tonic-gate RE_DEAD_FILE, 7170Sstevel@tonic-gate RE_END, 7180Sstevel@tonic-gate RE_FAIL_RELOCK, 7190Sstevel@tonic-gate RE_FAIL_REMAP_LEN, 7200Sstevel@tonic-gate RE_FAIL_REMAP_OP, 7210Sstevel@tonic-gate RE_FAILOVER, 7220Sstevel@tonic-gate RE_FILE_DIFF, 7230Sstevel@tonic-gate RE_LOST_STATE, 7240Sstevel@tonic-gate RE_OPENS_CHANGED, 7250Sstevel@tonic-gate RE_SIGLOST, 7260Sstevel@tonic-gate RE_SIGLOST_NO_DUMP, 7270Sstevel@tonic-gate RE_START, 7280Sstevel@tonic-gate RE_UNEXPECTED_ACTION, 7290Sstevel@tonic-gate RE_UNEXPECTED_ERRNO, 7300Sstevel@tonic-gate RE_UNEXPECTED_STATUS, 7310Sstevel@tonic-gate RE_WRONGSEC, 7320Sstevel@tonic-gate RE_LOST_STATE_BAD_OP 7330Sstevel@tonic-gate } nfs4_event_type_t; 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate typedef enum { 7360Sstevel@tonic-gate RFS_NO_INSPECT, 7370Sstevel@tonic-gate RFS_INSPECT 7380Sstevel@tonic-gate } nfs4_fact_status_t; 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate typedef enum { 7410Sstevel@tonic-gate RF_BADOWNER, 7420Sstevel@tonic-gate RF_ERR, 7430Sstevel@tonic-gate RF_RENEW_EXPIRED, 7440Sstevel@tonic-gate RF_SRV_NOT_RESPOND, 7450Sstevel@tonic-gate RF_SRV_OK, 7460Sstevel@tonic-gate RF_SRVS_NOT_RESPOND, 7470Sstevel@tonic-gate RF_SRVS_OK, 7480Sstevel@tonic-gate RF_DELMAP_CB_ERR 7490Sstevel@tonic-gate } nfs4_fact_type_t; 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate typedef enum { 7520Sstevel@tonic-gate NFS4_MS_DUMP, 7530Sstevel@tonic-gate NFS4_MS_NO_DUMP 7540Sstevel@tonic-gate } nfs4_msg_status_t; 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate typedef struct nfs4_rfact { 7570Sstevel@tonic-gate nfs4_fact_type_t rf_type; 7580Sstevel@tonic-gate nfs4_fact_status_t rf_status; 7590Sstevel@tonic-gate bool_t rf_reboot; 7600Sstevel@tonic-gate nfs4_recov_t rf_action; 7610Sstevel@tonic-gate nfs_opnum4 rf_op; 7620Sstevel@tonic-gate nfsstat4 rf_stat4; 7630Sstevel@tonic-gate timespec_t rf_time; 7640Sstevel@tonic-gate int rf_error; 7650Sstevel@tonic-gate struct rnode4 *rf_rp1; 7660Sstevel@tonic-gate char *rf_char1; 7670Sstevel@tonic-gate } nfs4_rfact_t; 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate typedef struct nfs4_revent { 7700Sstevel@tonic-gate nfs4_event_type_t re_type; 7710Sstevel@tonic-gate nfsstat4 re_stat4; 7720Sstevel@tonic-gate uint_t re_uint; 7730Sstevel@tonic-gate pid_t re_pid; 7740Sstevel@tonic-gate struct mntinfo4 *re_mi; 7750Sstevel@tonic-gate struct rnode4 *re_rp1; 7760Sstevel@tonic-gate struct rnode4 *re_rp2; 7770Sstevel@tonic-gate char *re_char1; 7780Sstevel@tonic-gate char *re_char2; 7790Sstevel@tonic-gate nfs4_tag_type_t re_tag1; 7800Sstevel@tonic-gate nfs4_tag_type_t re_tag2; 7810Sstevel@tonic-gate seqid4 re_seqid1; 7820Sstevel@tonic-gate seqid4 re_seqid2; 7830Sstevel@tonic-gate } nfs4_revent_t; 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate typedef enum { 7860Sstevel@tonic-gate RM_EVENT, 7870Sstevel@tonic-gate RM_FACT 7880Sstevel@tonic-gate } nfs4_msg_type_t; 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate typedef struct nfs4_debug_msg { 7910Sstevel@tonic-gate timespec_t msg_time; 7920Sstevel@tonic-gate nfs4_msg_type_t msg_type; 7930Sstevel@tonic-gate char *msg_srv; 7940Sstevel@tonic-gate char *msg_mntpt; 7950Sstevel@tonic-gate union { 7960Sstevel@tonic-gate nfs4_rfact_t msg_fact; 7970Sstevel@tonic-gate nfs4_revent_t msg_event; 7980Sstevel@tonic-gate } rmsg_u; 7990Sstevel@tonic-gate nfs4_msg_status_t msg_status; 8000Sstevel@tonic-gate list_node_t msg_node; 8010Sstevel@tonic-gate } nfs4_debug_msg_t; 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate /* 8040Sstevel@tonic-gate * NFS private data per mounted file system 8050Sstevel@tonic-gate * The mi_lock mutex protects the following fields: 8060Sstevel@tonic-gate * mi_flags 8070Sstevel@tonic-gate * mi_in_recovery 8080Sstevel@tonic-gate * mi_recovflags 8090Sstevel@tonic-gate * mi_recovthread 8100Sstevel@tonic-gate * mi_error 8110Sstevel@tonic-gate * mi_printed 8120Sstevel@tonic-gate * mi_down 8130Sstevel@tonic-gate * mi_stsize 8140Sstevel@tonic-gate * mi_curread 8150Sstevel@tonic-gate * mi_curwrite 8160Sstevel@tonic-gate * mi_timers 8170Sstevel@tonic-gate * mi_curr_serv 8180Sstevel@tonic-gate * mi_klmconfig 8190Sstevel@tonic-gate * mi_oo_list 8200Sstevel@tonic-gate * mi_foo_list 8210Sstevel@tonic-gate * mi_foo_num 8220Sstevel@tonic-gate * mi_foo_max 8230Sstevel@tonic-gate * mi_lost_state 8240Sstevel@tonic-gate * mi_bseqid_list 8255302Sth199096 * mi_ephemeral 8265302Sth199096 * mi_ephemeral_tree 8270Sstevel@tonic-gate * 8280Sstevel@tonic-gate * Normally the netconfig information for the mount comes from 8290Sstevel@tonic-gate * mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a 8300Sstevel@tonic-gate * different transport, mi_klmconfig contains the necessary netconfig 8310Sstevel@tonic-gate * information. 8320Sstevel@tonic-gate * 8330Sstevel@tonic-gate * The mi_async_lock mutex protects the following fields: 8340Sstevel@tonic-gate * mi_async_reqs 8350Sstevel@tonic-gate * mi_async_req_count 8360Sstevel@tonic-gate * mi_async_tail 8370Sstevel@tonic-gate * mi_async_curr 8380Sstevel@tonic-gate * mi_async_clusters 8390Sstevel@tonic-gate * mi_async_init_clusters 8400Sstevel@tonic-gate * mi_threads 8410Sstevel@tonic-gate * mi_inactive_thread 8420Sstevel@tonic-gate * mi_manager_thread 8430Sstevel@tonic-gate * 8440Sstevel@tonic-gate * The nfs4_server_t::s_lock protects the following fields: 8450Sstevel@tonic-gate * mi_clientid 8460Sstevel@tonic-gate * mi_clientid_next 8470Sstevel@tonic-gate * mi_clientid_prev 8480Sstevel@tonic-gate * mi_open_files 8490Sstevel@tonic-gate * mi_srvsettime 8500Sstevel@tonic-gate * 851163Sek110237 * The mntinfo4_t::mi_recovlock protects the following fields: 852163Sek110237 * mi_srvsettime 853163Sek110237 * 8540Sstevel@tonic-gate * Locking order: 8550Sstevel@tonic-gate * mi4_globals::mig_lock > mi_async_lock 8560Sstevel@tonic-gate * mi_async_lock > nfs4_server_t::s_lock > mi_lock 8570Sstevel@tonic-gate * mi_recovlock > mi_rename_lock > nfs_rtable4_lock 8580Sstevel@tonic-gate * nfs4_server_t::s_recovlock > mi_recovlock 8590Sstevel@tonic-gate * rnode4_t::r_rwlock > mi_rename_lock 8600Sstevel@tonic-gate * nfs_rtable4_lock > mi_lock 8610Sstevel@tonic-gate * nfs4_server_t::s_lock > mi_msg_list_lock 862163Sek110237 * mi_recovlock > nfs4_server_t::s_lock 863163Sek110237 * mi_recovlock > nfs4_server_lst_lock 8640Sstevel@tonic-gate * 8650Sstevel@tonic-gate * The 'mi_oo_list' represents the hash buckets that contain the 8660Sstevel@tonic-gate * nfs4_open_owenrs for this particular mntinfo4. 8670Sstevel@tonic-gate * 8680Sstevel@tonic-gate * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4. 8690Sstevel@tonic-gate * 'mi_foo_num' is the current number of freed open owners on the list, 8700Sstevel@tonic-gate * 'mi_foo_max' is the maximum number of freed open owners that are allowable 8710Sstevel@tonic-gate * on the list. 8720Sstevel@tonic-gate * 8730Sstevel@tonic-gate * mi_rootfh and mi_srvparentfh are read-only once created, but that just 8740Sstevel@tonic-gate * refers to the pointer. The contents must be updated to keep in sync 8750Sstevel@tonic-gate * with mi_curr_serv. 8760Sstevel@tonic-gate * 8770Sstevel@tonic-gate * The mi_msg_list_lock protects against adding/deleting entries to the 8780Sstevel@tonic-gate * mi_msg_list, and also the updating/retrieving of mi_lease_period; 8790Sstevel@tonic-gate * 8800Sstevel@tonic-gate * 'mi_zone' is initialized at structure creation time, and never 8810Sstevel@tonic-gate * changes; it may be read without a lock. 8820Sstevel@tonic-gate * 8830Sstevel@tonic-gate * mi_zone_node is linkage into the mi4_globals.mig_list, and is 8840Sstevel@tonic-gate * protected by mi4_globals.mig_list_lock. 8855302Sth199096 * 8865302Sth199096 * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an 8875302Sth199096 * ephemeral structure for this ephemeral mount point. It can not be 8885302Sth199096 * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral 8895302Sth199096 * tree. 8905302Sth199096 * 8915302Sth199096 * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has 8925302Sth199096 * to be NULL. If mi_ephemeral_tree is non-NULL, then this node 8935302Sth199096 * is the enclosing mntinfo4 for the ephemeral tree. 8940Sstevel@tonic-gate */ 8950Sstevel@tonic-gate struct zone; 8965302Sth199096 struct nfs4_ephemeral; 8975302Sth199096 struct nfs4_ephemeral_tree; 8980Sstevel@tonic-gate typedef struct mntinfo4 { 8990Sstevel@tonic-gate kmutex_t mi_lock; /* protects mntinfo4 fields */ 9000Sstevel@tonic-gate struct servinfo4 *mi_servers; /* server list */ 9010Sstevel@tonic-gate struct servinfo4 *mi_curr_serv; /* current server */ 9020Sstevel@tonic-gate struct nfs4_sharedfh *mi_rootfh; /* root filehandle */ 9030Sstevel@tonic-gate struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */ 9040Sstevel@tonic-gate kcondvar_t mi_failover_cv; /* failover synchronization */ 9050Sstevel@tonic-gate struct vfs *mi_vfsp; /* back pointer to vfs */ 9060Sstevel@tonic-gate enum vtype mi_type; /* file type of the root vnode */ 9070Sstevel@tonic-gate uint_t mi_flags; /* see below */ 9080Sstevel@tonic-gate uint_t mi_recovflags; /* if recovery active; see below */ 9090Sstevel@tonic-gate kthread_t *mi_recovthread; /* active recov thread or NULL */ 9100Sstevel@tonic-gate uint_t mi_error; /* only set/valid when MI4_RECOV_FAIL */ 9110Sstevel@tonic-gate /* is set in mi_flags */ 9120Sstevel@tonic-gate int mi_tsize; /* transfer size (bytes) */ 9130Sstevel@tonic-gate /* really read size */ 9140Sstevel@tonic-gate int mi_stsize; /* server's max transfer size (bytes) */ 9150Sstevel@tonic-gate /* really write size */ 9160Sstevel@tonic-gate int mi_timeo; /* inital timeout in 10th sec */ 9170Sstevel@tonic-gate int mi_retrans; /* times to retry request */ 9180Sstevel@tonic-gate hrtime_t mi_acregmin; /* min time to hold cached file attr */ 9190Sstevel@tonic-gate hrtime_t mi_acregmax; /* max time to hold cached file attr */ 9200Sstevel@tonic-gate hrtime_t mi_acdirmin; /* min time to hold cached dir attr */ 9210Sstevel@tonic-gate hrtime_t mi_acdirmax; /* max time to hold cached dir attr */ 9220Sstevel@tonic-gate len_t mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */ 9230Sstevel@tonic-gate int mi_curread; /* current read size */ 9240Sstevel@tonic-gate int mi_curwrite; /* current write size */ 9251705Sjwahlig uint_t mi_count; /* ref count */ 9260Sstevel@tonic-gate /* 9270Sstevel@tonic-gate * async I/O management. There may be a pool of threads to handle 9280Sstevel@tonic-gate * async I/O requests, etc., plus there is always one thread that 9290Sstevel@tonic-gate * handles over-the-wire requests for VOP_INACTIVE. The async pool 9300Sstevel@tonic-gate * can also help out with VOP_INACTIVE. 9310Sstevel@tonic-gate */ 9320Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES]; 9330Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES]; 9340Sstevel@tonic-gate struct nfs4_async_reqs **mi_async_curr; /* current async queue */ 9350Sstevel@tonic-gate uint_t mi_async_clusters[NFS4_ASYNC_TYPES]; 9360Sstevel@tonic-gate uint_t mi_async_init_clusters; 9370Sstevel@tonic-gate uint_t mi_async_req_count; /* # outstanding work requests */ 9380Sstevel@tonic-gate kcondvar_t mi_async_reqs_cv; /* signaled when there's work */ 9390Sstevel@tonic-gate ushort_t mi_threads; /* number of active async threads */ 9400Sstevel@tonic-gate ushort_t mi_max_threads; /* max number of async threads */ 9410Sstevel@tonic-gate kthread_t *mi_manager_thread; /* async manager thread id */ 9420Sstevel@tonic-gate kthread_t *mi_inactive_thread; /* inactive thread id */ 9430Sstevel@tonic-gate kcondvar_t mi_inact_req_cv; /* notify VOP_INACTIVE thread */ 9440Sstevel@tonic-gate kcondvar_t mi_async_work_cv; /* tell workers to work */ 9450Sstevel@tonic-gate kcondvar_t mi_async_cv; /* all pool threads exited */ 9460Sstevel@tonic-gate kmutex_t mi_async_lock; 9470Sstevel@tonic-gate /* 9480Sstevel@tonic-gate * Other stuff 9490Sstevel@tonic-gate */ 9500Sstevel@tonic-gate struct pathcnf *mi_pathconf; /* static pathconf kludge */ 9510Sstevel@tonic-gate rpcprog_t mi_prog; /* RPC program number */ 9520Sstevel@tonic-gate rpcvers_t mi_vers; /* RPC program version number */ 9530Sstevel@tonic-gate char **mi_rfsnames; /* mapping to proc names */ 9540Sstevel@tonic-gate kstat_named_t *mi_reqs; /* count of requests */ 9550Sstevel@tonic-gate clock_t mi_printftime; /* last error printf time */ 9560Sstevel@tonic-gate nfs_rwlock_t mi_recovlock; /* separate ops from recovery (v4) */ 9570Sstevel@tonic-gate time_t mi_grace_wait; /* non-zero represents time to wait */ 9580Sstevel@tonic-gate time_t mi_srvsettime; /* when we switched nfs4_server_t */ 9590Sstevel@tonic-gate nfs_rwlock_t mi_rename_lock; /* atomic volfh rename */ 9600Sstevel@tonic-gate struct nfs4_fname *mi_fname; /* root fname */ 9610Sstevel@tonic-gate list_t mi_lost_state; /* resend list */ 9620Sstevel@tonic-gate list_t mi_bseqid_list; /* bad seqid list */ 9630Sstevel@tonic-gate /* 9640Sstevel@tonic-gate * Client Side Failover stats 9650Sstevel@tonic-gate */ 9660Sstevel@tonic-gate uint_t mi_noresponse; /* server not responding count */ 9670Sstevel@tonic-gate uint_t mi_failover; /* failover to new server count */ 9680Sstevel@tonic-gate uint_t mi_remap; /* remap to new server count */ 9690Sstevel@tonic-gate /* 9700Sstevel@tonic-gate * Kstat statistics 9710Sstevel@tonic-gate */ 9720Sstevel@tonic-gate struct kstat *mi_io_kstats; 9730Sstevel@tonic-gate struct kstat *mi_ro_kstats; 9740Sstevel@tonic-gate kstat_t *mi_recov_ksp; /* ptr to the recovery kstat */ 9750Sstevel@tonic-gate 9760Sstevel@tonic-gate /* 9770Sstevel@tonic-gate * Volatile fh flags (nfsv4) 9780Sstevel@tonic-gate */ 9790Sstevel@tonic-gate uint32_t mi_fh_expire_type; 9800Sstevel@tonic-gate /* 9810Sstevel@tonic-gate * Lease Management 9820Sstevel@tonic-gate */ 9830Sstevel@tonic-gate struct mntinfo4 *mi_clientid_next; 9840Sstevel@tonic-gate struct mntinfo4 *mi_clientid_prev; 9850Sstevel@tonic-gate clientid4 mi_clientid; /* redundant info found in nfs4_server */ 9860Sstevel@tonic-gate int mi_open_files; /* count of open files */ 9870Sstevel@tonic-gate int mi_in_recovery; /* count of recovery instances */ 9880Sstevel@tonic-gate kcondvar_t mi_cv_in_recov; /* cv for recovery threads */ 9890Sstevel@tonic-gate /* 9900Sstevel@tonic-gate * Open owner stuff. 9910Sstevel@tonic-gate */ 9920Sstevel@tonic-gate struct nfs4_oo_hash_bucket mi_oo_list[NFS4_NUM_OO_BUCKETS]; 9930Sstevel@tonic-gate list_t mi_foo_list; 9940Sstevel@tonic-gate int mi_foo_num; 9950Sstevel@tonic-gate int mi_foo_max; 9960Sstevel@tonic-gate /* 9970Sstevel@tonic-gate * Shared filehandle pool. 9980Sstevel@tonic-gate */ 9990Sstevel@tonic-gate nfs_rwlock_t mi_fh_lock; 10000Sstevel@tonic-gate avl_tree_t mi_filehandles; 10010Sstevel@tonic-gate 10020Sstevel@tonic-gate /* 10030Sstevel@tonic-gate * Debug message queue. 10040Sstevel@tonic-gate */ 10050Sstevel@tonic-gate list_t mi_msg_list; 10060Sstevel@tonic-gate int mi_msg_count; 10070Sstevel@tonic-gate time_t mi_lease_period; 10080Sstevel@tonic-gate /* 10090Sstevel@tonic-gate * not guaranteed to be accurate. 10100Sstevel@tonic-gate * only should be used by debug queue. 10110Sstevel@tonic-gate */ 10120Sstevel@tonic-gate kmutex_t mi_msg_list_lock; 10130Sstevel@tonic-gate /* 10140Sstevel@tonic-gate * Zones support. 10150Sstevel@tonic-gate */ 10160Sstevel@tonic-gate struct zone *mi_zone; /* Zone mounted in */ 10170Sstevel@tonic-gate list_node_t mi_zone_node; /* linkage into per-zone mi list */ 10185302Sth199096 10195302Sth199096 /* 10205302Sth199096 * Links for unmounting ephemeral mounts. 10215302Sth199096 */ 10225302Sth199096 struct nfs4_ephemeral *mi_ephemeral; 10235302Sth199096 struct nfs4_ephemeral_tree *mi_ephemeral_tree; 10240Sstevel@tonic-gate } mntinfo4_t; 10250Sstevel@tonic-gate 10260Sstevel@tonic-gate /* 10270Sstevel@tonic-gate * The values for mi_flags. 10280Sstevel@tonic-gate * 10290Sstevel@tonic-gate * MI4_HARD hard or soft mount 10300Sstevel@tonic-gate * MI4_PRINTED responding message printed 10310Sstevel@tonic-gate * MI4_INT allow INTR on hard mount 10320Sstevel@tonic-gate * MI4_DOWN server is down 10330Sstevel@tonic-gate * MI4_NOAC don't cache attributes 10340Sstevel@tonic-gate * MI4_NOCTO no close-to-open consistency 10350Sstevel@tonic-gate * MI4_LLOCK local locking only (no lockmgr) 10360Sstevel@tonic-gate * MI4_GRPID System V group id inheritance 10370Sstevel@tonic-gate * MI4_SHUTDOWN System is rebooting or shutting down 10380Sstevel@tonic-gate * MI4_LINK server supports link 10390Sstevel@tonic-gate * MI4_SYMLINK server supports symlink 10405302Sth199096 * MI4_EPHEMERAL_RECURSED an ephemeral mount being unmounted 10415302Sth199096 * due to a recursive call - no need 10425302Sth199096 * for additional recursion 10430Sstevel@tonic-gate * MI4_ACL server supports NFSv4 ACLs 10445302Sth199096 * MI4_MIRRORMOUNT is a mirrormount 10450Sstevel@tonic-gate * MI4_NOPRINT don't print messages 10460Sstevel@tonic-gate * MI4_DIRECTIO do direct I/O 10470Sstevel@tonic-gate * MI4_RECOV_ACTIV filesystem has recovery a thread 10480Sstevel@tonic-gate * MI4_REMOVE_ON_LAST_CLOSE remove from server's list 10490Sstevel@tonic-gate * MI4_RECOV_FAIL client recovery failed 10500Sstevel@tonic-gate * MI4_PUBLIC public/url option used 10510Sstevel@tonic-gate * MI4_MOUNTING mount in progress, don't failover 10520Sstevel@tonic-gate * MI4_POSIX_LOCK if server is using POSIX locking 10530Sstevel@tonic-gate * MI4_LOCK_DEBUG cmn_err'd posix lock err msg 10541705Sjwahlig * MI4_DEAD zone has released it 10550Sstevel@tonic-gate * MI4_INACTIVE_IDLE inactive thread idle 10560Sstevel@tonic-gate * MI4_BADOWNER_DEBUG badowner error msg per mount 10570Sstevel@tonic-gate * MI4_ASYNC_MGR_STOP tell async manager to die 10580Sstevel@tonic-gate * MI4_TIMEDOUT saw a timeout during zone shutdown 10595302Sth199096 * MI4_EPHEMERAL is an ephemeral mount 10600Sstevel@tonic-gate */ 10610Sstevel@tonic-gate #define MI4_HARD 0x1 10620Sstevel@tonic-gate #define MI4_PRINTED 0x2 10630Sstevel@tonic-gate #define MI4_INT 0x4 10640Sstevel@tonic-gate #define MI4_DOWN 0x8 10650Sstevel@tonic-gate #define MI4_NOAC 0x10 10660Sstevel@tonic-gate #define MI4_NOCTO 0x20 10670Sstevel@tonic-gate #define MI4_LLOCK 0x80 10680Sstevel@tonic-gate #define MI4_GRPID 0x100 10690Sstevel@tonic-gate #define MI4_SHUTDOWN 0x200 10700Sstevel@tonic-gate #define MI4_LINK 0x400 10710Sstevel@tonic-gate #define MI4_SYMLINK 0x800 10725302Sth199096 #define MI4_EPHEMERAL_RECURSED 0x1000 10730Sstevel@tonic-gate #define MI4_ACL 0x2000 10745302Sth199096 /* MI4_MIRRORMOUNT is also defined in nfsstat.c */ 10755302Sth199096 #define MI4_MIRRORMOUNT 0x4000 10760Sstevel@tonic-gate /* 0x8000 is available */ 10770Sstevel@tonic-gate /* 0x10000 is available */ 10780Sstevel@tonic-gate #define MI4_NOPRINT 0x20000 10790Sstevel@tonic-gate #define MI4_DIRECTIO 0x40000 10800Sstevel@tonic-gate /* 0x80000 is available */ 10810Sstevel@tonic-gate #define MI4_RECOV_ACTIV 0x100000 10820Sstevel@tonic-gate #define MI4_REMOVE_ON_LAST_CLOSE 0x200000 10830Sstevel@tonic-gate #define MI4_RECOV_FAIL 0x400000 10840Sstevel@tonic-gate #define MI4_PUBLIC 0x800000 10850Sstevel@tonic-gate #define MI4_MOUNTING 0x1000000 10860Sstevel@tonic-gate #define MI4_POSIX_LOCK 0x2000000 10870Sstevel@tonic-gate #define MI4_LOCK_DEBUG 0x4000000 10880Sstevel@tonic-gate #define MI4_DEAD 0x8000000 10890Sstevel@tonic-gate #define MI4_INACTIVE_IDLE 0x10000000 10900Sstevel@tonic-gate #define MI4_BADOWNER_DEBUG 0x20000000 10910Sstevel@tonic-gate #define MI4_ASYNC_MGR_STOP 0x40000000 10920Sstevel@tonic-gate #define MI4_TIMEDOUT 0x80000000 10930Sstevel@tonic-gate 10945302Sth199096 /* 10955302Sth199096 * Note that when we add referrals, then MI4_EPHEMERAL 10965302Sth199096 * will be MI4_MIRRORMOUNT | MI4_REFERRAL. 10975302Sth199096 */ 10985302Sth199096 #define MI4_EPHEMERAL MI4_MIRRORMOUNT 10995302Sth199096 11000Sstevel@tonic-gate #define INTR4(vp) (VTOMI4(vp)->mi_flags & MI4_INT) 11010Sstevel@tonic-gate 11020Sstevel@tonic-gate #define FAILOVER_MOUNT4(mi) (mi->mi_servers->sv_next) 11030Sstevel@tonic-gate 11040Sstevel@tonic-gate /* 11050Sstevel@tonic-gate * Recovery flags. 11060Sstevel@tonic-gate * 11070Sstevel@tonic-gate * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag 11080Sstevel@tonic-gate * that's important), but some flag is needed to indicate that recovery is 11090Sstevel@tonic-gate * going on for the filesystem. 11100Sstevel@tonic-gate */ 11110Sstevel@tonic-gate #define MI4R_NEED_CLIENTID 0x1 11120Sstevel@tonic-gate #define MI4R_REOPEN_FILES 0x2 11130Sstevel@tonic-gate #define MI4R_NEED_SECINFO 0x4 11140Sstevel@tonic-gate #define MI4R_NEED_NEW_SERVER 0x8 11150Sstevel@tonic-gate #define MI4R_REMAP_FILES 0x10 11160Sstevel@tonic-gate #define MI4R_SRV_REBOOT 0x20 /* server has rebooted */ 11170Sstevel@tonic-gate #define MI4R_LOST_STATE 0x40 11180Sstevel@tonic-gate #define MI4R_BAD_SEQID 0x80 11190Sstevel@tonic-gate 11201705Sjwahlig #define MI4_HOLD(mi) { \ 11211705Sjwahlig mi_hold(mi); \ 11221705Sjwahlig } 11231705Sjwahlig 11241705Sjwahlig #define MI4_RELE(mi) { \ 11251705Sjwahlig mi_rele(mi); \ 11261705Sjwahlig } 11271705Sjwahlig 11280Sstevel@tonic-gate /* 11290Sstevel@tonic-gate * vfs pointer to mount info 11300Sstevel@tonic-gate */ 11310Sstevel@tonic-gate #define VFTOMI4(vfsp) ((mntinfo4_t *)((vfsp)->vfs_data)) 11320Sstevel@tonic-gate 11330Sstevel@tonic-gate /* 11340Sstevel@tonic-gate * vnode pointer to mount info 11350Sstevel@tonic-gate */ 11360Sstevel@tonic-gate #define VTOMI4(vp) ((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data)) 11370Sstevel@tonic-gate 11380Sstevel@tonic-gate /* 11390Sstevel@tonic-gate * Lease Management 11400Sstevel@tonic-gate * 11410Sstevel@tonic-gate * lease_valid is initially set to NFS4_LEASE_NOT_STARTED. This is when the 11420Sstevel@tonic-gate * nfs4_server is first created. lease_valid is then set to 11430Sstevel@tonic-gate * NFS4_LEASE_UNITIALIZED when the renew thread is started. The extra state of 11440Sstevel@tonic-gate * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread 11450Sstevel@tonic-gate * already exists when we do SETCLIENTID). lease_valid is then set to 11460Sstevel@tonic-gate * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating 11470Sstevel@tonic-gate * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as 11480Sstevel@tonic-gate * the lease is renewed. It is set to NFS4_LEASE_INVALID when the lease 11490Sstevel@tonic-gate * expires. Client recovery is needed to set the lease back to 11500Sstevel@tonic-gate * NFS4_LEASE_VALID from NFS4_LEASE_INVALID. 11510Sstevel@tonic-gate * 11520Sstevel@tonic-gate * The s_cred is the credential used to mount the first file system for this 11530Sstevel@tonic-gate * server. It used as the credential for the renew thread's calls to the 11540Sstevel@tonic-gate * server. 11550Sstevel@tonic-gate * 11560Sstevel@tonic-gate * The renew thread waits on the condition variable cv_thread_exit. If the cv 11570Sstevel@tonic-gate * is signalled, then the thread knows it must check s_thread_exit to see if 11580Sstevel@tonic-gate * it should exit. The cv is signaled when the last file system is unmounted 11590Sstevel@tonic-gate * from a particular server. s_thread_exit is set to 0 upon thread startup, 11600Sstevel@tonic-gate * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby 11610Sstevel@tonic-gate * telling the thread to exit. s_thread_exit is needed to avoid spurious 11620Sstevel@tonic-gate * wakeups. 11630Sstevel@tonic-gate * 11640Sstevel@tonic-gate * state_ref_count is incremented every time a new file is opened and 11650Sstevel@tonic-gate * decremented every time a file is closed otw. This keeps track of whether 11660Sstevel@tonic-gate * the nfs4_server has state associated with it or not. 11670Sstevel@tonic-gate * 11680Sstevel@tonic-gate * s_refcnt is the reference count for storage management of the struct 11690Sstevel@tonic-gate * itself. 11700Sstevel@tonic-gate * 11710Sstevel@tonic-gate * mntinfo4_list points to the doubly linked list of mntinfo4s that share 11720Sstevel@tonic-gate * this nfs4_server (ie: <clientid, saddr> pair) in the current zone. This is 11730Sstevel@tonic-gate * needed for a nfs4_server to get a mntinfo4 for use in rfs4call. 11740Sstevel@tonic-gate * 11750Sstevel@tonic-gate * s_recovlock is used to synchronize recovery operations. The thread 11760Sstevel@tonic-gate * that is recovering the client must acquire it as a writer. If the 11770Sstevel@tonic-gate * thread is using the clientid (including recovery operations on other 11780Sstevel@tonic-gate * state), acquire it as a reader. 11790Sstevel@tonic-gate * 11800Sstevel@tonic-gate * The 's_otw_call_count' keeps track of the number of outstanding over the 11810Sstevel@tonic-gate * wire requests for this structure. The struct will not go away as long 11820Sstevel@tonic-gate * as this is non-zero (or s_refcnt is non-zero). 11830Sstevel@tonic-gate * 11840Sstevel@tonic-gate * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count' 11850Sstevel@tonic-gate * variable to let the renew thread when an outstanding otw request has 11860Sstevel@tonic-gate * finished. 11870Sstevel@tonic-gate * 11880Sstevel@tonic-gate * 'zoneid' and 'zone_globals' are set at creation of this structure 11890Sstevel@tonic-gate * and are read-only after that; no lock is required to read them. 11900Sstevel@tonic-gate * 11910Sstevel@tonic-gate * s_lock protects: everything except cv_thread_exit and s_recovlock. 11920Sstevel@tonic-gate * 11930Sstevel@tonic-gate * s_program is used as the index into the nfs4_callback_globals's 11940Sstevel@tonic-gate * nfs4prog2server table. When a callback request comes in, we can 11950Sstevel@tonic-gate * use that request's program number (minus NFS4_CALLBACK) as an index 11960Sstevel@tonic-gate * into the nfs4prog2server. That entry will hold the nfs4_server_t ptr. 11970Sstevel@tonic-gate * We can then access that nfs4_server_t and its 's_deleg_list' (its list of 11980Sstevel@tonic-gate * delegated rnode4_ts). 11990Sstevel@tonic-gate * 12000Sstevel@tonic-gate * Lock order: 12010Sstevel@tonic-gate * nfs4_server::s_lock > mntinfo4::mi_lock 12020Sstevel@tonic-gate * nfs_rtable4_lock > s_lock 12030Sstevel@tonic-gate * nfs4_server_lst_lock > s_lock 12040Sstevel@tonic-gate * s_recovlock > s_lock 12050Sstevel@tonic-gate */ 12060Sstevel@tonic-gate struct nfs4_callback_globals; 12070Sstevel@tonic-gate 12080Sstevel@tonic-gate typedef struct nfs4_server { 12090Sstevel@tonic-gate struct nfs4_server *forw; 12100Sstevel@tonic-gate struct nfs4_server *back; 12110Sstevel@tonic-gate struct netbuf saddr; 12120Sstevel@tonic-gate uint_t s_flags; /* see below */ 12130Sstevel@tonic-gate uint_t s_refcnt; 12140Sstevel@tonic-gate clientid4 clientid; /* what we get from server */ 12150Sstevel@tonic-gate nfs_client_id4 clidtosend; /* what we send to server */ 12160Sstevel@tonic-gate mntinfo4_t *mntinfo4_list; 12170Sstevel@tonic-gate int lease_valid; 12180Sstevel@tonic-gate time_t s_lease_time; 12190Sstevel@tonic-gate time_t last_renewal_time; 12200Sstevel@tonic-gate timespec_t propagation_delay; 12210Sstevel@tonic-gate cred_t *s_cred; 12220Sstevel@tonic-gate kcondvar_t cv_thread_exit; 12230Sstevel@tonic-gate int s_thread_exit; 12240Sstevel@tonic-gate int state_ref_count; 12250Sstevel@tonic-gate int s_otw_call_count; 12260Sstevel@tonic-gate kcondvar_t s_cv_otw_count; 12271649Sdm120769 kcondvar_t s_clientid_pend; 12280Sstevel@tonic-gate kmutex_t s_lock; 12290Sstevel@tonic-gate list_t s_deleg_list; 12300Sstevel@tonic-gate rpcprog_t s_program; 12310Sstevel@tonic-gate nfs_rwlock_t s_recovlock; 12320Sstevel@tonic-gate kcondvar_t wait_cb_null; /* used to wait for CB_NULL */ 12330Sstevel@tonic-gate zoneid_t zoneid; /* zone using this nfs4_server_t */ 12340Sstevel@tonic-gate struct nfs4_callback_globals *zone_globals; /* globals */ 12350Sstevel@tonic-gate } nfs4_server_t; 12360Sstevel@tonic-gate 12370Sstevel@tonic-gate /* nfs4_server flags */ 12380Sstevel@tonic-gate #define N4S_CLIENTID_SET 1 /* server has our clientid */ 12391649Sdm120769 #define N4S_CLIENTID_PEND 0x2 /* server doesn't have clientid */ 12400Sstevel@tonic-gate #define N4S_CB_PINGED 0x4 /* server has sent us a CB_NULL */ 12410Sstevel@tonic-gate #define N4S_CB_WAITER 0x8 /* is/has wait{ing/ed} for cb_null */ 12421849Sdm120769 #define N4S_INSERTED 0x10 /* list has reference for server */ 12431849Sdm120769 #define N4S_BADOWNER_DEBUG 0x20 /* bad owner err msg per client */ 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate #define N4S_CB_PAUSE_TIME 10000 /* Amount of time to pause (10ms) */ 12460Sstevel@tonic-gate 12470Sstevel@tonic-gate struct lease_time_arg { 12480Sstevel@tonic-gate time_t lease_time; 12490Sstevel@tonic-gate }; 12500Sstevel@tonic-gate 12510Sstevel@tonic-gate enum nfs4_delegreturn_policy { 12520Sstevel@tonic-gate IMMEDIATE, 12530Sstevel@tonic-gate FIRSTCLOSE, 12540Sstevel@tonic-gate LASTCLOSE, 12550Sstevel@tonic-gate INACTIVE 12560Sstevel@tonic-gate }; 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate /* 12590Sstevel@tonic-gate * Operation hints for the recovery framework (mostly). 12600Sstevel@tonic-gate * 12610Sstevel@tonic-gate * EXCEPTIONS: 12620Sstevel@tonic-gate * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR 12630Sstevel@tonic-gate * These hints exist to allow user visit/readdir a R4SRVSTUB dir. 12640Sstevel@tonic-gate * (dir represents the root of a server fs that has not yet been 12650Sstevel@tonic-gate * mounted at client) 12660Sstevel@tonic-gate */ 12670Sstevel@tonic-gate typedef enum { 12680Sstevel@tonic-gate OH_OTHER, 12690Sstevel@tonic-gate OH_READ, 12700Sstevel@tonic-gate OH_WRITE, 12710Sstevel@tonic-gate OH_COMMIT, 12720Sstevel@tonic-gate OH_VFH_RENAME, 12730Sstevel@tonic-gate OH_MOUNT, 12740Sstevel@tonic-gate OH_CLOSE, 12750Sstevel@tonic-gate OH_LOCKU, 12760Sstevel@tonic-gate OH_DELEGRETURN, 12770Sstevel@tonic-gate OH_ACCESS, 12780Sstevel@tonic-gate OH_GETACL, 12790Sstevel@tonic-gate OH_GETATTR, 12800Sstevel@tonic-gate OH_LOOKUP, 12810Sstevel@tonic-gate OH_READDIR 12820Sstevel@tonic-gate } nfs4_op_hint_t; 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate /* 12855302Sth199096 * This data structure is used to track ephemeral mounts for both 12865302Sth199096 * mirror mounts and referrals. 12875302Sth199096 * 12885302Sth199096 * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral 12895302Sth199096 * pointing at it. So we don't need two backpointers to walk 12905302Sth199096 * back up the tree. 12915302Sth199096 * 12925302Sth199096 * An ephemeral tree is pointed to by an enclosing non-ephemeral 12935302Sth199096 * mntinfo4. The root is also pointed to by its ephemeral 12945302Sth199096 * mntinfo4. ne_child will get us back to it, while ne_prior 12955302Sth199096 * will get us back to the non-ephemeral mntinfo4. This is an 12965302Sth199096 * edge case we will need to be wary of when walking back up the 12975302Sth199096 * tree. 12985302Sth199096 * 12995302Sth199096 * The way we handle this edge case is to have ne_prior be NULL 13005302Sth199096 * for the root nfs4_ephemeral node. 13015302Sth199096 */ 13025302Sth199096 typedef struct nfs4_ephemeral { 13035302Sth199096 mntinfo4_t *ne_mount; /* who encloses us */ 13045302Sth199096 struct nfs4_ephemeral *ne_child; /* first child node */ 13055302Sth199096 struct nfs4_ephemeral *ne_peer; /* next sibling */ 13065302Sth199096 struct nfs4_ephemeral *ne_prior; /* who points at us */ 13075302Sth199096 time_t ne_ref_time; /* time last referenced */ 13085302Sth199096 uint_t ne_mount_to; /* timeout at */ 13095302Sth199096 int ne_state; /* used to traverse */ 13105302Sth199096 } nfs4_ephemeral_t; 13115302Sth199096 13125302Sth199096 /* 13135302Sth199096 * State for the node (set in ne_state): 13145302Sth199096 */ 13155302Sth199096 #define NFS4_EPHEMERAL_OK 0x0 13165302Sth199096 #define NFS4_EPHEMERAL_VISIT_CHILD 0x1 13175302Sth199096 #define NFS4_EPHEMERAL_VISIT_SIBLING 0x2 13185302Sth199096 #define NFS4_EPHEMERAL_PROCESS_ME 0x4 13195302Sth199096 #define NFS4_EPHEMERAL_CHILD_ERROR 0x8 13205302Sth199096 #define NFS4_EPHEMERAL_PEER_ERROR 0x10 13215302Sth199096 13225302Sth199096 /* 13235302Sth199096 * These are the locks used in processing ephemeral data: 13245302Sth199096 * 13255302Sth199096 * mi->mi_lock 13265302Sth199096 * 13275302Sth199096 * net->net_tree_lock 13285302Sth199096 * This lock is used to gate all tree operations. 13295302Sth199096 * If it is held, then no other process may 13305302Sth199096 * traverse the tree. This allows us to not 13315302Sth199096 * throw a hold on each vfs_t in the tree. 13325302Sth199096 * Can be held for a "long" time. 13335302Sth199096 * 13345302Sth199096 * net->net_cnt_lock 13355302Sth199096 * Used to protect refcnt and status. 13365302Sth199096 * Must be held for a really short time. 13375302Sth199096 * 13385302Sth199096 * nfs4_ephemeral_thread_lock 13395302Sth199096 * Is only held to create the harvester for the zone. 13405302Sth199096 * There is no ordering imposed on it. 13415302Sth199096 * Held for a really short time. 13425302Sth199096 * 13435302Sth199096 * Some further detail on the interactions: 13445302Sth199096 * 13455302Sth199096 * net_tree_lock controls access to net_root. Access needs to first be 13465302Sth199096 * attempted in a non-blocking check. 13475302Sth199096 * 13485302Sth199096 * net_cnt_lock controls access to net_refcnt and net_status. It must only be 13495302Sth199096 * held for very short periods of time, unless the refcnt is 0 and the status 13505302Sth199096 * is INVALID. 13515302Sth199096 * 13525302Sth199096 * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock 13535302Sth199096 * to bump the net_refcnt. It then releases it and does the action specific 13545302Sth199096 * algorithm to get the net_tree_lock. Once it has that, then it is okay to 13555302Sth199096 * grab the net_cnt_lock and change the status. The status can only be 13565302Sth199096 * changed if the caller has the net_tree_lock held as well. 13575302Sth199096 * 13586218Sth199096 * Note that the initial grab of net_cnt_lock must occur whilst 13596218Sth199096 * mi_lock is being held. This prevents stale data in that if the 13606218Sth199096 * ephemeral tree is non-NULL, then the harvester can not remove 13616218Sth199096 * the tree from the mntinfo node until it grabs that lock. I.e., 13626218Sth199096 * we get the pointer to the tree and hold the lock atomically 13636218Sth199096 * with respect to being in mi_lock. 13646218Sth199096 * 13655302Sth199096 * When a caller is done with net_tree_lock, it can decrement the net_refcnt 13665302Sth199096 * either before it releases net_tree_lock or after. 13675302Sth199096 * 13685302Sth199096 * In either event, to decrement net_refcnt, it must hold net_cnt_lock. 13695302Sth199096 * 13705302Sth199096 * Note that the overall locking scheme for the nodes is to control access 13715302Sth199096 * via the tree. The current scheme could easily be extended such that 13725302Sth199096 * the enclosing root referenced a "forest" of trees. The underlying trees 13735302Sth199096 * would be autonomous with respect to locks. 13745302Sth199096 * 13755302Sth199096 * Note that net_next is controlled by external locks 13765302Sth199096 * particular to the data structure that the tree is being added to. 13775302Sth199096 */ 13785302Sth199096 typedef struct nfs4_ephemeral_tree { 13795302Sth199096 mntinfo4_t *net_mount; 13805302Sth199096 nfs4_ephemeral_t *net_root; 13815302Sth199096 struct nfs4_ephemeral_tree *net_next; 13825302Sth199096 kmutex_t net_tree_lock; 13835302Sth199096 kmutex_t net_cnt_lock; 13845302Sth199096 uint_t net_status; 13855302Sth199096 uint_t net_refcnt; 13865302Sth199096 } nfs4_ephemeral_tree_t; 13875302Sth199096 13885302Sth199096 /* 13895302Sth199096 * State for the tree (set in net_status): 13905302Sth199096 */ 13915302Sth199096 #define NFS4_EPHEMERAL_TREE_OK 0x0 13925302Sth199096 #define NFS4_EPHEMERAL_TREE_BUILDING 0x1 13935302Sth199096 #define NFS4_EPHEMERAL_TREE_DEROOTING 0x2 13945302Sth199096 #define NFS4_EPHEMERAL_TREE_INVALID 0x4 13955302Sth199096 #define NFS4_EPHEMERAL_TREE_MOUNTING 0x8 13965302Sth199096 #define NFS4_EPHEMERAL_TREE_UMOUNTING 0x10 13975302Sth199096 #define NFS4_EPHEMERAL_TREE_LOCKED 0x20 13985302Sth199096 13997318SThomas.Haynes@Sun.COM #define NFS4_EPHEMERAL_TREE_PROCESSING (NFS4_EPHEMERAL_TREE_DEROOTING | \ 14007318SThomas.Haynes@Sun.COM NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \ 14017318SThomas.Haynes@Sun.COM NFS4_EPHEMERAL_TREE_LOCKED) 14027318SThomas.Haynes@Sun.COM 14035302Sth199096 /* 14040Sstevel@tonic-gate * This macro evaluates to non-zero if the given op releases state at the 14050Sstevel@tonic-gate * server. 14060Sstevel@tonic-gate */ 14070Sstevel@tonic-gate #define OH_IS_STATE_RELE(op) ((op) == OH_CLOSE || (op) == OH_LOCKU || \ 14080Sstevel@tonic-gate (op) == OH_DELEGRETURN) 14090Sstevel@tonic-gate 14100Sstevel@tonic-gate #ifdef _KERNEL 14110Sstevel@tonic-gate 14120Sstevel@tonic-gate extern void nfs4_async_manager(struct vfs *); 14130Sstevel@tonic-gate extern void nfs4_async_manager_stop(struct vfs *); 14140Sstevel@tonic-gate extern void nfs4_async_stop(struct vfs *); 14150Sstevel@tonic-gate extern int nfs4_async_stop_sig(struct vfs *); 14160Sstevel@tonic-gate extern int nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t, 14170Sstevel@tonic-gate struct seg *, cred_t *, 14180Sstevel@tonic-gate void (*)(vnode_t *, u_offset_t, 14190Sstevel@tonic-gate caddr_t, struct seg *, cred_t *)); 14200Sstevel@tonic-gate extern int nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t, 14210Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 14220Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 14230Sstevel@tonic-gate extern int nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t, 14240Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 14250Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 14260Sstevel@tonic-gate extern void nfs4_async_commit(vnode_t *, page_t *, offset3, count3, 14270Sstevel@tonic-gate cred_t *, void (*)(vnode_t *, page_t *, 14280Sstevel@tonic-gate offset3, count3, cred_t *)); 14290Sstevel@tonic-gate extern void nfs4_async_inactive(vnode_t *, cred_t *); 14300Sstevel@tonic-gate extern void nfs4_inactive_thread(mntinfo4_t *mi); 14310Sstevel@tonic-gate extern void nfs4_inactive_otw(vnode_t *, cred_t *); 14320Sstevel@tonic-gate extern int nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *); 14330Sstevel@tonic-gate 14340Sstevel@tonic-gate extern int nfs4_setopts(vnode_t *, model_t, struct nfs_args *); 14350Sstevel@tonic-gate extern void nfs4_mnt_kstat_init(struct vfs *); 14360Sstevel@tonic-gate 14370Sstevel@tonic-gate extern void rfs4call(struct mntinfo4 *, struct COMPOUND4args_clnt *, 14380Sstevel@tonic-gate struct COMPOUND4res_clnt *, cred_t *, int *, int, 14390Sstevel@tonic-gate nfs4_error_t *); 14400Sstevel@tonic-gate extern void nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *); 14410Sstevel@tonic-gate extern int nfs4_attr_otw(vnode_t *, nfs4_tag_type_t, 14420Sstevel@tonic-gate nfs4_ga_res_t *, bitmap4, cred_t *); 14430Sstevel@tonic-gate 14440Sstevel@tonic-gate extern void nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t); 14450Sstevel@tonic-gate extern void nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *, 14460Sstevel@tonic-gate hrtime_t, cred_t *, int, 14470Sstevel@tonic-gate change_info4 *); 14480Sstevel@tonic-gate extern void nfs4_purge_rddir_cache(vnode_t *); 14490Sstevel@tonic-gate extern void nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *); 14500Sstevel@tonic-gate extern void nfs4_purge_caches(vnode_t *, int, cred_t *, int); 14510Sstevel@tonic-gate extern void nfs4_purge_stale_fh(int, vnode_t *, cred_t *); 14520Sstevel@tonic-gate 14530Sstevel@tonic-gate extern void nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *); 14540Sstevel@tonic-gate extern void nfs4_update_paths(vnode_t *, char *, vnode_t *, char *, 14550Sstevel@tonic-gate vnode_t *); 14560Sstevel@tonic-gate 14570Sstevel@tonic-gate extern void nfs4args_lookup_free(nfs_argop4 *, int); 14580Sstevel@tonic-gate extern void nfs4args_copen_free(OPEN4cargs *); 14590Sstevel@tonic-gate 14600Sstevel@tonic-gate extern void nfs4_printfhandle(nfs4_fhandle_t *); 14610Sstevel@tonic-gate 14620Sstevel@tonic-gate extern void nfs_free_mi4(mntinfo4_t *); 14630Sstevel@tonic-gate extern void sv4_free(servinfo4_t *); 14640Sstevel@tonic-gate extern void nfs4_mi_zonelist_add(mntinfo4_t *); 14651705Sjwahlig extern int nfs4_mi_zonelist_remove(mntinfo4_t *); 14660Sstevel@tonic-gate extern int nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *); 14670Sstevel@tonic-gate extern void nfs4_secinfo_init(void); 14680Sstevel@tonic-gate extern void nfs4_secinfo_fini(void); 14690Sstevel@tonic-gate extern int nfs4_secinfo_path(mntinfo4_t *, cred_t *, int); 14700Sstevel@tonic-gate extern int nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *); 14710Sstevel@tonic-gate extern void secinfo_free(sv_secinfo_t *); 14720Sstevel@tonic-gate extern void save_mnt_secinfo(servinfo4_t *); 14730Sstevel@tonic-gate extern void check_mnt_secinfo(servinfo4_t *, vnode_t *); 14740Sstevel@tonic-gate extern int vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int, 14750Sstevel@tonic-gate enum nfs_opnum4, bitmap4 supp_mask); 14760Sstevel@tonic-gate extern int nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *, 14770Sstevel@tonic-gate int, cred_t *); 14780Sstevel@tonic-gate extern void nfs4_write_error(vnode_t *, int, cred_t *); 14790Sstevel@tonic-gate extern void nfs4_lockcompletion(vnode_t *, int); 14800Sstevel@tonic-gate extern bool_t nfs4_map_lost_lock_conflict(vnode_t *); 14810Sstevel@tonic-gate extern int vtodv(vnode_t *, vnode_t **, cred_t *, bool_t); 14820Sstevel@tonic-gate extern void nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *, 14830Sstevel@tonic-gate bool_t, bool_t *, nfs4_open_owner_t *, bool_t, 14840Sstevel@tonic-gate nfs4_error_t *, int *); 14850Sstevel@tonic-gate extern void nfs4_error_zinit(nfs4_error_t *); 14860Sstevel@tonic-gate extern void nfs4_error_init(nfs4_error_t *, int); 14875302Sth199096 extern void nfs4_free_args(struct nfs_args *); 14881705Sjwahlig 14891705Sjwahlig extern void mi_hold(mntinfo4_t *); 14901705Sjwahlig extern void mi_rele(mntinfo4_t *); 14911705Sjwahlig 14925302Sth199096 extern sec_data_t *copy_sec_data(sec_data_t *); 14935302Sth199096 extern gss_clntdata_t *copy_sec_data_gss(gss_clntdata_t *); 14945302Sth199096 14950Sstevel@tonic-gate #ifdef DEBUG 14960Sstevel@tonic-gate extern int nfs4_consistent_type(vnode_t *); 14970Sstevel@tonic-gate #endif 14980Sstevel@tonic-gate 14990Sstevel@tonic-gate extern void nfs4_init_dot_entries(void); 15000Sstevel@tonic-gate extern void nfs4_destroy_dot_entries(void); 15010Sstevel@tonic-gate extern struct nfs4_callback_globals *nfs4_get_callback_globals(void); 15020Sstevel@tonic-gate 15030Sstevel@tonic-gate extern struct nfs4_server nfs4_server_lst; 15040Sstevel@tonic-gate 15050Sstevel@tonic-gate extern clock_t nfs_write_error_interval; 15060Sstevel@tonic-gate 15070Sstevel@tonic-gate #endif /* _KERNEL */ 15080Sstevel@tonic-gate 15090Sstevel@tonic-gate /* 15100Sstevel@tonic-gate * Flags for nfs4getfh_otw. 15110Sstevel@tonic-gate */ 15120Sstevel@tonic-gate 15130Sstevel@tonic-gate #define NFS4_GETFH_PUBLIC 0x01 15140Sstevel@tonic-gate #define NFS4_GETFH_NEEDSOP 0x02 15150Sstevel@tonic-gate 15160Sstevel@tonic-gate /* 15170Sstevel@tonic-gate * Found through rnodes. 15180Sstevel@tonic-gate * 15190Sstevel@tonic-gate * The os_open_ref_count keeps track the number of open file descriptor 15200Sstevel@tonic-gate * refernces on this data structure. It will be bumped for any successful 15210Sstevel@tonic-gate * OTW OPEN call and any OPEN call that determines the OTW call is not 15220Sstevel@tonic-gate * necessary and the open stream hasn't just been created (see 15230Sstevel@tonic-gate * nfs4_is_otw_open_necessary). 15240Sstevel@tonic-gate * 15250Sstevel@tonic-gate * os_mapcnt is a count of the number of mmapped pages for a particular 15260Sstevel@tonic-gate * open stream; this in conjunction w/ os_open_ref_count is used to 15270Sstevel@tonic-gate * determine when to do a close to the server. This is necessary because 15280Sstevel@tonic-gate * of the semantics of doing open, mmap, close; the OTW close must be wait 15290Sstevel@tonic-gate * until all open and mmap references have vanished. 15300Sstevel@tonic-gate * 15310Sstevel@tonic-gate * 'os_valid' tells us whether this structure is about to be freed or not, 15320Sstevel@tonic-gate * if it is then don't return it in find_open_stream(). 15330Sstevel@tonic-gate * 15340Sstevel@tonic-gate * 'os_final_close' is set when a CLOSE OTW was attempted. This is needed 15350Sstevel@tonic-gate * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE 15360Sstevel@tonic-gate * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE. It 15370Sstevel@tonic-gate * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE 15380Sstevel@tonic-gate * that tried to close OTW but failed, and left the state cleanup to 15390Sstevel@tonic-gate * nfs4_inactive/CLOSE_FORCE. 15400Sstevel@tonic-gate * 15410Sstevel@tonic-gate * 'os_force_close' is used to let us know if an intervening thread came 15420Sstevel@tonic-gate * and reopened the open stream after we decided to issue a CLOSE_FORCE, 15430Sstevel@tonic-gate * but before we could actually process the CLOSE_FORCE. 15440Sstevel@tonic-gate * 15450Sstevel@tonic-gate * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the 15460Sstevel@tonic-gate * lost state queue. 15470Sstevel@tonic-gate * 15480Sstevel@tonic-gate * 'open_stateid' is set the last open stateid returned by the server unless 15490Sstevel@tonic-gate * 'os_delegation' is 1, in which case 'open_stateid' refers to the 15500Sstevel@tonic-gate * delegation stateid returned by the server. This is used in cases where the 15510Sstevel@tonic-gate * client tries to OPEN a file but already has a suitable delegation, so we 15520Sstevel@tonic-gate * just stick the delegation stateid in the open stream. 15530Sstevel@tonic-gate * 15540Sstevel@tonic-gate * os_dc_openacc are open access bits which have been granted to the 15550Sstevel@tonic-gate * open stream by virtue of a delegation, but which have not been seen 15560Sstevel@tonic-gate * by the server. This applies even if the open stream does not have 15570Sstevel@tonic-gate * os_delegation set. These bits are used when setting file locks to 15580Sstevel@tonic-gate * determine whether an open with CLAIM_DELEGATE_CUR needs to be done 15590Sstevel@tonic-gate * before the lock request can be sent to the server. See 15600Sstevel@tonic-gate * nfs4frlock_check_deleg(). 15610Sstevel@tonic-gate * 15620Sstevel@tonic-gate * 'os_mmap_read/write' keep track of the read and write access our memory 15630Sstevel@tonic-gate * maps require. We need to keep track of this so we can provide the proper 15640Sstevel@tonic-gate * access bits in the open/mmap/close/reboot/reopen case. 15650Sstevel@tonic-gate * 15660Sstevel@tonic-gate * 'os_failed_reopen' tells us that we failed to successfully reopen this 15670Sstevel@tonic-gate * open stream; therefore, we should not use this open stateid as it is 15680Sstevel@tonic-gate * not valid anymore. This flag is also used to indicate an unsuccessful 15690Sstevel@tonic-gate * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR. 15700Sstevel@tonic-gate * 15710Sstevel@tonic-gate * If 'os_orig_oo_name' is different than os_open_owner's oo_name 15720Sstevel@tonic-gate * then this tells us that this open stream's open owner used a 15730Sstevel@tonic-gate * bad seqid (that is, got NFS4ERR_BAD_SEQID). If different, this open 15740Sstevel@tonic-gate * stream will no longer be used for future OTW state releasing calls. 15750Sstevel@tonic-gate * 15760Sstevel@tonic-gate * Lock ordering: 15770Sstevel@tonic-gate * rnode4_t::r_os_lock > os_sync_lock 15780Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statelock 15790Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statev4_lock 15800Sstevel@tonic-gate * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call) 15810Sstevel@tonic-gate * 15820Sstevel@tonic-gate * The 'os_sync_lock' protects: 15830Sstevel@tonic-gate * open_stateid 15840Sstevel@tonic-gate * os_dc_openacc 15850Sstevel@tonic-gate * os_delegation 15860Sstevel@tonic-gate * os_failed_reopen 15870Sstevel@tonic-gate * os_final_close 15880Sstevel@tonic-gate * os_force_close 15890Sstevel@tonic-gate * os_mapcnt 15900Sstevel@tonic-gate * os_mmap_read 15910Sstevel@tonic-gate * os_mmap_write 15920Sstevel@tonic-gate * os_open_ref_count 15930Sstevel@tonic-gate * os_pending_close 15940Sstevel@tonic-gate * os_share_acc_read 15950Sstevel@tonic-gate * os_share_acc_write 15960Sstevel@tonic-gate * os_share_deny_none 15970Sstevel@tonic-gate * os_share_deny_read 15980Sstevel@tonic-gate * os_share_deny_write 15990Sstevel@tonic-gate * os_ref_count 16000Sstevel@tonic-gate * os_valid 16010Sstevel@tonic-gate * 16020Sstevel@tonic-gate * The rnode4_t::r_os_lock protects: 16030Sstevel@tonic-gate * os_node 16040Sstevel@tonic-gate * 16050Sstevel@tonic-gate * These fields are set at creation time and 16060Sstevel@tonic-gate * read only after that: 16070Sstevel@tonic-gate * os_open_owner 16080Sstevel@tonic-gate * os_orig_oo_name 16090Sstevel@tonic-gate */ 16100Sstevel@tonic-gate typedef struct nfs4_open_stream { 16110Sstevel@tonic-gate uint64_t os_share_acc_read; 16120Sstevel@tonic-gate uint64_t os_share_acc_write; 16130Sstevel@tonic-gate uint64_t os_mmap_read; 16140Sstevel@tonic-gate uint64_t os_mmap_write; 16150Sstevel@tonic-gate uint32_t os_share_deny_none; 16160Sstevel@tonic-gate uint32_t os_share_deny_read; 16170Sstevel@tonic-gate uint32_t os_share_deny_write; 16180Sstevel@tonic-gate stateid4 open_stateid; 16190Sstevel@tonic-gate int os_dc_openacc; 16200Sstevel@tonic-gate int os_ref_count; 16210Sstevel@tonic-gate unsigned os_valid:1; 16220Sstevel@tonic-gate unsigned os_delegation:1; 16230Sstevel@tonic-gate unsigned os_final_close:1; 16240Sstevel@tonic-gate unsigned os_pending_close:1; 16250Sstevel@tonic-gate unsigned os_failed_reopen:1; 16260Sstevel@tonic-gate unsigned os_force_close:1; 16270Sstevel@tonic-gate int os_open_ref_count; 16280Sstevel@tonic-gate long os_mapcnt; 16290Sstevel@tonic-gate list_node_t os_node; 16300Sstevel@tonic-gate struct nfs4_open_owner *os_open_owner; 16310Sstevel@tonic-gate uint64_t os_orig_oo_name; 16320Sstevel@tonic-gate kmutex_t os_sync_lock; 16330Sstevel@tonic-gate } nfs4_open_stream_t; 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate /* 16360Sstevel@tonic-gate * This structure describes the format of the lock_owner_name 16370Sstevel@tonic-gate * field of the lock owner. 16380Sstevel@tonic-gate */ 16390Sstevel@tonic-gate 16400Sstevel@tonic-gate typedef struct nfs4_lo_name { 16410Sstevel@tonic-gate uint64_t ln_seq_num; 16420Sstevel@tonic-gate pid_t ln_pid; 16430Sstevel@tonic-gate } nfs4_lo_name_t; 16440Sstevel@tonic-gate 16450Sstevel@tonic-gate /* 16460Sstevel@tonic-gate * Flags for lo_flags. 16470Sstevel@tonic-gate */ 16480Sstevel@tonic-gate #define NFS4_LOCK_SEQID_INUSE 0x1 16490Sstevel@tonic-gate #define NFS4_BAD_SEQID_LOCK 0x2 16500Sstevel@tonic-gate 16510Sstevel@tonic-gate /* 16520Sstevel@tonic-gate * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs 16530Sstevel@tonic-gate * off the rnode. If the links are NULL it means this object is not on the 16540Sstevel@tonic-gate * list. 16550Sstevel@tonic-gate * 16560Sstevel@tonic-gate * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and 16570Sstevel@tonic-gate * didn't get a response back. This is used to figure out if we have 16580Sstevel@tonic-gate * possible remote v4 locks, so that we can clean up at process exit. In 16590Sstevel@tonic-gate * theory, the client should be able to figure out if the server received 16600Sstevel@tonic-gate * the request (based on what seqid works), so maybe we can get rid of this 16610Sstevel@tonic-gate * flag someday. 16620Sstevel@tonic-gate * 16630Sstevel@tonic-gate * 'lo_ref_count' tells us how many processes/threads are using this data 16640Sstevel@tonic-gate * structure. The rnode's list accounts for one reference. 16650Sstevel@tonic-gate * 16660Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the 16670Sstevel@tonic-gate * data structure. It is then set to NFS4_PERM_CREATED when a lock request 16680Sstevel@tonic-gate * is successful using this lock owner structure. We need to keep 'temporary' 16690Sstevel@tonic-gate * lock owners around so we can properly keep the lock seqid synchronization 16700Sstevel@tonic-gate * when multiple processes/threads are trying to create the lock owner for the 16710Sstevel@tonic-gate * first time (especially with the DENIED error case). Once 16720Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change. 16730Sstevel@tonic-gate * 16740Sstevel@tonic-gate * 'lo_valid' tells us whether this structure is about to be freed or not, 16750Sstevel@tonic-gate * if it is then don't return it from find_lock_owner(). 16760Sstevel@tonic-gate * 16770Sstevel@tonic-gate * Retrieving and setting of 'lock_seqid' is protected by the 16780Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag. Waiters for NFS4_LOCK_SEQID_INUSE should 16790Sstevel@tonic-gate * use 'lo_cv_seqid_sync'. 16800Sstevel@tonic-gate * 16810Sstevel@tonic-gate * The setting of 'lock_stateid' is protected by the 16820Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'. The retrieving of the 16830Sstevel@tonic-gate * 'lock_stateid' is protected by 'lo_lock', with the additional 16840Sstevel@tonic-gate * requirement that the calling function can handle NFS4ERR_OLD_STATEID and 16850Sstevel@tonic-gate * NFS4ERR_BAD_STATEID as appropiate. 16860Sstevel@tonic-gate * 16870Sstevel@tonic-gate * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock 16880Sstevel@tonic-gate * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID). With this set, 16890Sstevel@tonic-gate * this lock owner will no longer be used for future OTW calls. Once set, 16900Sstevel@tonic-gate * it is never unset. 16910Sstevel@tonic-gate * 16920Sstevel@tonic-gate * Lock ordering: 16930Sstevel@tonic-gate * rnode4_t::r_statev4_lock > lo_lock 16940Sstevel@tonic-gate */ 16950Sstevel@tonic-gate typedef struct nfs4_lock_owner { 16960Sstevel@tonic-gate struct nfs4_lock_owner *lo_next_rnode; 16970Sstevel@tonic-gate struct nfs4_lock_owner *lo_prev_rnode; 16980Sstevel@tonic-gate int lo_pid; 16990Sstevel@tonic-gate stateid4 lock_stateid; 17000Sstevel@tonic-gate seqid4 lock_seqid; 17010Sstevel@tonic-gate /* 17020Sstevel@tonic-gate * Fix this to always be 12 bytes 17030Sstevel@tonic-gate */ 17040Sstevel@tonic-gate nfs4_lo_name_t lock_owner_name; 17050Sstevel@tonic-gate int lo_ref_count; 17060Sstevel@tonic-gate int lo_valid; 17070Sstevel@tonic-gate int lo_pending_rqsts; 17080Sstevel@tonic-gate int lo_just_created; 17090Sstevel@tonic-gate int lo_flags; 17100Sstevel@tonic-gate kcondvar_t lo_cv_seqid_sync; 17110Sstevel@tonic-gate kmutex_t lo_lock; 17120Sstevel@tonic-gate kthread_t *lo_seqid_holder; /* debugging aid */ 17130Sstevel@tonic-gate } nfs4_lock_owner_t; 17140Sstevel@tonic-gate 17150Sstevel@tonic-gate /* for nfs4_lock_owner_t lookups */ 17160Sstevel@tonic-gate typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t; 17170Sstevel@tonic-gate 17180Sstevel@tonic-gate /* Number of times to retry a call that fails with state independent error */ 17190Sstevel@tonic-gate #define NFS4_NUM_RECOV_RETRIES 3 17200Sstevel@tonic-gate 17210Sstevel@tonic-gate typedef enum { 17220Sstevel@tonic-gate NO_SID, 17230Sstevel@tonic-gate DEL_SID, 17240Sstevel@tonic-gate LOCK_SID, 17250Sstevel@tonic-gate OPEN_SID, 17260Sstevel@tonic-gate SPEC_SID 17270Sstevel@tonic-gate } nfs4_stateid_type_t; 17280Sstevel@tonic-gate 17290Sstevel@tonic-gate typedef struct nfs4_stateid_types { 17300Sstevel@tonic-gate stateid4 d_sid; 17310Sstevel@tonic-gate stateid4 l_sid; 17320Sstevel@tonic-gate stateid4 o_sid; 17330Sstevel@tonic-gate nfs4_stateid_type_t cur_sid_type; 17340Sstevel@tonic-gate } nfs4_stateid_types_t; 17350Sstevel@tonic-gate 17360Sstevel@tonic-gate /* 17370Sstevel@tonic-gate * Per-zone data for dealing with callbacks. Included here solely for the 17380Sstevel@tonic-gate * benefit of MDB. 17390Sstevel@tonic-gate */ 17400Sstevel@tonic-gate struct nfs4_callback_stats { 17410Sstevel@tonic-gate kstat_named_t delegations; 17420Sstevel@tonic-gate kstat_named_t cb_getattr; 17430Sstevel@tonic-gate kstat_named_t cb_recall; 17440Sstevel@tonic-gate kstat_named_t cb_null; 17450Sstevel@tonic-gate kstat_named_t cb_dispatch; 17460Sstevel@tonic-gate kstat_named_t delegaccept_r; 17470Sstevel@tonic-gate kstat_named_t delegaccept_rw; 17480Sstevel@tonic-gate kstat_named_t delegreturn; 17490Sstevel@tonic-gate kstat_named_t callbacks; 17500Sstevel@tonic-gate kstat_named_t claim_cur; 17510Sstevel@tonic-gate kstat_named_t claim_cur_ok; 17520Sstevel@tonic-gate kstat_named_t recall_trunc; 17530Sstevel@tonic-gate kstat_named_t recall_failed; 17540Sstevel@tonic-gate kstat_named_t return_limit_write; 17550Sstevel@tonic-gate kstat_named_t return_limit_addmap; 17560Sstevel@tonic-gate kstat_named_t deleg_recover; 17570Sstevel@tonic-gate kstat_named_t cb_illegal; 17580Sstevel@tonic-gate }; 17590Sstevel@tonic-gate 17600Sstevel@tonic-gate struct nfs4_callback_globals { 17610Sstevel@tonic-gate kmutex_t nfs4_cb_lock; 17620Sstevel@tonic-gate kmutex_t nfs4_dlist_lock; 17630Sstevel@tonic-gate int nfs4_program_hint; 17640Sstevel@tonic-gate /* this table maps the program number to the nfs4_server structure */ 17650Sstevel@tonic-gate struct nfs4_server **nfs4prog2server; 17660Sstevel@tonic-gate list_t nfs4_dlist; 17670Sstevel@tonic-gate list_t nfs4_cb_ports; 17680Sstevel@tonic-gate struct nfs4_callback_stats nfs4_callback_stats; 17690Sstevel@tonic-gate #ifdef DEBUG 17700Sstevel@tonic-gate int nfs4_dlistadd_c; 17710Sstevel@tonic-gate int nfs4_dlistclean_c; 17720Sstevel@tonic-gate #endif 17730Sstevel@tonic-gate }; 17740Sstevel@tonic-gate 17750Sstevel@tonic-gate typedef enum { 17760Sstevel@tonic-gate CLOSE_NORM, 17770Sstevel@tonic-gate CLOSE_DELMAP, 17780Sstevel@tonic-gate CLOSE_FORCE, 17790Sstevel@tonic-gate CLOSE_RESEND, 17800Sstevel@tonic-gate CLOSE_AFTER_RESEND 17810Sstevel@tonic-gate } nfs4_close_type_t; 17820Sstevel@tonic-gate 17830Sstevel@tonic-gate /* 17840Sstevel@tonic-gate * Structure to hold the bad seqid information that is passed 17850Sstevel@tonic-gate * to the recovery framework. 17860Sstevel@tonic-gate */ 17870Sstevel@tonic-gate typedef struct nfs4_bseqid_entry { 17880Sstevel@tonic-gate nfs4_open_owner_t *bs_oop; 17890Sstevel@tonic-gate nfs4_lock_owner_t *bs_lop; 17900Sstevel@tonic-gate vnode_t *bs_vp; 17910Sstevel@tonic-gate pid_t bs_pid; 17920Sstevel@tonic-gate nfs4_tag_type_t bs_tag; 17930Sstevel@tonic-gate seqid4 bs_seqid; 17940Sstevel@tonic-gate list_node_t bs_node; 17950Sstevel@tonic-gate } nfs4_bseqid_entry_t; 17960Sstevel@tonic-gate 17970Sstevel@tonic-gate #ifdef _KERNEL 17980Sstevel@tonic-gate 17990Sstevel@tonic-gate extern void nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int, 18000Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t, 18010Sstevel@tonic-gate size_t, uint_t, uint_t); 18020Sstevel@tonic-gate extern void nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *); 18030Sstevel@tonic-gate extern void nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4); 18040Sstevel@tonic-gate extern void open_owner_hold(nfs4_open_owner_t *); 18050Sstevel@tonic-gate extern void open_owner_rele(nfs4_open_owner_t *); 18060Sstevel@tonic-gate extern nfs4_open_stream_t *find_or_create_open_stream(nfs4_open_owner_t *, 18070Sstevel@tonic-gate struct rnode4 *, int *); 18080Sstevel@tonic-gate extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *, 18090Sstevel@tonic-gate struct rnode4 *); 18100Sstevel@tonic-gate extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop, 18110Sstevel@tonic-gate struct rnode4 *rp); 18120Sstevel@tonic-gate extern void open_stream_hold(nfs4_open_stream_t *); 18130Sstevel@tonic-gate extern void open_stream_rele(nfs4_open_stream_t *, struct rnode4 *); 18140Sstevel@tonic-gate extern int nfs4close_all(vnode_t *, cred_t *); 18150Sstevel@tonic-gate extern void lock_owner_hold(nfs4_lock_owner_t *); 18160Sstevel@tonic-gate extern void lock_owner_rele(nfs4_lock_owner_t *); 18170Sstevel@tonic-gate extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t); 18180Sstevel@tonic-gate extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t); 18190Sstevel@tonic-gate extern void nfs4_rnode_remove_lock_owner(struct rnode4 *, 18200Sstevel@tonic-gate nfs4_lock_owner_t *); 18210Sstevel@tonic-gate extern void nfs4_flush_lock_owners(struct rnode4 *); 18220Sstevel@tonic-gate extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t); 18230Sstevel@tonic-gate extern void nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *, 18240Sstevel@tonic-gate nfs4_tag_type_t); 18250Sstevel@tonic-gate extern void nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *); 18260Sstevel@tonic-gate extern void nfs4_get_and_set_next_open_seqid(nfs4_open_owner_t *, 18270Sstevel@tonic-gate nfs4_tag_type_t); 18280Sstevel@tonic-gate extern void nfs4_end_open_seqid_sync(nfs4_open_owner_t *); 18290Sstevel@tonic-gate extern int nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *); 18300Sstevel@tonic-gate extern void nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *); 18310Sstevel@tonic-gate extern int nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *); 18320Sstevel@tonic-gate extern void nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *, 18330Sstevel@tonic-gate nfs4_open_stream_t *, clientid4, locker4 *); 18340Sstevel@tonic-gate extern void nfs4_destroy_open_owner(nfs4_open_owner_t *); 18350Sstevel@tonic-gate 18360Sstevel@tonic-gate extern void nfs4_renew_lease_thread(nfs4_server_t *); 18370Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server(mntinfo4_t *); 18380Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server_all(mntinfo4_t *, int all); 18390Sstevel@tonic-gate extern nfs4_server_t *new_nfs4_server(servinfo4_t *, cred_t *); 18400Sstevel@tonic-gate extern void nfs4_mark_srv_dead(nfs4_server_t *); 18410Sstevel@tonic-gate extern nfs4_server_t *servinfo4_to_nfs4_server(servinfo4_t *); 18420Sstevel@tonic-gate extern void nfs4_inc_state_ref_count(mntinfo4_t *); 18430Sstevel@tonic-gate extern void nfs4_inc_state_ref_count_nolock(nfs4_server_t *, 18440Sstevel@tonic-gate mntinfo4_t *); 18450Sstevel@tonic-gate extern void nfs4_dec_state_ref_count(mntinfo4_t *); 18460Sstevel@tonic-gate extern void nfs4_dec_state_ref_count_nolock(nfs4_server_t *, 18470Sstevel@tonic-gate mntinfo4_t *); 18480Sstevel@tonic-gate extern clientid4 mi2clientid(mntinfo4_t *); 18490Sstevel@tonic-gate extern int nfs4_server_in_recovery(nfs4_server_t *); 18500Sstevel@tonic-gate extern bool_t nfs4_server_vlock(nfs4_server_t *, int); 18510Sstevel@tonic-gate extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *); 18520Sstevel@tonic-gate extern uint64_t nfs4_get_new_oo_name(void); 18530Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *); 18540Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *); 18550Sstevel@tonic-gate extern void nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *, 18560Sstevel@tonic-gate int, u_offset_t, cred_t *, nfs4_error_t *, 18570Sstevel@tonic-gate nfs4_lost_rqst_t *, int *); 18580Sstevel@tonic-gate extern void nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *, 18590Sstevel@tonic-gate nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *, 18600Sstevel@tonic-gate vnode_t *, int, int); 18610Sstevel@tonic-gate extern void nfs4_open_downgrade(int, int, nfs4_open_owner_t *, 18620Sstevel@tonic-gate nfs4_open_stream_t *, vnode_t *, cred_t *, 18630Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *); 18640Sstevel@tonic-gate extern seqid4 nfs4_get_open_seqid(nfs4_open_owner_t *); 18650Sstevel@tonic-gate extern cred_t *nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *); 18660Sstevel@tonic-gate extern void nfs4_init_stateid_types(nfs4_stateid_types_t *); 18670Sstevel@tonic-gate extern void nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *); 18680Sstevel@tonic-gate 18690Sstevel@tonic-gate extern kmutex_t nfs4_server_lst_lock; 18700Sstevel@tonic-gate 18710Sstevel@tonic-gate extern void nfs4callback_destroy(nfs4_server_t *); 18720Sstevel@tonic-gate extern void nfs4_callback_init(void); 18730Sstevel@tonic-gate extern void nfs4_callback_fini(void); 18740Sstevel@tonic-gate extern void nfs4_cb_args(nfs4_server_t *, struct knetconfig *, 18750Sstevel@tonic-gate SETCLIENTID4args *); 18760Sstevel@tonic-gate extern void nfs4delegreturn_async(struct rnode4 *, int, bool_t); 18770Sstevel@tonic-gate 18780Sstevel@tonic-gate extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy; 18790Sstevel@tonic-gate 18800Sstevel@tonic-gate extern void nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *); 18810Sstevel@tonic-gate extern void nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *); 18820Sstevel@tonic-gate extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *); 18830Sstevel@tonic-gate extern bool_t nfs4_fs_active(nfs4_server_t *); 18840Sstevel@tonic-gate extern void nfs4_server_rele(nfs4_server_t *); 18850Sstevel@tonic-gate extern bool_t inlease(nfs4_server_t *); 18860Sstevel@tonic-gate extern bool_t nfs4_has_pages(vnode_t *); 18870Sstevel@tonic-gate extern void nfs4_log_badowner(mntinfo4_t *, nfs_opnum4); 18880Sstevel@tonic-gate 18890Sstevel@tonic-gate #endif /* _KERNEL */ 18900Sstevel@tonic-gate 18910Sstevel@tonic-gate /* 18920Sstevel@tonic-gate * Client State Recovery 18930Sstevel@tonic-gate */ 18940Sstevel@tonic-gate 18950Sstevel@tonic-gate /* 18960Sstevel@tonic-gate * The following defines are used for rs_flags in 18970Sstevel@tonic-gate * a nfs4_recov_state_t structure. 18980Sstevel@tonic-gate * 18990Sstevel@tonic-gate * NFS4_RS_RENAME_HELD Indicates that the mi_rename_lock was held. 19000Sstevel@tonic-gate * NFS4_RS_GRACE_MSG Set once we have uprintf'ed a grace message. 19010Sstevel@tonic-gate * NFS4_RS_DELAY_MSG Set once we have uprintf'ed a delay message. 19020Sstevel@tonic-gate * NFS4_RS_RECALL_HELD1 r_deleg_recall_lock for vp1 was held. 19030Sstevel@tonic-gate * NFS4_RS_RECALL_HELD2 r_deleg_recall_lock for vp2 was held. 19040Sstevel@tonic-gate */ 19050Sstevel@tonic-gate #define NFS4_RS_RENAME_HELD 0x000000001 19060Sstevel@tonic-gate #define NFS4_RS_GRACE_MSG 0x000000002 19070Sstevel@tonic-gate #define NFS4_RS_DELAY_MSG 0x000000004 19080Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD1 0x000000008 19090Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD2 0x000000010 19100Sstevel@tonic-gate 19110Sstevel@tonic-gate /* 19120Sstevel@tonic-gate * Information that is retrieved from nfs4_start_op() and that is 19130Sstevel@tonic-gate * passed into nfs4_end_op(). 19140Sstevel@tonic-gate * 19150Sstevel@tonic-gate * rs_sp is a reference to the nfs4_server that was found, or NULL. 19160Sstevel@tonic-gate * 19170Sstevel@tonic-gate * rs_num_retry_despite_err is the number times client retried an 19180Sstevel@tonic-gate * OTW op despite a recovery error. It is only incremented for hints 19190Sstevel@tonic-gate * exempt to normal R4RECOVERR processing 19200Sstevel@tonic-gate * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN). (XXX this special-case code 19210Sstevel@tonic-gate * needs review for possible removal.) 19220Sstevel@tonic-gate * It is initialized wherever nfs4_recov_state_t is declared -- usually 19230Sstevel@tonic-gate * very near initialization of rs_flags. 19240Sstevel@tonic-gate */ 19250Sstevel@tonic-gate typedef struct { 19260Sstevel@tonic-gate nfs4_server_t *rs_sp; 19270Sstevel@tonic-gate int rs_flags; 19280Sstevel@tonic-gate int rs_num_retry_despite_err; 19290Sstevel@tonic-gate } nfs4_recov_state_t; 19300Sstevel@tonic-gate 19310Sstevel@tonic-gate /* 19320Sstevel@tonic-gate * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root. 19330Sstevel@tonic-gate */ 19340Sstevel@tonic-gate 19350Sstevel@tonic-gate #define NFS4_REMAP_CKATTRS 1 19360Sstevel@tonic-gate #define NFS4_REMAP_NEEDSOP 2 19370Sstevel@tonic-gate 19380Sstevel@tonic-gate #ifdef _KERNEL 19390Sstevel@tonic-gate 19400Sstevel@tonic-gate extern int nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int, 19410Sstevel@tonic-gate vnode_t *, int, int *, int, nfs4_recov_state_t *); 19420Sstevel@tonic-gate extern void nfs4setclientid(struct mntinfo4 *, struct cred *, bool_t, 19430Sstevel@tonic-gate nfs4_error_t *); 19440Sstevel@tonic-gate extern void nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *, 19450Sstevel@tonic-gate open_claim_type4, bool_t, bool_t); 19460Sstevel@tonic-gate extern void nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int); 19470Sstevel@tonic-gate extern void nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int, 19480Sstevel@tonic-gate nfs4_error_t *); 19490Sstevel@tonic-gate extern void nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int, 19500Sstevel@tonic-gate nfs4_error_t *); 19510Sstevel@tonic-gate extern int nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t, 19520Sstevel@tonic-gate vnode_t *, cred_t *, vnode_t **, int); 19530Sstevel@tonic-gate extern void nfs4_fail_recov(vnode_t *, char *, int, nfsstat4); 19540Sstevel@tonic-gate 19550Sstevel@tonic-gate extern int nfs4_needs_recovery(nfs4_error_t *, bool_t, vfs_t *); 19560Sstevel@tonic-gate extern int nfs4_recov_marks_dead(nfsstat4); 19570Sstevel@tonic-gate extern bool_t nfs4_start_recovery(nfs4_error_t *, struct mntinfo4 *, 19580Sstevel@tonic-gate vnode_t *, vnode_t *, stateid4 *, 19590Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs_opnum4, nfs4_bseqid_entry_t *); 19600Sstevel@tonic-gate extern int nfs4_start_op(struct mntinfo4 *, vnode_t *, vnode_t *, 19610Sstevel@tonic-gate nfs4_recov_state_t *); 19620Sstevel@tonic-gate extern void nfs4_end_op(struct mntinfo4 *, vnode_t *, vnode_t *, 19630Sstevel@tonic-gate nfs4_recov_state_t *, bool_t); 19640Sstevel@tonic-gate extern int nfs4_start_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 19650Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t *); 19660Sstevel@tonic-gate extern void nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 19670Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t); 19680Sstevel@tonic-gate extern char *nfs4_recov_action_to_str(nfs4_recov_t); 19690Sstevel@tonic-gate 19705302Sth199096 /* 19715302Sth199096 * In sequence, code desiring to unmount an ephemeral tree must 19725302Sth199096 * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate, 19735302Sth199096 * and nfs4_ephemeral_umount_unlock. The _unlock must also be 19745302Sth199096 * called on all error paths that occur before it would naturally 19755302Sth199096 * be invoked. 19765302Sth199096 * 19775302Sth199096 * The caller must also provde a pointer to a boolean to keep track 19785302Sth199096 * of whether or not the code in _unlock is to be ran. 19795302Sth199096 */ 19805302Sth199096 extern void nfs4_ephemeral_umount_activate(mntinfo4_t *, 19817790SThomas.Haynes@Sun.COM bool_t *, bool_t *, nfs4_ephemeral_tree_t **); 19825302Sth199096 extern int nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *, 19837790SThomas.Haynes@Sun.COM bool_t *, bool_t *, nfs4_ephemeral_tree_t **); 19847790SThomas.Haynes@Sun.COM extern void nfs4_ephemeral_umount_unlock(bool_t *, bool_t *, 19855302Sth199096 nfs4_ephemeral_tree_t **); 19865302Sth199096 19877318SThomas.Haynes@Sun.COM extern int nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp); 19885302Sth199096 19890Sstevel@tonic-gate extern int wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t, 19900Sstevel@tonic-gate nfs4_recov_state_t *); 19910Sstevel@tonic-gate extern void nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *); 19920Sstevel@tonic-gate extern void nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t, 19930Sstevel@tonic-gate int, nfsstat4); 19940Sstevel@tonic-gate extern time_t nfs4err_delay_time; 19950Sstevel@tonic-gate extern void nfs4_set_grace_wait(mntinfo4_t *); 19960Sstevel@tonic-gate extern void nfs4_set_delay_wait(vnode_t *); 19970Sstevel@tonic-gate extern int nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *); 19980Sstevel@tonic-gate extern int nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *); 19990Sstevel@tonic-gate extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *, 20000Sstevel@tonic-gate nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t, 20010Sstevel@tonic-gate seqid4); 20020Sstevel@tonic-gate 20030Sstevel@tonic-gate extern void nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *, 20040Sstevel@tonic-gate nfs4_error_t *); 20050Sstevel@tonic-gate extern void nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *, 20060Sstevel@tonic-gate nfs4_server_t *); 20070Sstevel@tonic-gate extern int nfs4_rpc_retry_error(int); 20080Sstevel@tonic-gate extern int nfs4_try_failover(nfs4_error_t *); 20090Sstevel@tonic-gate extern void nfs4_free_msg(nfs4_debug_msg_t *); 20100Sstevel@tonic-gate extern void nfs4_mnt_recov_kstat_init(vfs_t *); 20110Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_delay(mntinfo4_t *); 20120Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_no_grace(mntinfo4_t *); 20130Sstevel@tonic-gate extern char *nfs4_stat_to_str(nfsstat4); 20140Sstevel@tonic-gate extern char *nfs4_op_to_str(nfs_opnum4); 20150Sstevel@tonic-gate 20160Sstevel@tonic-gate extern void nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *, 20170Sstevel@tonic-gate uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t, 20180Sstevel@tonic-gate nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4); 20190Sstevel@tonic-gate extern void nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4, 20200Sstevel@tonic-gate nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *); 20210Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_event) 20220Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_fact) 20230Sstevel@tonic-gate 20240Sstevel@tonic-gate /* Used for preformed "." and ".." dirents */ 20250Sstevel@tonic-gate extern char *nfs4_dot_entries; 20260Sstevel@tonic-gate extern char *nfs4_dot_dot_entry; 20270Sstevel@tonic-gate 20280Sstevel@tonic-gate #ifdef DEBUG 20290Sstevel@tonic-gate extern uint_t nfs4_tsd_key; 20300Sstevel@tonic-gate #endif 20310Sstevel@tonic-gate 20320Sstevel@tonic-gate #endif /* _KERNEL */ 20330Sstevel@tonic-gate 20340Sstevel@tonic-gate /* 20350Sstevel@tonic-gate * Filehandle management. 20360Sstevel@tonic-gate * 20370Sstevel@tonic-gate * Filehandles can change in v4, so rather than storing the filehandle 20380Sstevel@tonic-gate * directly in the rnode, etc., we manage the filehandle through one of 20390Sstevel@tonic-gate * these objects. 20400Sstevel@tonic-gate * Locking: sfh_fh and sfh_tree is protected by the filesystem's 20410Sstevel@tonic-gate * mi_fh_lock. The reference count and flags are protected by sfh_lock. 20420Sstevel@tonic-gate * sfh_mi is read-only. 20430Sstevel@tonic-gate * 20440Sstevel@tonic-gate * mntinfo4_t::mi_fh_lock > sfh_lock. 20450Sstevel@tonic-gate */ 20460Sstevel@tonic-gate 20470Sstevel@tonic-gate typedef struct nfs4_sharedfh { 20480Sstevel@tonic-gate nfs_fh4 sfh_fh; /* key and current filehandle */ 20490Sstevel@tonic-gate kmutex_t sfh_lock; 20500Sstevel@tonic-gate uint_t sfh_refcnt; /* reference count */ 20510Sstevel@tonic-gate uint_t sfh_flags; 20520Sstevel@tonic-gate mntinfo4_t *sfh_mi; /* backptr to filesystem */ 20530Sstevel@tonic-gate avl_node_t sfh_tree; /* used by avl package */ 20540Sstevel@tonic-gate } nfs4_sharedfh_t; 20550Sstevel@tonic-gate 20560Sstevel@tonic-gate #define SFH4_SAME(sfh1, sfh2) ((sfh1) == (sfh2)) 20570Sstevel@tonic-gate 20580Sstevel@tonic-gate /* 20590Sstevel@tonic-gate * Flags. 20600Sstevel@tonic-gate */ 20610Sstevel@tonic-gate #define SFH4_IN_TREE 0x1 /* currently in an AVL tree */ 20620Sstevel@tonic-gate 20630Sstevel@tonic-gate #ifdef _KERNEL 20640Sstevel@tonic-gate 20650Sstevel@tonic-gate extern void sfh4_createtab(avl_tree_t *); 20660Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *); 20670Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *, 20680Sstevel@tonic-gate nfs4_sharedfh_t *); 20690Sstevel@tonic-gate extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *); 20700Sstevel@tonic-gate extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *); 20710Sstevel@tonic-gate extern void sfh4_hold(nfs4_sharedfh_t *); 20720Sstevel@tonic-gate extern void sfh4_rele(nfs4_sharedfh_t **); 20730Sstevel@tonic-gate extern void sfh4_printfhandle(const nfs4_sharedfh_t *); 20740Sstevel@tonic-gate 20750Sstevel@tonic-gate #endif 20760Sstevel@tonic-gate 20770Sstevel@tonic-gate /* 20780Sstevel@tonic-gate * Path and file name management. 20790Sstevel@tonic-gate * 20800Sstevel@tonic-gate * This type stores the name of an entry in the filesystem and keeps enough 20810Sstevel@tonic-gate * information that it can provide a complete path. All fields are 20820Sstevel@tonic-gate * protected by fn_lock, except for the reference count, which is managed 20830Sstevel@tonic-gate * using atomic add/subtract. 20840Sstevel@tonic-gate * 2085*7902SNagakiran.Rajashekar@Sun.COM * Additionally shared filehandle for this fname is stored. 2086*7902SNagakiran.Rajashekar@Sun.COM * Normally, fn_get() when it creates this fname stores the passed in 2087*7902SNagakiran.Rajashekar@Sun.COM * shared fh in fn_sfh by doing sfh_hold. Similarly the path which 2088*7902SNagakiran.Rajashekar@Sun.COM * destroys this fname releases the reference on this fh by doing sfh_rele. 2089*7902SNagakiran.Rajashekar@Sun.COM * 2090*7902SNagakiran.Rajashekar@Sun.COM * fn_get uses the fn_sfh to refine the comparision in cases 2091*7902SNagakiran.Rajashekar@Sun.COM * where we have matched the name but have differing file handles, 2092*7902SNagakiran.Rajashekar@Sun.COM * this normally happens due to 2093*7902SNagakiran.Rajashekar@Sun.COM * 2094*7902SNagakiran.Rajashekar@Sun.COM * 1. Server side rename of a file/directory. 2095*7902SNagakiran.Rajashekar@Sun.COM * 2. Another client renaming a file/directory on the server. 2096*7902SNagakiran.Rajashekar@Sun.COM * 2097*7902SNagakiran.Rajashekar@Sun.COM * Differing names but same filehandle is possible as in the case of hardlinks, 2098*7902SNagakiran.Rajashekar@Sun.COM * but differing filehandles with same name component will later confuse 2099*7902SNagakiran.Rajashekar@Sun.COM * the client and can cause various panics. 2100*7902SNagakiran.Rajashekar@Sun.COM * 21010Sstevel@tonic-gate * Lock order: child and then parent. 21020Sstevel@tonic-gate */ 21030Sstevel@tonic-gate 21040Sstevel@tonic-gate typedef struct nfs4_fname { 21050Sstevel@tonic-gate struct nfs4_fname *fn_parent; /* parent name; null if fs root */ 21060Sstevel@tonic-gate char *fn_name; /* the actual name */ 2107*7902SNagakiran.Rajashekar@Sun.COM nfs4_sharedfh_t *fn_sfh; /* The fh for this fname */ 21080Sstevel@tonic-gate ssize_t fn_len; /* strlen(fn_name) */ 21090Sstevel@tonic-gate uint32_t fn_refcnt; /* reference count */ 21100Sstevel@tonic-gate kmutex_t fn_lock; 21110Sstevel@tonic-gate avl_node_t fn_tree; 21120Sstevel@tonic-gate avl_tree_t fn_children; /* children, if any */ 21130Sstevel@tonic-gate } nfs4_fname_t; 21140Sstevel@tonic-gate 21150Sstevel@tonic-gate #ifdef _KERNEL 21160Sstevel@tonic-gate 21170Sstevel@tonic-gate extern vnode_t nfs4_xattr_notsupp_vnode; 21180Sstevel@tonic-gate #define NFS4_XATTR_DIR_NOTSUPP &nfs4_xattr_notsupp_vnode 21190Sstevel@tonic-gate 2120*7902SNagakiran.Rajashekar@Sun.COM extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *); 21210Sstevel@tonic-gate extern void fn_hold(nfs4_fname_t *); 21220Sstevel@tonic-gate extern void fn_rele(nfs4_fname_t **); 21230Sstevel@tonic-gate extern char *fn_name(nfs4_fname_t *); 21240Sstevel@tonic-gate extern char *fn_path(nfs4_fname_t *); 21250Sstevel@tonic-gate extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *); 21260Sstevel@tonic-gate extern nfs4_fname_t *fn_parent(nfs4_fname_t *); 21270Sstevel@tonic-gate 21280Sstevel@tonic-gate #endif 21290Sstevel@tonic-gate 21300Sstevel@tonic-gate /* 21310Sstevel@tonic-gate * Per-zone data for managing client handles, included in this file for the 21320Sstevel@tonic-gate * benefit of MDB. 21330Sstevel@tonic-gate */ 21340Sstevel@tonic-gate struct nfs4_clnt { 21350Sstevel@tonic-gate struct chhead *nfscl_chtable4; 21360Sstevel@tonic-gate kmutex_t nfscl_chtable4_lock; 21370Sstevel@tonic-gate zoneid_t nfscl_zoneid; 21380Sstevel@tonic-gate list_node_t nfscl_node; 21390Sstevel@tonic-gate struct clstat4 nfscl_stat; 21400Sstevel@tonic-gate }; 21410Sstevel@tonic-gate 21420Sstevel@tonic-gate #ifdef __cplusplus 21430Sstevel@tonic-gate } 21440Sstevel@tonic-gate #endif 21450Sstevel@tonic-gate 21460Sstevel@tonic-gate #endif /* _NFS4_CLNT_H */ 2147