17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f86c6ccaSdm120769 * Common Development and Distribution License (the "License"). 6f86c6ccaSdm120769 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22a19609f8Sjv227347 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 267c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 307c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifndef _NFS4_CLNT_H 347c478bd9Sstevel@tonic-gate #define _NFS4_CLNT_H 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/errno.h> 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 387c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 397c478bd9Sstevel@tonic-gate #include <sys/time.h> 407c478bd9Sstevel@tonic-gate #include <sys/flock.h> 417c478bd9Sstevel@tonic-gate #include <vm/page.h> 427c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 437c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h> 447c478bd9Sstevel@tonic-gate #include <nfs/rnode.h> 457c478bd9Sstevel@tonic-gate #include <sys/avl.h> 467c478bd9Sstevel@tonic-gate #include <sys/list.h> 47b9238976Sth199096 #include <rpc/auth.h> 482f172c55SRobert Thurlow #include <sys/door.h> 490776f5e6SVallish Vaidyeshwara #include <sys/condvar_impl.h> 50a19609f8Sjv227347 #include <sys/zone.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #ifdef __cplusplus 537c478bd9Sstevel@tonic-gate extern "C" { 547c478bd9Sstevel@tonic-gate #endif 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #define NFS4_SIZE_OK(size) ((size) <= MAXOFFSET_T) 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* Four states of nfs4_server's lease_valid */ 597c478bd9Sstevel@tonic-gate #define NFS4_LEASE_INVALID 0 607c478bd9Sstevel@tonic-gate #define NFS4_LEASE_VALID 1 617c478bd9Sstevel@tonic-gate #define NFS4_LEASE_UNINITIALIZED 2 627c478bd9Sstevel@tonic-gate #define NFS4_LEASE_NOT_STARTED 3 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* flag to tell the renew thread it should exit */ 657c478bd9Sstevel@tonic-gate #define NFS4_THREAD_EXIT 1 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* Default number of seconds to wait on GRACE and DELAY errors */ 687c478bd9Sstevel@tonic-gate #define NFS4ERR_DELAY_TIME 10 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* Number of hash buckets for open owners for each nfs4_server */ 717c478bd9Sstevel@tonic-gate #define NFS4_NUM_OO_BUCKETS 53 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* Number of freed open owners (per mntinfo4_t) to keep around */ 747c478bd9Sstevel@tonic-gate #define NFS4_NUM_FREED_OPEN_OWNERS 8 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */ 777c478bd9Sstevel@tonic-gate #define NFS4_RETRY_SCLID_DELAY 10 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */ 807c478bd9Sstevel@tonic-gate #define NFS4_NUM_SCLID_RETRIES 3 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */ 837c478bd9Sstevel@tonic-gate #define NFS4_NUM_RETRY_BAD_SEQID 3 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate /* 860776f5e6SVallish Vaidyeshwara * Macro to wakeup sleeping async worker threads. 870776f5e6SVallish Vaidyeshwara */ 880776f5e6SVallish Vaidyeshwara #define NFS4_WAKE_ASYNC_WORKER(work_cv) { \ 890776f5e6SVallish Vaidyeshwara if (CV_HAS_WAITERS(&work_cv[NFS4_ASYNC_QUEUE])) \ 900776f5e6SVallish Vaidyeshwara cv_signal(&work_cv[NFS4_ASYNC_QUEUE]); \ 910776f5e6SVallish Vaidyeshwara else if (CV_HAS_WAITERS(&work_cv[NFS4_ASYNC_PGOPS_QUEUE])) \ 920776f5e6SVallish Vaidyeshwara cv_signal(&work_cv[NFS4_ASYNC_PGOPS_QUEUE]); \ 930776f5e6SVallish Vaidyeshwara } 940776f5e6SVallish Vaidyeshwara 950776f5e6SVallish Vaidyeshwara #define NFS4_WAKEALL_ASYNC_WORKERS(work_cv) { \ 960776f5e6SVallish Vaidyeshwara cv_broadcast(&work_cv[NFS4_ASYNC_QUEUE]); \ 970776f5e6SVallish Vaidyeshwara cv_broadcast(&work_cv[NFS4_ASYNC_PGOPS_QUEUE]); \ 980776f5e6SVallish Vaidyeshwara } 990776f5e6SVallish Vaidyeshwara 1000776f5e6SVallish Vaidyeshwara /* 1017c478bd9Sstevel@tonic-gate * Is the attribute cache valid? If client holds a delegation, then attrs 1027c478bd9Sstevel@tonic-gate * are by definition valid. If not, then check to see if attrs have timed out. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate #define ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \ 1057c478bd9Sstevel@tonic-gate gethrtime() < VTOR4(vp)->r_time_attr_inval) 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * Flags to indicate whether to purge the DNLC for non-directory vnodes 1097c478bd9Sstevel@tonic-gate * in a call to nfs_purge_caches. 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate #define NFS4_NOPURGE_DNLC 0 1127c478bd9Sstevel@tonic-gate #define NFS4_PURGE_DNLC 1 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* 1157c478bd9Sstevel@tonic-gate * Is cache valid? 1167c478bd9Sstevel@tonic-gate * Swap is always valid, if no attributes (attrtime == 0) or 1177c478bd9Sstevel@tonic-gate * if mtime matches cached mtime it is valid 1187c478bd9Sstevel@tonic-gate * NOTE: mtime is now a timestruc_t. 1197c478bd9Sstevel@tonic-gate * Caller should be holding the rnode r_statelock mutex. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate #define CACHE4_VALID(rp, mtime, fsize) \ 1227c478bd9Sstevel@tonic-gate ((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP || \ 1237c478bd9Sstevel@tonic-gate (((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec && \ 1247c478bd9Sstevel@tonic-gate (mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \ 1257c478bd9Sstevel@tonic-gate ((fsize) == (rp)->r_attr.va_size))) 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * Macro to detect forced unmount or a zone shutdown. 1297c478bd9Sstevel@tonic-gate */ 1307c478bd9Sstevel@tonic-gate #define FS_OR_ZONE_GONE4(vfsp) \ 1317c478bd9Sstevel@tonic-gate (((vfsp)->vfs_flag & VFS_UNMOUNTED) || \ 1327c478bd9Sstevel@tonic-gate zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * Macro to help determine whether a request failed because the underlying 1367c478bd9Sstevel@tonic-gate * filesystem has been forcibly unmounted or because of zone shutdown. 1377c478bd9Sstevel@tonic-gate */ 1387c478bd9Sstevel@tonic-gate #define NFS4_FRC_UNMT_ERR(err, vfsp) \ 1397c478bd9Sstevel@tonic-gate ((err) == EIO && FS_OR_ZONE_GONE4((vfsp))) 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * Due to the way the address space callbacks are used to execute a delmap, 1437c478bd9Sstevel@tonic-gate * we must keep track of how many times the same thread has called 1447c478bd9Sstevel@tonic-gate * VOP_DELMAP()->nfs4_delmap(). This is done by having a list of 1457c478bd9Sstevel@tonic-gate * nfs4_delmapcall_t's associated with each rnode4_t. This list is protected 1467c478bd9Sstevel@tonic-gate * by the rnode4_t's r_statelock. The individual elements do not need to be 1477c478bd9Sstevel@tonic-gate * protected as they will only ever be created, modified and destroyed by 1487c478bd9Sstevel@tonic-gate * one thread (the call_id). 1497c478bd9Sstevel@tonic-gate * See nfs4_delmap() for further explanation. 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate typedef struct nfs4_delmapcall { 1527c478bd9Sstevel@tonic-gate kthread_t *call_id; 1537c478bd9Sstevel@tonic-gate int error; /* error from delmap */ 1547c478bd9Sstevel@tonic-gate list_node_t call_node; 1557c478bd9Sstevel@tonic-gate } nfs4_delmapcall_t; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * delmap address space callback args 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate typedef struct nfs4_delmap_args { 1617c478bd9Sstevel@tonic-gate vnode_t *vp; 1627c478bd9Sstevel@tonic-gate offset_t off; 1637c478bd9Sstevel@tonic-gate caddr_t addr; 1647c478bd9Sstevel@tonic-gate size_t len; 1657c478bd9Sstevel@tonic-gate uint_t prot; 1667c478bd9Sstevel@tonic-gate uint_t maxprot; 1677c478bd9Sstevel@tonic-gate uint_t flags; 1687c478bd9Sstevel@tonic-gate cred_t *cr; 1697c478bd9Sstevel@tonic-gate nfs4_delmapcall_t *caller; /* to retrieve errors from the cb */ 1707c478bd9Sstevel@tonic-gate } nfs4_delmap_args_t; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * client side statistics 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate /* 1767c478bd9Sstevel@tonic-gate * Per-zone counters 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate struct clstat4 { 1797c478bd9Sstevel@tonic-gate kstat_named_t calls; /* client requests */ 1807c478bd9Sstevel@tonic-gate kstat_named_t badcalls; /* rpc failures */ 1812f172c55SRobert Thurlow kstat_named_t referrals; /* referrals */ 1822f172c55SRobert Thurlow kstat_named_t referlinks; /* referrals as symlinks */ 1837c478bd9Sstevel@tonic-gate kstat_named_t clgets; /* client handle gets */ 1847c478bd9Sstevel@tonic-gate kstat_named_t cltoomany; /* client handle cache misses */ 1857c478bd9Sstevel@tonic-gate #ifdef DEBUG 1867c478bd9Sstevel@tonic-gate kstat_named_t clalloc; /* number of client handles */ 1877c478bd9Sstevel@tonic-gate kstat_named_t noresponse; /* server not responding cnt */ 1887c478bd9Sstevel@tonic-gate kstat_named_t failover; /* server failover count */ 1897c478bd9Sstevel@tonic-gate kstat_named_t remap; /* server remap count */ 1907c478bd9Sstevel@tonic-gate #endif 1917c478bd9Sstevel@tonic-gate }; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate #ifdef DEBUG 1947c478bd9Sstevel@tonic-gate /* 1957c478bd9Sstevel@tonic-gate * The following are statistics that describe the behavior of the system as a 1967c478bd9Sstevel@tonic-gate * whole and don't correspond to any particular zone. 1977c478bd9Sstevel@tonic-gate */ 1987c478bd9Sstevel@tonic-gate struct clstat4_debug { 1997c478bd9Sstevel@tonic-gate kstat_named_t nrnode; /* number of allocated rnodes */ 2007c478bd9Sstevel@tonic-gate kstat_named_t access; /* size of access cache */ 2017c478bd9Sstevel@tonic-gate kstat_named_t dirent; /* size of readdir cache */ 2027c478bd9Sstevel@tonic-gate kstat_named_t dirents; /* size of readdir buf cache */ 2037c478bd9Sstevel@tonic-gate kstat_named_t reclaim; /* number of reclaims */ 2047c478bd9Sstevel@tonic-gate kstat_named_t clreclaim; /* number of cl reclaims */ 2057c478bd9Sstevel@tonic-gate kstat_named_t f_reclaim; /* number of free reclaims */ 2067c478bd9Sstevel@tonic-gate kstat_named_t a_reclaim; /* number of active reclaims */ 2077c478bd9Sstevel@tonic-gate kstat_named_t r_reclaim; /* number of rnode reclaims */ 2087c478bd9Sstevel@tonic-gate kstat_named_t rpath; /* bytes used to store rpaths */ 2097c478bd9Sstevel@tonic-gate }; 2107c478bd9Sstevel@tonic-gate extern struct clstat4_debug clstat4_debug; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate #endif 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /* 2150776f5e6SVallish Vaidyeshwara * The NFS specific async_reqs structure. iotype4 is grouped to support two 2160776f5e6SVallish Vaidyeshwara * types of async thread pools, please read comments section of mntinfo4_t 2170776f5e6SVallish Vaidyeshwara * definition for more information. Care should be taken while adding new 2180776f5e6SVallish Vaidyeshwara * members to this group. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate enum iotype4 { 2227c478bd9Sstevel@tonic-gate NFS4_PUTAPAGE, 2237c478bd9Sstevel@tonic-gate NFS4_PAGEIO, 2240776f5e6SVallish Vaidyeshwara NFS4_COMMIT, 2250776f5e6SVallish Vaidyeshwara NFS4_READ_AHEAD, 2267c478bd9Sstevel@tonic-gate NFS4_READDIR, 2277c478bd9Sstevel@tonic-gate NFS4_INACTIVE, 2280776f5e6SVallish Vaidyeshwara NFS4_ASYNC_TYPES 2297c478bd9Sstevel@tonic-gate }; 2300776f5e6SVallish Vaidyeshwara #define NFS4_ASYNC_PGOPS_TYPES (NFS4_COMMIT + 1) 2310776f5e6SVallish Vaidyeshwara 2320776f5e6SVallish Vaidyeshwara /* 2330776f5e6SVallish Vaidyeshwara * NFS async requests queue type. 2340776f5e6SVallish Vaidyeshwara */ 2350776f5e6SVallish Vaidyeshwara enum ioqtype4 { 2360776f5e6SVallish Vaidyeshwara NFS4_ASYNC_QUEUE, 2370776f5e6SVallish Vaidyeshwara NFS4_ASYNC_PGOPS_QUEUE, 2380776f5e6SVallish Vaidyeshwara NFS4_MAX_ASYNC_QUEUES 2390776f5e6SVallish Vaidyeshwara }; 2400776f5e6SVallish Vaidyeshwara 2410776f5e6SVallish Vaidyeshwara /* 2420776f5e6SVallish Vaidyeshwara * Number of NFS async threads operating exclusively on page op requests. 2430776f5e6SVallish Vaidyeshwara */ 2440776f5e6SVallish Vaidyeshwara #define NUM_ASYNC_PGOPS_THREADS 0x2 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate struct nfs4_async_read_req { 2477c478bd9Sstevel@tonic-gate void (*readahead)(); /* pointer to readahead function */ 2487c478bd9Sstevel@tonic-gate u_offset_t blkoff; /* offset in file */ 2497c478bd9Sstevel@tonic-gate struct seg *seg; /* segment to do i/o to */ 2507c478bd9Sstevel@tonic-gate caddr_t addr; /* address to do i/o to */ 2517c478bd9Sstevel@tonic-gate }; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate struct nfs4_pageio_req { 2547c478bd9Sstevel@tonic-gate int (*pageio)(); /* pointer to pageio function */ 2557c478bd9Sstevel@tonic-gate page_t *pp; /* page list */ 2567c478bd9Sstevel@tonic-gate u_offset_t io_off; /* offset in file */ 2577c478bd9Sstevel@tonic-gate uint_t io_len; /* size of request */ 2587c478bd9Sstevel@tonic-gate int flags; 2597c478bd9Sstevel@tonic-gate }; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate struct nfs4_readdir_req { 2627c478bd9Sstevel@tonic-gate int (*readdir)(); /* pointer to readdir function */ 2637c478bd9Sstevel@tonic-gate struct rddir4_cache *rdc; /* pointer to cache entry to fill */ 2647c478bd9Sstevel@tonic-gate }; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate struct nfs4_commit_req { 2677c478bd9Sstevel@tonic-gate void (*commit)(); /* pointer to commit function */ 2687c478bd9Sstevel@tonic-gate page_t *plist; /* page list */ 2697c478bd9Sstevel@tonic-gate offset4 offset; /* starting offset */ 2707c478bd9Sstevel@tonic-gate count4 count; /* size of range to be commited */ 2717c478bd9Sstevel@tonic-gate }; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate struct nfs4_async_reqs { 2747c478bd9Sstevel@tonic-gate struct nfs4_async_reqs *a_next; /* pointer to next arg struct */ 2757c478bd9Sstevel@tonic-gate #ifdef DEBUG 2767c478bd9Sstevel@tonic-gate kthread_t *a_queuer; /* thread id of queueing thread */ 2777c478bd9Sstevel@tonic-gate #endif 2787c478bd9Sstevel@tonic-gate struct vnode *a_vp; /* vnode pointer */ 2797c478bd9Sstevel@tonic-gate struct cred *a_cred; /* cred pointer */ 2807c478bd9Sstevel@tonic-gate enum iotype4 a_io; /* i/o type */ 2817c478bd9Sstevel@tonic-gate union { 2827c478bd9Sstevel@tonic-gate struct nfs4_async_read_req a_read_args; 2837c478bd9Sstevel@tonic-gate struct nfs4_pageio_req a_pageio_args; 2847c478bd9Sstevel@tonic-gate struct nfs4_readdir_req a_readdir_args; 2857c478bd9Sstevel@tonic-gate struct nfs4_commit_req a_commit_args; 2867c478bd9Sstevel@tonic-gate } a_args; 2877c478bd9Sstevel@tonic-gate }; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate #define a_nfs4_readahead a_args.a_read_args.readahead 2907c478bd9Sstevel@tonic-gate #define a_nfs4_blkoff a_args.a_read_args.blkoff 2917c478bd9Sstevel@tonic-gate #define a_nfs4_seg a_args.a_read_args.seg 2927c478bd9Sstevel@tonic-gate #define a_nfs4_addr a_args.a_read_args.addr 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate #define a_nfs4_putapage a_args.a_pageio_args.pageio 2957c478bd9Sstevel@tonic-gate #define a_nfs4_pageio a_args.a_pageio_args.pageio 2967c478bd9Sstevel@tonic-gate #define a_nfs4_pp a_args.a_pageio_args.pp 2977c478bd9Sstevel@tonic-gate #define a_nfs4_off a_args.a_pageio_args.io_off 2987c478bd9Sstevel@tonic-gate #define a_nfs4_len a_args.a_pageio_args.io_len 2997c478bd9Sstevel@tonic-gate #define a_nfs4_flags a_args.a_pageio_args.flags 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate #define a_nfs4_readdir a_args.a_readdir_args.readdir 3027c478bd9Sstevel@tonic-gate #define a_nfs4_rdc a_args.a_readdir_args.rdc 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate #define a_nfs4_commit a_args.a_commit_args.commit 3057c478bd9Sstevel@tonic-gate #define a_nfs4_plist a_args.a_commit_args.plist 3067c478bd9Sstevel@tonic-gate #define a_nfs4_offset a_args.a_commit_args.offset 3077c478bd9Sstevel@tonic-gate #define a_nfs4_count a_args.a_commit_args.count 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate /* 3107c478bd9Sstevel@tonic-gate * Security information 3117c478bd9Sstevel@tonic-gate */ 3127c478bd9Sstevel@tonic-gate typedef struct sv_secinfo { 3137c478bd9Sstevel@tonic-gate uint_t count; /* how many sdata there are */ 3147c478bd9Sstevel@tonic-gate uint_t index; /* which sdata[index] */ 3157c478bd9Sstevel@tonic-gate struct sec_data *sdata; 3167c478bd9Sstevel@tonic-gate } sv_secinfo_t; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate /* 3197c478bd9Sstevel@tonic-gate * Hash bucket for the mi's open owner list (mi_oo_list). 3207c478bd9Sstevel@tonic-gate */ 3217c478bd9Sstevel@tonic-gate typedef struct nfs4_oo_hash_bucket { 3227c478bd9Sstevel@tonic-gate list_t b_oo_hash_list; 3237c478bd9Sstevel@tonic-gate kmutex_t b_lock; 3247c478bd9Sstevel@tonic-gate } nfs4_oo_hash_bucket_t; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Global array of ctags. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate extern ctag_t nfs4_ctags[]; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate typedef enum nfs4_tag_type { 3327c478bd9Sstevel@tonic-gate TAG_NONE, 3337c478bd9Sstevel@tonic-gate TAG_ACCESS, 3347c478bd9Sstevel@tonic-gate TAG_CLOSE, 3357c478bd9Sstevel@tonic-gate TAG_CLOSE_LOST, 3367c478bd9Sstevel@tonic-gate TAG_CLOSE_UNDO, 3377c478bd9Sstevel@tonic-gate TAG_COMMIT, 3387c478bd9Sstevel@tonic-gate TAG_DELEGRETURN, 3397c478bd9Sstevel@tonic-gate TAG_FSINFO, 3407c478bd9Sstevel@tonic-gate TAG_GET_SYMLINK, 3417c478bd9Sstevel@tonic-gate TAG_GETATTR, 3422f172c55SRobert Thurlow TAG_GETATTR_FSLOCATION, 3437c478bd9Sstevel@tonic-gate TAG_INACTIVE, 3447c478bd9Sstevel@tonic-gate TAG_LINK, 3457c478bd9Sstevel@tonic-gate TAG_LOCK, 3467c478bd9Sstevel@tonic-gate TAG_LOCK_RECLAIM, 3477c478bd9Sstevel@tonic-gate TAG_LOCK_RESEND, 3487c478bd9Sstevel@tonic-gate TAG_LOCK_REINSTATE, 3497c478bd9Sstevel@tonic-gate TAG_LOCK_UNKNOWN, 3507c478bd9Sstevel@tonic-gate TAG_LOCKT, 3517c478bd9Sstevel@tonic-gate TAG_LOCKU, 3527c478bd9Sstevel@tonic-gate TAG_LOCKU_RESEND, 3537c478bd9Sstevel@tonic-gate TAG_LOCKU_REINSTATE, 3547c478bd9Sstevel@tonic-gate TAG_LOOKUP, 3557c478bd9Sstevel@tonic-gate TAG_LOOKUP_PARENT, 3567c478bd9Sstevel@tonic-gate TAG_LOOKUP_VALID, 3577c478bd9Sstevel@tonic-gate TAG_LOOKUP_VPARENT, 3587c478bd9Sstevel@tonic-gate TAG_MKDIR, 3597c478bd9Sstevel@tonic-gate TAG_MKNOD, 3607c478bd9Sstevel@tonic-gate TAG_MOUNT, 3617c478bd9Sstevel@tonic-gate TAG_OPEN, 3627c478bd9Sstevel@tonic-gate TAG_OPEN_CONFIRM, 3637c478bd9Sstevel@tonic-gate TAG_OPEN_CONFIRM_LOST, 3647c478bd9Sstevel@tonic-gate TAG_OPEN_DG, 3657c478bd9Sstevel@tonic-gate TAG_OPEN_DG_LOST, 3667c478bd9Sstevel@tonic-gate TAG_OPEN_LOST, 3677c478bd9Sstevel@tonic-gate TAG_OPENATTR, 3687c478bd9Sstevel@tonic-gate TAG_PATHCONF, 3697c478bd9Sstevel@tonic-gate TAG_PUTROOTFH, 3707c478bd9Sstevel@tonic-gate TAG_READ, 3717c478bd9Sstevel@tonic-gate TAG_READAHEAD, 3727c478bd9Sstevel@tonic-gate TAG_READDIR, 3737c478bd9Sstevel@tonic-gate TAG_READLINK, 3747c478bd9Sstevel@tonic-gate TAG_RELOCK, 3757c478bd9Sstevel@tonic-gate TAG_REMAP_LOOKUP, 3767c478bd9Sstevel@tonic-gate TAG_REMAP_LOOKUP_AD, 3777c478bd9Sstevel@tonic-gate TAG_REMAP_LOOKUP_NA, 3787c478bd9Sstevel@tonic-gate TAG_REMAP_MOUNT, 3797c478bd9Sstevel@tonic-gate TAG_RMDIR, 3807c478bd9Sstevel@tonic-gate TAG_REMOVE, 3817c478bd9Sstevel@tonic-gate TAG_RENAME, 3827c478bd9Sstevel@tonic-gate TAG_RENAME_VFH, 3837c478bd9Sstevel@tonic-gate TAG_RENEW, 3847c478bd9Sstevel@tonic-gate TAG_REOPEN, 3857c478bd9Sstevel@tonic-gate TAG_REOPEN_LOST, 3867c478bd9Sstevel@tonic-gate TAG_SECINFO, 3877c478bd9Sstevel@tonic-gate TAG_SETATTR, 3887c478bd9Sstevel@tonic-gate TAG_SETCLIENTID, 3897c478bd9Sstevel@tonic-gate TAG_SETCLIENTID_CF, 3907c478bd9Sstevel@tonic-gate TAG_SYMLINK, 3917c478bd9Sstevel@tonic-gate TAG_WRITE 3927c478bd9Sstevel@tonic-gate } nfs4_tag_type_t; 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate #define NFS4_TAG_INITIALIZER { \ 3957c478bd9Sstevel@tonic-gate {TAG_NONE, "", \ 3967c478bd9Sstevel@tonic-gate {0x20202020, 0x20202020, 0x20202020}}, \ 3977c478bd9Sstevel@tonic-gate {TAG_ACCESS, "access", \ 3987c478bd9Sstevel@tonic-gate {0x61636365, 0x73732020, 0x20202020}}, \ 3997c478bd9Sstevel@tonic-gate {TAG_CLOSE, "close", \ 4007c478bd9Sstevel@tonic-gate {0x636c6f73, 0x65202020, 0x20202020}}, \ 4017c478bd9Sstevel@tonic-gate {TAG_CLOSE_LOST, "lost close", \ 4027c478bd9Sstevel@tonic-gate {0x6c6f7374, 0x20636c6f, 0x73652020}}, \ 4037c478bd9Sstevel@tonic-gate {TAG_CLOSE_UNDO, "undo close", \ 4047c478bd9Sstevel@tonic-gate {0x756e646f, 0x20636c6f, 0x73652020}}, \ 4057c478bd9Sstevel@tonic-gate {TAG_COMMIT, "commit", \ 4067c478bd9Sstevel@tonic-gate {0x636f6d6d, 0x69742020, 0x20202020}}, \ 4077c478bd9Sstevel@tonic-gate {TAG_DELEGRETURN, "delegreturn", \ 4087c478bd9Sstevel@tonic-gate {0x64656c65, 0x67726574, 0x75726e20}}, \ 4097c478bd9Sstevel@tonic-gate {TAG_FSINFO, "fsinfo", \ 4107c478bd9Sstevel@tonic-gate {0x6673696e, 0x666f2020, 0x20202020}}, \ 4117c478bd9Sstevel@tonic-gate {TAG_GET_SYMLINK, "get symlink text", \ 4127c478bd9Sstevel@tonic-gate {0x67657420, 0x736c6e6b, 0x20747874}}, \ 4137c478bd9Sstevel@tonic-gate {TAG_GETATTR, "getattr", \ 4147c478bd9Sstevel@tonic-gate {0x67657461, 0x74747220, 0x20202020}}, \ 4152f172c55SRobert Thurlow {TAG_GETATTR_FSLOCATION, "getattr fslocation", \ 4162f172c55SRobert Thurlow {0x67657461, 0x74747220, 0x66736c6f}}, \ 4177c478bd9Sstevel@tonic-gate {TAG_INACTIVE, "inactive", \ 4187c478bd9Sstevel@tonic-gate {0x696e6163, 0x74697665, 0x20202020}}, \ 4197c478bd9Sstevel@tonic-gate {TAG_LINK, "link", \ 4207c478bd9Sstevel@tonic-gate {0x6c696e6b, 0x20202020, 0x20202020}}, \ 4217c478bd9Sstevel@tonic-gate {TAG_LOCK, "lock", \ 4227c478bd9Sstevel@tonic-gate {0x6c6f636b, 0x20202020, 0x20202020}}, \ 4237c478bd9Sstevel@tonic-gate {TAG_LOCK_RECLAIM, "reclaim lock", \ 4247c478bd9Sstevel@tonic-gate {0x7265636c, 0x61696d20, 0x6c6f636b}}, \ 4257c478bd9Sstevel@tonic-gate {TAG_LOCK_RESEND, "resend lock", \ 4267c478bd9Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b20}}, \ 4277c478bd9Sstevel@tonic-gate {TAG_LOCK_REINSTATE, "reinstate lock", \ 4287c478bd9Sstevel@tonic-gate {0x7265696e, 0x7374206c, 0x6f636b20}}, \ 4297c478bd9Sstevel@tonic-gate {TAG_LOCK_UNKNOWN, "unknown lock", \ 4307c478bd9Sstevel@tonic-gate {0x756e6b6e, 0x6f776e20, 0x6c6f636b}}, \ 4317c478bd9Sstevel@tonic-gate {TAG_LOCKT, "lock test", \ 4327c478bd9Sstevel@tonic-gate {0x6c6f636b, 0x5f746573, 0x74202020}}, \ 4337c478bd9Sstevel@tonic-gate {TAG_LOCKU, "unlock", \ 4347c478bd9Sstevel@tonic-gate {0x756e6c6f, 0x636b2020, 0x20202020}}, \ 4357c478bd9Sstevel@tonic-gate {TAG_LOCKU_RESEND, "resend locku", \ 4367c478bd9Sstevel@tonic-gate {0x72657365, 0x6e64206c, 0x6f636b75}}, \ 4377c478bd9Sstevel@tonic-gate {TAG_LOCKU_REINSTATE, "reinstate unlock", \ 4387c478bd9Sstevel@tonic-gate {0x7265696e, 0x73742075, 0x6e6c636b}}, \ 4397c478bd9Sstevel@tonic-gate {TAG_LOOKUP, "lookup", \ 4407c478bd9Sstevel@tonic-gate {0x6c6f6f6b, 0x75702020, 0x20202020}}, \ 4417c478bd9Sstevel@tonic-gate {TAG_LOOKUP_PARENT, "lookup parent", \ 4427c478bd9Sstevel@tonic-gate {0x6c6f6f6b, 0x75702070, 0x6172656e}}, \ 4437c478bd9Sstevel@tonic-gate {TAG_LOOKUP_VALID, "lookup valid", \ 4447c478bd9Sstevel@tonic-gate {0x6c6f6f6b, 0x75702076, 0x616c6964}}, \ 4457c478bd9Sstevel@tonic-gate {TAG_LOOKUP_VPARENT, "lookup valid parent", \ 4467c478bd9Sstevel@tonic-gate {0x6c6f6f6b, 0x766c6420, 0x7061726e}}, \ 4477c478bd9Sstevel@tonic-gate {TAG_MKDIR, "mkdir", \ 4487c478bd9Sstevel@tonic-gate {0x6d6b6469, 0x72202020, 0x20202020}}, \ 4497c478bd9Sstevel@tonic-gate {TAG_MKNOD, "mknod", \ 4507c478bd9Sstevel@tonic-gate {0x6d6b6e6f, 0x64202020, 0x20202020}}, \ 4517c478bd9Sstevel@tonic-gate {TAG_MOUNT, "mount", \ 4527c478bd9Sstevel@tonic-gate {0x6d6f756e, 0x74202020, 0x20202020}}, \ 4537c478bd9Sstevel@tonic-gate {TAG_OPEN, "open", \ 4547c478bd9Sstevel@tonic-gate {0x6f70656e, 0x20202020, 0x20202020}}, \ 4557c478bd9Sstevel@tonic-gate {TAG_OPEN_CONFIRM, "open confirm", \ 4567c478bd9Sstevel@tonic-gate {0x6f70656e, 0x5f636f6e, 0x6669726d}}, \ 4577c478bd9Sstevel@tonic-gate {TAG_OPEN_CONFIRM_LOST, "lost open confirm", \ 4587c478bd9Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e5f636f}}, \ 4597c478bd9Sstevel@tonic-gate {TAG_OPEN_DG, "open downgrade", \ 4607c478bd9Sstevel@tonic-gate {0x6f70656e, 0x20646772, 0x61646520}}, \ 4617c478bd9Sstevel@tonic-gate {TAG_OPEN_DG_LOST, "lost open downgrade", \ 4627c478bd9Sstevel@tonic-gate {0x6c737420, 0x6f70656e, 0x20646772}}, \ 4637c478bd9Sstevel@tonic-gate {TAG_OPEN_LOST, "lost open", \ 4647c478bd9Sstevel@tonic-gate {0x6c6f7374, 0x206f7065, 0x6e202020}}, \ 4657c478bd9Sstevel@tonic-gate {TAG_OPENATTR, "openattr", \ 4667c478bd9Sstevel@tonic-gate {0x6f70656e, 0x61747472, 0x20202020}}, \ 4673731b537SBart Coddens {TAG_PATHCONF, "pathconf", \ 4687c478bd9Sstevel@tonic-gate {0x70617468, 0x636f6e66, 0x20202020}}, \ 4697c478bd9Sstevel@tonic-gate {TAG_PUTROOTFH, "putrootfh", \ 4707c478bd9Sstevel@tonic-gate {0x70757472, 0x6f6f7466, 0x68202020}}, \ 4717c478bd9Sstevel@tonic-gate {TAG_READ, "read", \ 4727c478bd9Sstevel@tonic-gate {0x72656164, 0x20202020, 0x20202020}}, \ 4737c478bd9Sstevel@tonic-gate {TAG_READAHEAD, "readahead", \ 4747c478bd9Sstevel@tonic-gate {0x72656164, 0x61686561, 0x64202020}}, \ 4757c478bd9Sstevel@tonic-gate {TAG_READDIR, "readdir", \ 4767c478bd9Sstevel@tonic-gate {0x72656164, 0x64697220, 0x20202020}}, \ 4777c478bd9Sstevel@tonic-gate {TAG_READLINK, "readlink", \ 4787c478bd9Sstevel@tonic-gate {0x72656164, 0x6c696e6b, 0x20202020}}, \ 4797c478bd9Sstevel@tonic-gate {TAG_RELOCK, "relock", \ 4807c478bd9Sstevel@tonic-gate {0x72656c6f, 0x636b2020, 0x20202020}}, \ 4817c478bd9Sstevel@tonic-gate {TAG_REMAP_LOOKUP, "remap lookup", \ 4827c478bd9Sstevel@tonic-gate {0x72656d61, 0x70206c6f, 0x6f6b7570}}, \ 4837c478bd9Sstevel@tonic-gate {TAG_REMAP_LOOKUP_AD, "remap lookup attr dir", \ 4847c478bd9Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206164}}, \ 4857c478bd9Sstevel@tonic-gate {TAG_REMAP_LOOKUP_NA, "remap lookup named attrs", \ 4867c478bd9Sstevel@tonic-gate {0x72656d70, 0x206c6b75, 0x70206e61}}, \ 4877c478bd9Sstevel@tonic-gate {TAG_REMAP_MOUNT, "remap mount", \ 4887c478bd9Sstevel@tonic-gate {0x72656d61, 0x70206d6f, 0x756e7420}}, \ 4897c478bd9Sstevel@tonic-gate {TAG_RMDIR, "rmdir", \ 4907c478bd9Sstevel@tonic-gate {0x726d6469, 0x72202020, 0x20202020}}, \ 4917c478bd9Sstevel@tonic-gate {TAG_REMOVE, "remove", \ 4927c478bd9Sstevel@tonic-gate {0x72656d6f, 0x76652020, 0x20202020}}, \ 4937c478bd9Sstevel@tonic-gate {TAG_RENAME, "rename", \ 4947c478bd9Sstevel@tonic-gate {0x72656e61, 0x6d652020, 0x20202020}}, \ 4957c478bd9Sstevel@tonic-gate {TAG_RENAME_VFH, "rename volatile fh", \ 4967c478bd9Sstevel@tonic-gate {0x72656e61, 0x6d652028, 0x76666829}}, \ 4977c478bd9Sstevel@tonic-gate {TAG_RENEW, "renew", \ 4987c478bd9Sstevel@tonic-gate {0x72656e65, 0x77202020, 0x20202020}}, \ 4997c478bd9Sstevel@tonic-gate {TAG_REOPEN, "reopen", \ 5007c478bd9Sstevel@tonic-gate {0x72656f70, 0x656e2020, 0x20202020}}, \ 5017c478bd9Sstevel@tonic-gate {TAG_REOPEN_LOST, "lost reopen", \ 5027c478bd9Sstevel@tonic-gate {0x6c6f7374, 0x2072656f, 0x70656e20}}, \ 5037c478bd9Sstevel@tonic-gate {TAG_SECINFO, "secinfo", \ 5047c478bd9Sstevel@tonic-gate {0x73656369, 0x6e666f20, 0x20202020}}, \ 5057c478bd9Sstevel@tonic-gate {TAG_SETATTR, "setattr", \ 5067c478bd9Sstevel@tonic-gate {0x73657461, 0x74747220, 0x20202020}}, \ 5077c478bd9Sstevel@tonic-gate {TAG_SETCLIENTID, "setclientid", \ 5087c478bd9Sstevel@tonic-gate {0x73657463, 0x6c69656e, 0x74696420}}, \ 5097c478bd9Sstevel@tonic-gate {TAG_SETCLIENTID_CF, "setclientid_confirm", \ 5107c478bd9Sstevel@tonic-gate {0x73636c6e, 0x7469645f, 0x636f6e66}}, \ 5117c478bd9Sstevel@tonic-gate {TAG_SYMLINK, "symlink", \ 5127c478bd9Sstevel@tonic-gate {0x73796d6c, 0x696e6b20, 0x20202020}}, \ 5137c478bd9Sstevel@tonic-gate {TAG_WRITE, "write", \ 5147c478bd9Sstevel@tonic-gate {0x77726974, 0x65202020, 0x20202020}} \ 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * These flags are for differentiating the search criterian for 5197c478bd9Sstevel@tonic-gate * find_open_owner(). The comparison is done with the open_owners's 5207c478bd9Sstevel@tonic-gate * 'oo_just_created' flag. 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate #define NFS4_PERM_CREATED 0x0 5237c478bd9Sstevel@tonic-gate #define NFS4_JUST_CREATED 0x1 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate /* 5267c478bd9Sstevel@tonic-gate * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw' 5277c478bd9Sstevel@tonic-gate * is stored upon a successful OPEN. This is needed when the user's effective 5287c478bd9Sstevel@tonic-gate * and real uid's don't match. The 'oo_cred_otw' overrides the credential 5297c478bd9Sstevel@tonic-gate * passed down by VFS for async read/write, commit, lock, and close operations. 5307c478bd9Sstevel@tonic-gate * 5317c478bd9Sstevel@tonic-gate * The oo_ref_count keeps track the number of active references on this 5327c478bd9Sstevel@tonic-gate * data structure + number of nfs4_open_streams point to this structure. 5337c478bd9Sstevel@tonic-gate * 5347c478bd9Sstevel@tonic-gate * 'oo_valid' tells whether this stuct is about to be freed or not. 5357c478bd9Sstevel@tonic-gate * 5367c478bd9Sstevel@tonic-gate * 'oo_just_created' tells us whether this struct has just been created but 5377c478bd9Sstevel@tonic-gate * not been fully finalized (that is created upon an OPEN request and 5387c478bd9Sstevel@tonic-gate * finalized upon the OPEN success). 5397c478bd9Sstevel@tonic-gate * 5407c478bd9Sstevel@tonic-gate * The 'oo_seqid_inuse' is for the open seqid synchronization. If a thread 5417c478bd9Sstevel@tonic-gate * is currently using the open owner and it's open_seqid, then it sets the 5427c478bd9Sstevel@tonic-gate * oo_seqid_inuse to true if it currently is not set. If it is set then it 5437c478bd9Sstevel@tonic-gate * does a cv_wait on the oo_cv_seqid_sync condition variable. When the thread 5447c478bd9Sstevel@tonic-gate * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process 5457c478bd9Sstevel@tonic-gate * waiting on the condition variable. 5467c478bd9Sstevel@tonic-gate * 5477c478bd9Sstevel@tonic-gate * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW, 5487c478bd9Sstevel@tonic-gate * and 'oo_last_good_op' is the operation that issued the last valid seqid. 5497c478bd9Sstevel@tonic-gate * 5507c478bd9Sstevel@tonic-gate * Lock ordering: 5517c478bd9Sstevel@tonic-gate * mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list) 5527c478bd9Sstevel@tonic-gate * 5537c478bd9Sstevel@tonic-gate * oo_seqid_inuse > mntinfo4_t::mi_lock 5547c478bd9Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statelock 5557c478bd9Sstevel@tonic-gate * oo_seqid_inuse > rnode4_t::r_statev4_lock 5567c478bd9Sstevel@tonic-gate * oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock 5577c478bd9Sstevel@tonic-gate * 5587c478bd9Sstevel@tonic-gate * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects: 5597c478bd9Sstevel@tonic-gate * oo_last_good_op 5607c478bd9Sstevel@tonic-gate * oo_last_good_seqid 5617c478bd9Sstevel@tonic-gate * oo_name 5627c478bd9Sstevel@tonic-gate * oo_seqid 5637c478bd9Sstevel@tonic-gate * 5647c478bd9Sstevel@tonic-gate * The 'oo_lock' protects: 5657c478bd9Sstevel@tonic-gate * oo_cred 5667c478bd9Sstevel@tonic-gate * oo_cred_otw 5677c478bd9Sstevel@tonic-gate * oo_foo_node 5687c478bd9Sstevel@tonic-gate * oo_hash_node 5697c478bd9Sstevel@tonic-gate * oo_just_created 5707c478bd9Sstevel@tonic-gate * oo_ref_count 5717c478bd9Sstevel@tonic-gate * oo_valid 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate typedef struct nfs4_open_owner { 5757c478bd9Sstevel@tonic-gate cred_t *oo_cred; 5767c478bd9Sstevel@tonic-gate int oo_ref_count; 5777c478bd9Sstevel@tonic-gate int oo_valid; 5787c478bd9Sstevel@tonic-gate int oo_just_created; 5797c478bd9Sstevel@tonic-gate seqid4 oo_seqid; 5807c478bd9Sstevel@tonic-gate seqid4 oo_last_good_seqid; 5817c478bd9Sstevel@tonic-gate nfs4_tag_type_t oo_last_good_op; 5827c478bd9Sstevel@tonic-gate unsigned oo_seqid_inuse:1; 5837c478bd9Sstevel@tonic-gate cred_t *oo_cred_otw; 5847c478bd9Sstevel@tonic-gate kcondvar_t oo_cv_seqid_sync; 5857c478bd9Sstevel@tonic-gate /* 5867c478bd9Sstevel@tonic-gate * Fix this to always be 8 bytes 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate uint64_t oo_name; 5897c478bd9Sstevel@tonic-gate list_node_t oo_hash_node; 5907c478bd9Sstevel@tonic-gate list_node_t oo_foo_node; 5917c478bd9Sstevel@tonic-gate kmutex_t oo_lock; 5927c478bd9Sstevel@tonic-gate } nfs4_open_owner_t; 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate /* 5957c478bd9Sstevel@tonic-gate * Static server information. 5962f172c55SRobert Thurlow * These fields are read-only once they are initialized; sv_lock 5972f172c55SRobert Thurlow * should be held as writer if they are changed during mount: 5987c478bd9Sstevel@tonic-gate * sv_addr 5997c478bd9Sstevel@tonic-gate * sv_dhsec 6007c478bd9Sstevel@tonic-gate * sv_hostname 6017c478bd9Sstevel@tonic-gate * sv_hostnamelen 6027c478bd9Sstevel@tonic-gate * sv_knconf 6037c478bd9Sstevel@tonic-gate * sv_next 6047c478bd9Sstevel@tonic-gate * sv_origknconf 6057c478bd9Sstevel@tonic-gate * 6067c478bd9Sstevel@tonic-gate * These fields are protected by sv_lock: 6077c478bd9Sstevel@tonic-gate * sv_currsec 6087c478bd9Sstevel@tonic-gate * sv_fhandle 6097c478bd9Sstevel@tonic-gate * sv_flags 6107c478bd9Sstevel@tonic-gate * sv_fsid 6117c478bd9Sstevel@tonic-gate * sv_path 6127c478bd9Sstevel@tonic-gate * sv_pathlen 6137c478bd9Sstevel@tonic-gate * sv_pfhandle 6147c478bd9Sstevel@tonic-gate * sv_save_secinfo 6157c478bd9Sstevel@tonic-gate * sv_savesec 6167c478bd9Sstevel@tonic-gate * sv_secdata 6177c478bd9Sstevel@tonic-gate * sv_secinfo 6187c478bd9Sstevel@tonic-gate * sv_supp_attrs 6197c478bd9Sstevel@tonic-gate * 6207c478bd9Sstevel@tonic-gate * Lock ordering: 6217c478bd9Sstevel@tonic-gate * nfs_rtable4_lock > sv_lock 6227c478bd9Sstevel@tonic-gate * rnode4_t::r_statelock > sv_lock 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate typedef struct servinfo4 { 6257c478bd9Sstevel@tonic-gate struct knetconfig *sv_knconf; /* bound TLI fd */ 6267c478bd9Sstevel@tonic-gate struct knetconfig *sv_origknconf; /* For RDMA save orig knconf */ 6277c478bd9Sstevel@tonic-gate struct netbuf sv_addr; /* server's address */ 6287c478bd9Sstevel@tonic-gate nfs4_fhandle_t sv_fhandle; /* this server's filehandle */ 6297c478bd9Sstevel@tonic-gate nfs4_fhandle_t sv_pfhandle; /* parent dir filehandle */ 6307c478bd9Sstevel@tonic-gate int sv_pathlen; /* Length of server path */ 6317c478bd9Sstevel@tonic-gate char *sv_path; /* Path name on server */ 6327c478bd9Sstevel@tonic-gate uint32_t sv_flags; /* flags for this server */ 6337c478bd9Sstevel@tonic-gate sec_data_t *sv_secdata; /* client initiated security data */ 6347c478bd9Sstevel@tonic-gate sv_secinfo_t *sv_secinfo; /* server security information */ 6357c478bd9Sstevel@tonic-gate sec_data_t *sv_currsec; /* security data currently used; */ 6367c478bd9Sstevel@tonic-gate /* points to one of the sec_data */ 6377c478bd9Sstevel@tonic-gate /* entries in sv_secinfo */ 6387c478bd9Sstevel@tonic-gate sv_secinfo_t *sv_save_secinfo; /* saved secinfo */ 6397c478bd9Sstevel@tonic-gate sec_data_t *sv_savesec; /* saved security data */ 6407c478bd9Sstevel@tonic-gate sec_data_t *sv_dhsec; /* AUTH_DH data from the user land */ 6417c478bd9Sstevel@tonic-gate char *sv_hostname; /* server's hostname */ 6427c478bd9Sstevel@tonic-gate int sv_hostnamelen; /* server's hostname length */ 6437c478bd9Sstevel@tonic-gate fattr4_fsid sv_fsid; /* fsid of shared obj */ 6447c478bd9Sstevel@tonic-gate fattr4_supported_attrs sv_supp_attrs; 6457c478bd9Sstevel@tonic-gate struct servinfo4 *sv_next; /* next in list */ 6467c478bd9Sstevel@tonic-gate nfs_rwlock_t sv_lock; 6477c478bd9Sstevel@tonic-gate } servinfo4_t; 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate /* sv_flags fields */ 6507c478bd9Sstevel@tonic-gate #define SV4_TRYSECINFO 0x001 /* try secinfo data from the server */ 6517c478bd9Sstevel@tonic-gate #define SV4_TRYSECDEFAULT 0x002 /* try a default flavor */ 6527c478bd9Sstevel@tonic-gate #define SV4_NOTINUSE 0x004 /* servinfo4_t had fatal errors */ 6537c478bd9Sstevel@tonic-gate #define SV4_ROOT_STALE 0x008 /* root vnode got ESTALE */ 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate /* 6567c478bd9Sstevel@tonic-gate * Lock call types. See nfs4frlock(). 6577c478bd9Sstevel@tonic-gate */ 6587c478bd9Sstevel@tonic-gate typedef enum nfs4_lock_call_type { 6597c478bd9Sstevel@tonic-gate NFS4_LCK_CTYPE_NORM, 6607c478bd9Sstevel@tonic-gate NFS4_LCK_CTYPE_RECLAIM, 6617c478bd9Sstevel@tonic-gate NFS4_LCK_CTYPE_RESEND, 6627c478bd9Sstevel@tonic-gate NFS4_LCK_CTYPE_REINSTATE 6637c478bd9Sstevel@tonic-gate } nfs4_lock_call_type_t; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate /* 6667c478bd9Sstevel@tonic-gate * This structure holds the information for a lost open/close/open downgrade/ 6677c478bd9Sstevel@tonic-gate * lock/locku request. It is also used for requests that are queued up so 6687c478bd9Sstevel@tonic-gate * that the recovery thread can release server state after a forced 6697c478bd9Sstevel@tonic-gate * unmount. 6707c478bd9Sstevel@tonic-gate * "lr_op" is 0 if the struct is uninitialized. Otherwise, it is set to 6717c478bd9Sstevel@tonic-gate * the proper OP_* nfs_opnum4 number. The other fields contain information 6727c478bd9Sstevel@tonic-gate * to reconstruct the call. 6737c478bd9Sstevel@tonic-gate * 6747c478bd9Sstevel@tonic-gate * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the 6757c478bd9Sstevel@tonic-gate * parent directroy without relying on vtodv (since we may not have a vp 6767c478bd9Sstevel@tonic-gate * for the file we wish to create). 6777c478bd9Sstevel@tonic-gate * 6787c478bd9Sstevel@tonic-gate * lr_putfirst means that the request should go to the front of the resend 6797c478bd9Sstevel@tonic-gate * queue, rather than the end. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate typedef struct nfs4_lost_rqst { 6827c478bd9Sstevel@tonic-gate list_node_t lr_node; 6837c478bd9Sstevel@tonic-gate nfs_opnum4 lr_op; 6847c478bd9Sstevel@tonic-gate vnode_t *lr_vp; 6857c478bd9Sstevel@tonic-gate vnode_t *lr_dvp; 6867c478bd9Sstevel@tonic-gate nfs4_open_owner_t *lr_oop; 6877c478bd9Sstevel@tonic-gate struct nfs4_open_stream *lr_osp; 6887c478bd9Sstevel@tonic-gate struct nfs4_lock_owner *lr_lop; 6897c478bd9Sstevel@tonic-gate cred_t *lr_cr; 6907c478bd9Sstevel@tonic-gate flock64_t *lr_flk; 6917c478bd9Sstevel@tonic-gate bool_t lr_putfirst; 6927c478bd9Sstevel@tonic-gate union { 6937c478bd9Sstevel@tonic-gate struct { 6947c478bd9Sstevel@tonic-gate nfs4_lock_call_type_t lru_ctype; 6957c478bd9Sstevel@tonic-gate nfs_lock_type4 lru_locktype; 6967c478bd9Sstevel@tonic-gate } lru_lockargs; /* LOCK, LOCKU */ 6977c478bd9Sstevel@tonic-gate struct { 6987c478bd9Sstevel@tonic-gate uint32_t lru_oaccess; 6997c478bd9Sstevel@tonic-gate uint32_t lru_odeny; 7007c478bd9Sstevel@tonic-gate enum open_claim_type4 lru_oclaim; 7017c478bd9Sstevel@tonic-gate stateid4 lru_ostateid; /* reopen only */ 7027c478bd9Sstevel@tonic-gate component4 lru_ofile; 7037c478bd9Sstevel@tonic-gate } lru_open_args; 7047c478bd9Sstevel@tonic-gate struct { 7057c478bd9Sstevel@tonic-gate uint32_t lru_dg_access; 7067c478bd9Sstevel@tonic-gate uint32_t lru_dg_deny; 7077c478bd9Sstevel@tonic-gate } lru_open_dg_args; 7087c478bd9Sstevel@tonic-gate } nfs4_lr_u; 7097c478bd9Sstevel@tonic-gate } nfs4_lost_rqst_t; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate #define lr_oacc nfs4_lr_u.lru_open_args.lru_oaccess 7127c478bd9Sstevel@tonic-gate #define lr_odeny nfs4_lr_u.lru_open_args.lru_odeny 7137c478bd9Sstevel@tonic-gate #define lr_oclaim nfs4_lr_u.lru_open_args.lru_oclaim 7147c478bd9Sstevel@tonic-gate #define lr_ostateid nfs4_lr_u.lru_open_args.lru_ostateid 7157c478bd9Sstevel@tonic-gate #define lr_ofile nfs4_lr_u.lru_open_args.lru_ofile 7167c478bd9Sstevel@tonic-gate #define lr_dg_acc nfs4_lr_u.lru_open_dg_args.lru_dg_access 7177c478bd9Sstevel@tonic-gate #define lr_dg_deny nfs4_lr_u.lru_open_dg_args.lru_dg_deny 7187c478bd9Sstevel@tonic-gate #define lr_ctype nfs4_lr_u.lru_lockargs.lru_ctype 7197c478bd9Sstevel@tonic-gate #define lr_locktype nfs4_lr_u.lru_lockargs.lru_locktype 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate /* 7227c478bd9Sstevel@tonic-gate * Recovery actions. Some actions can imply further recovery using a 7237c478bd9Sstevel@tonic-gate * different recovery action (e.g., recovering the clientid leads to 7247c478bd9Sstevel@tonic-gate * recovering open files and locks). 7257c478bd9Sstevel@tonic-gate */ 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate typedef enum { 7287c478bd9Sstevel@tonic-gate NR_UNUSED, 7297c478bd9Sstevel@tonic-gate NR_CLIENTID, 7307c478bd9Sstevel@tonic-gate NR_OPENFILES, 7317c478bd9Sstevel@tonic-gate NR_FHEXPIRED, 7327c478bd9Sstevel@tonic-gate NR_FAILOVER, 7337c478bd9Sstevel@tonic-gate NR_WRONGSEC, 7347c478bd9Sstevel@tonic-gate NR_EXPIRED, 7357c478bd9Sstevel@tonic-gate NR_BAD_STATEID, 7367c478bd9Sstevel@tonic-gate NR_BADHANDLE, 7377c478bd9Sstevel@tonic-gate NR_BAD_SEQID, 7387c478bd9Sstevel@tonic-gate NR_OLDSTATEID, 7397c478bd9Sstevel@tonic-gate NR_GRACE, 7407c478bd9Sstevel@tonic-gate NR_DELAY, 7417c478bd9Sstevel@tonic-gate NR_LOST_LOCK, 7427c478bd9Sstevel@tonic-gate NR_LOST_STATE_RQST, 7432f172c55SRobert Thurlow NR_STALE, 7442f172c55SRobert Thurlow NR_MOVED 7457c478bd9Sstevel@tonic-gate } nfs4_recov_t; 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate /* 7487c478bd9Sstevel@tonic-gate * Administrative and debug message framework. 7497c478bd9Sstevel@tonic-gate */ 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate #define NFS4_MSG_MAX 100 7527c478bd9Sstevel@tonic-gate extern int nfs4_msg_max; 7537c478bd9Sstevel@tonic-gate 7542f172c55SRobert Thurlow #define NFS4_REFERRAL_LOOP_MAX 20 7552f172c55SRobert Thurlow 7567c478bd9Sstevel@tonic-gate typedef enum { 7577c478bd9Sstevel@tonic-gate RE_BAD_SEQID, 7587c478bd9Sstevel@tonic-gate RE_BADHANDLE, 7597c478bd9Sstevel@tonic-gate RE_CLIENTID, 7607c478bd9Sstevel@tonic-gate RE_DEAD_FILE, 7617c478bd9Sstevel@tonic-gate RE_END, 7627c478bd9Sstevel@tonic-gate RE_FAIL_RELOCK, 7637c478bd9Sstevel@tonic-gate RE_FAIL_REMAP_LEN, 7647c478bd9Sstevel@tonic-gate RE_FAIL_REMAP_OP, 7657c478bd9Sstevel@tonic-gate RE_FAILOVER, 7667c478bd9Sstevel@tonic-gate RE_FILE_DIFF, 7677c478bd9Sstevel@tonic-gate RE_LOST_STATE, 7687c478bd9Sstevel@tonic-gate RE_OPENS_CHANGED, 7697c478bd9Sstevel@tonic-gate RE_SIGLOST, 7707c478bd9Sstevel@tonic-gate RE_SIGLOST_NO_DUMP, 7717c478bd9Sstevel@tonic-gate RE_START, 7727c478bd9Sstevel@tonic-gate RE_UNEXPECTED_ACTION, 7737c478bd9Sstevel@tonic-gate RE_UNEXPECTED_ERRNO, 7747c478bd9Sstevel@tonic-gate RE_UNEXPECTED_STATUS, 7757c478bd9Sstevel@tonic-gate RE_WRONGSEC, 7762f172c55SRobert Thurlow RE_LOST_STATE_BAD_OP, 7772f172c55SRobert Thurlow RE_REFERRAL 7787c478bd9Sstevel@tonic-gate } nfs4_event_type_t; 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate typedef enum { 7817c478bd9Sstevel@tonic-gate RFS_NO_INSPECT, 7827c478bd9Sstevel@tonic-gate RFS_INSPECT 7837c478bd9Sstevel@tonic-gate } nfs4_fact_status_t; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate typedef enum { 7867c478bd9Sstevel@tonic-gate RF_BADOWNER, 7877c478bd9Sstevel@tonic-gate RF_ERR, 7887c478bd9Sstevel@tonic-gate RF_RENEW_EXPIRED, 7897c478bd9Sstevel@tonic-gate RF_SRV_NOT_RESPOND, 7907c478bd9Sstevel@tonic-gate RF_SRV_OK, 7917c478bd9Sstevel@tonic-gate RF_SRVS_NOT_RESPOND, 7927c478bd9Sstevel@tonic-gate RF_SRVS_OK, 793e280ed37SDai Ngo RF_DELMAP_CB_ERR, 794e280ed37SDai Ngo RF_SENDQ_FULL 7957c478bd9Sstevel@tonic-gate } nfs4_fact_type_t; 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate typedef enum { 7987c478bd9Sstevel@tonic-gate NFS4_MS_DUMP, 7997c478bd9Sstevel@tonic-gate NFS4_MS_NO_DUMP 8007c478bd9Sstevel@tonic-gate } nfs4_msg_status_t; 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate typedef struct nfs4_rfact { 8037c478bd9Sstevel@tonic-gate nfs4_fact_type_t rf_type; 8047c478bd9Sstevel@tonic-gate nfs4_fact_status_t rf_status; 8057c478bd9Sstevel@tonic-gate bool_t rf_reboot; 8067c478bd9Sstevel@tonic-gate nfs4_recov_t rf_action; 8077c478bd9Sstevel@tonic-gate nfs_opnum4 rf_op; 8087c478bd9Sstevel@tonic-gate nfsstat4 rf_stat4; 8097c478bd9Sstevel@tonic-gate timespec_t rf_time; 8107c478bd9Sstevel@tonic-gate int rf_error; 8117c478bd9Sstevel@tonic-gate struct rnode4 *rf_rp1; 8127c478bd9Sstevel@tonic-gate char *rf_char1; 8137c478bd9Sstevel@tonic-gate } nfs4_rfact_t; 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate typedef struct nfs4_revent { 8167c478bd9Sstevel@tonic-gate nfs4_event_type_t re_type; 8177c478bd9Sstevel@tonic-gate nfsstat4 re_stat4; 8187c478bd9Sstevel@tonic-gate uint_t re_uint; 8197c478bd9Sstevel@tonic-gate pid_t re_pid; 8207c478bd9Sstevel@tonic-gate struct mntinfo4 *re_mi; 8217c478bd9Sstevel@tonic-gate struct rnode4 *re_rp1; 8227c478bd9Sstevel@tonic-gate struct rnode4 *re_rp2; 8237c478bd9Sstevel@tonic-gate char *re_char1; 8247c478bd9Sstevel@tonic-gate char *re_char2; 8257c478bd9Sstevel@tonic-gate nfs4_tag_type_t re_tag1; 8267c478bd9Sstevel@tonic-gate nfs4_tag_type_t re_tag2; 8277c478bd9Sstevel@tonic-gate seqid4 re_seqid1; 8287c478bd9Sstevel@tonic-gate seqid4 re_seqid2; 8297c478bd9Sstevel@tonic-gate } nfs4_revent_t; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate typedef enum { 8327c478bd9Sstevel@tonic-gate RM_EVENT, 8337c478bd9Sstevel@tonic-gate RM_FACT 8347c478bd9Sstevel@tonic-gate } nfs4_msg_type_t; 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate typedef struct nfs4_debug_msg { 8377c478bd9Sstevel@tonic-gate timespec_t msg_time; 8387c478bd9Sstevel@tonic-gate nfs4_msg_type_t msg_type; 8397c478bd9Sstevel@tonic-gate char *msg_srv; 8407c478bd9Sstevel@tonic-gate char *msg_mntpt; 8417c478bd9Sstevel@tonic-gate union { 8427c478bd9Sstevel@tonic-gate nfs4_rfact_t msg_fact; 8437c478bd9Sstevel@tonic-gate nfs4_revent_t msg_event; 8447c478bd9Sstevel@tonic-gate } rmsg_u; 8457c478bd9Sstevel@tonic-gate nfs4_msg_status_t msg_status; 8467c478bd9Sstevel@tonic-gate list_node_t msg_node; 8477c478bd9Sstevel@tonic-gate } nfs4_debug_msg_t; 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate /* 8507c478bd9Sstevel@tonic-gate * NFS private data per mounted file system 8517c478bd9Sstevel@tonic-gate * The mi_lock mutex protects the following fields: 8527c478bd9Sstevel@tonic-gate * mi_flags 8537c478bd9Sstevel@tonic-gate * mi_in_recovery 8547c478bd9Sstevel@tonic-gate * mi_recovflags 8557c478bd9Sstevel@tonic-gate * mi_recovthread 8567c478bd9Sstevel@tonic-gate * mi_error 8577c478bd9Sstevel@tonic-gate * mi_printed 8587c478bd9Sstevel@tonic-gate * mi_down 8597c478bd9Sstevel@tonic-gate * mi_stsize 8607c478bd9Sstevel@tonic-gate * mi_curread 8617c478bd9Sstevel@tonic-gate * mi_curwrite 8627c478bd9Sstevel@tonic-gate * mi_timers 8637c478bd9Sstevel@tonic-gate * mi_curr_serv 8647c478bd9Sstevel@tonic-gate * mi_klmconfig 8657c478bd9Sstevel@tonic-gate * mi_oo_list 8667c478bd9Sstevel@tonic-gate * mi_foo_list 8677c478bd9Sstevel@tonic-gate * mi_foo_num 8687c478bd9Sstevel@tonic-gate * mi_foo_max 8697c478bd9Sstevel@tonic-gate * mi_lost_state 8707c478bd9Sstevel@tonic-gate * mi_bseqid_list 871b9238976Sth199096 * mi_ephemeral 872b9238976Sth199096 * mi_ephemeral_tree 8737c478bd9Sstevel@tonic-gate * 8747c478bd9Sstevel@tonic-gate * Normally the netconfig information for the mount comes from 8757c478bd9Sstevel@tonic-gate * mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a 8767c478bd9Sstevel@tonic-gate * different transport, mi_klmconfig contains the necessary netconfig 8777c478bd9Sstevel@tonic-gate * information. 8787c478bd9Sstevel@tonic-gate * 8797c478bd9Sstevel@tonic-gate * The mi_async_lock mutex protects the following fields: 8807c478bd9Sstevel@tonic-gate * mi_async_reqs 8817c478bd9Sstevel@tonic-gate * mi_async_req_count 8827c478bd9Sstevel@tonic-gate * mi_async_tail 8830776f5e6SVallish Vaidyeshwara * mi_async_curr[NFS4_MAX_ASYNC_QUEUES] 8847c478bd9Sstevel@tonic-gate * mi_async_clusters 8857c478bd9Sstevel@tonic-gate * mi_async_init_clusters 8860776f5e6SVallish Vaidyeshwara * mi_threads[NFS4_MAX_ASYNC_QUEUES] 8877c478bd9Sstevel@tonic-gate * mi_inactive_thread 8887c478bd9Sstevel@tonic-gate * mi_manager_thread 8897c478bd9Sstevel@tonic-gate * 8907c478bd9Sstevel@tonic-gate * The nfs4_server_t::s_lock protects the following fields: 8917c478bd9Sstevel@tonic-gate * mi_clientid 8927c478bd9Sstevel@tonic-gate * mi_clientid_next 8937c478bd9Sstevel@tonic-gate * mi_clientid_prev 8947c478bd9Sstevel@tonic-gate * mi_open_files 8957c478bd9Sstevel@tonic-gate * 896a092743bSek110237 * The mntinfo4_t::mi_recovlock protects the following fields: 897a092743bSek110237 * mi_srvsettime 8983b895386SPavel Filipensky * mi_srvset_cnt 8993b895386SPavel Filipensky * mi_srv 9003b895386SPavel Filipensky * 9013b895386SPavel Filipensky * Changing mi_srv from one nfs4_server_t to a different one requires 9023b895386SPavel Filipensky * holding the mi_recovlock as RW_WRITER. 9033b895386SPavel Filipensky * Exception: setting mi_srv the first time in mount/mountroot is done 9043b895386SPavel Filipensky * holding the mi_recovlock as RW_READER. 905a092743bSek110237 * 9067c478bd9Sstevel@tonic-gate * Locking order: 9077c478bd9Sstevel@tonic-gate * mi4_globals::mig_lock > mi_async_lock 9087c478bd9Sstevel@tonic-gate * mi_async_lock > nfs4_server_t::s_lock > mi_lock 9097c478bd9Sstevel@tonic-gate * mi_recovlock > mi_rename_lock > nfs_rtable4_lock 9107c478bd9Sstevel@tonic-gate * nfs4_server_t::s_recovlock > mi_recovlock 9117c478bd9Sstevel@tonic-gate * rnode4_t::r_rwlock > mi_rename_lock 9127c478bd9Sstevel@tonic-gate * nfs_rtable4_lock > mi_lock 9137c478bd9Sstevel@tonic-gate * nfs4_server_t::s_lock > mi_msg_list_lock 914a092743bSek110237 * mi_recovlock > nfs4_server_t::s_lock 915a092743bSek110237 * mi_recovlock > nfs4_server_lst_lock 9167c478bd9Sstevel@tonic-gate * 9177c478bd9Sstevel@tonic-gate * The 'mi_oo_list' represents the hash buckets that contain the 9187c478bd9Sstevel@tonic-gate * nfs4_open_owenrs for this particular mntinfo4. 9197c478bd9Sstevel@tonic-gate * 9207c478bd9Sstevel@tonic-gate * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4. 9217c478bd9Sstevel@tonic-gate * 'mi_foo_num' is the current number of freed open owners on the list, 9227c478bd9Sstevel@tonic-gate * 'mi_foo_max' is the maximum number of freed open owners that are allowable 9237c478bd9Sstevel@tonic-gate * on the list. 9247c478bd9Sstevel@tonic-gate * 9257c478bd9Sstevel@tonic-gate * mi_rootfh and mi_srvparentfh are read-only once created, but that just 9267c478bd9Sstevel@tonic-gate * refers to the pointer. The contents must be updated to keep in sync 9277c478bd9Sstevel@tonic-gate * with mi_curr_serv. 9287c478bd9Sstevel@tonic-gate * 9297c478bd9Sstevel@tonic-gate * The mi_msg_list_lock protects against adding/deleting entries to the 9307c478bd9Sstevel@tonic-gate * mi_msg_list, and also the updating/retrieving of mi_lease_period; 9317c478bd9Sstevel@tonic-gate * 9327c478bd9Sstevel@tonic-gate * 'mi_zone' is initialized at structure creation time, and never 9337c478bd9Sstevel@tonic-gate * changes; it may be read without a lock. 9347c478bd9Sstevel@tonic-gate * 9357c478bd9Sstevel@tonic-gate * mi_zone_node is linkage into the mi4_globals.mig_list, and is 9367c478bd9Sstevel@tonic-gate * protected by mi4_globals.mig_list_lock. 937b9238976Sth199096 * 938b9238976Sth199096 * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an 939b9238976Sth199096 * ephemeral structure for this ephemeral mount point. It can not be 940b9238976Sth199096 * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral 941b9238976Sth199096 * tree. 942b9238976Sth199096 * 943b9238976Sth199096 * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has 944b9238976Sth199096 * to be NULL. If mi_ephemeral_tree is non-NULL, then this node 945b9238976Sth199096 * is the enclosing mntinfo4 for the ephemeral tree. 9467c478bd9Sstevel@tonic-gate */ 9477c478bd9Sstevel@tonic-gate struct zone; 948b9238976Sth199096 struct nfs4_ephemeral; 949b9238976Sth199096 struct nfs4_ephemeral_tree; 9503b895386SPavel Filipensky struct nfs4_server; 9517c478bd9Sstevel@tonic-gate typedef struct mntinfo4 { 9527c478bd9Sstevel@tonic-gate kmutex_t mi_lock; /* protects mntinfo4 fields */ 9537c478bd9Sstevel@tonic-gate struct servinfo4 *mi_servers; /* server list */ 9547c478bd9Sstevel@tonic-gate struct servinfo4 *mi_curr_serv; /* current server */ 9557c478bd9Sstevel@tonic-gate struct nfs4_sharedfh *mi_rootfh; /* root filehandle */ 9567c478bd9Sstevel@tonic-gate struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */ 9577c478bd9Sstevel@tonic-gate kcondvar_t mi_failover_cv; /* failover synchronization */ 9587c478bd9Sstevel@tonic-gate struct vfs *mi_vfsp; /* back pointer to vfs */ 9597c478bd9Sstevel@tonic-gate enum vtype mi_type; /* file type of the root vnode */ 9607c478bd9Sstevel@tonic-gate uint_t mi_flags; /* see below */ 9617c478bd9Sstevel@tonic-gate uint_t mi_recovflags; /* if recovery active; see below */ 9627c478bd9Sstevel@tonic-gate kthread_t *mi_recovthread; /* active recov thread or NULL */ 9637c478bd9Sstevel@tonic-gate uint_t mi_error; /* only set/valid when MI4_RECOV_FAIL */ 9647c478bd9Sstevel@tonic-gate /* is set in mi_flags */ 9657c478bd9Sstevel@tonic-gate int mi_tsize; /* transfer size (bytes) */ 9667c478bd9Sstevel@tonic-gate /* really read size */ 9677c478bd9Sstevel@tonic-gate int mi_stsize; /* server's max transfer size (bytes) */ 9687c478bd9Sstevel@tonic-gate /* really write size */ 9697c478bd9Sstevel@tonic-gate int mi_timeo; /* inital timeout in 10th sec */ 9707c478bd9Sstevel@tonic-gate int mi_retrans; /* times to retry request */ 9717c478bd9Sstevel@tonic-gate hrtime_t mi_acregmin; /* min time to hold cached file attr */ 9727c478bd9Sstevel@tonic-gate hrtime_t mi_acregmax; /* max time to hold cached file attr */ 9737c478bd9Sstevel@tonic-gate hrtime_t mi_acdirmin; /* min time to hold cached dir attr */ 9747c478bd9Sstevel@tonic-gate hrtime_t mi_acdirmax; /* max time to hold cached dir attr */ 9757c478bd9Sstevel@tonic-gate len_t mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */ 9767c478bd9Sstevel@tonic-gate int mi_curread; /* current read size */ 9777c478bd9Sstevel@tonic-gate int mi_curwrite; /* current write size */ 97850a83466Sjwahlig uint_t mi_count; /* ref count */ 9797c478bd9Sstevel@tonic-gate /* 9800776f5e6SVallish Vaidyeshwara * Async I/O management 9810776f5e6SVallish Vaidyeshwara * We have 2 pools of threads working on async I/O: 9820776f5e6SVallish Vaidyeshwara * (1) Threads which work on all async queues. Default number of 9830776f5e6SVallish Vaidyeshwara * threads in this queue is 8. Threads in this pool work on async 9840776f5e6SVallish Vaidyeshwara * queue pointed by mi_async_curr[NFS4_ASYNC_QUEUE]. Number of 9850776f5e6SVallish Vaidyeshwara * active threads in this pool is tracked by 9860776f5e6SVallish Vaidyeshwara * mi_threads[NFS4_ASYNC_QUEUE]. 98781d2f16dSMarcel Telka * (2) Threads which work only on page op async queues. 9880776f5e6SVallish Vaidyeshwara * Page ops queue comprises of NFS4_PUTAPAGE, NFS4_PAGEIO & 9890776f5e6SVallish Vaidyeshwara * NFS4_COMMIT. Default number of threads in this queue is 2 9900776f5e6SVallish Vaidyeshwara * (NUM_ASYNC_PGOPS_THREADS). Threads in this pool work on async 9910776f5e6SVallish Vaidyeshwara * queue pointed by mi_async_curr[NFS4_ASYNC_PGOPS_QUEUE]. Number 9920776f5e6SVallish Vaidyeshwara * of active threads in this pool is tracked by 9930776f5e6SVallish Vaidyeshwara * mi_threads[NFS4_ASYNC_PGOPS_QUEUE]. 9940776f5e6SVallish Vaidyeshwara * 9950776f5e6SVallish Vaidyeshwara * In addition to above two pools, there is always one thread that 9960776f5e6SVallish Vaidyeshwara * handles over-the-wire requests for VOP_INACTIVE. 9977c478bd9Sstevel@tonic-gate */ 9987c478bd9Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES]; 9997c478bd9Sstevel@tonic-gate struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES]; 10000776f5e6SVallish Vaidyeshwara struct nfs4_async_reqs **mi_async_curr[NFS4_MAX_ASYNC_QUEUES]; 10010776f5e6SVallish Vaidyeshwara /* current async queue */ 10027c478bd9Sstevel@tonic-gate uint_t mi_async_clusters[NFS4_ASYNC_TYPES]; 10037c478bd9Sstevel@tonic-gate uint_t mi_async_init_clusters; 10047c478bd9Sstevel@tonic-gate uint_t mi_async_req_count; /* # outstanding work requests */ 10057c478bd9Sstevel@tonic-gate kcondvar_t mi_async_reqs_cv; /* signaled when there's work */ 10060776f5e6SVallish Vaidyeshwara ushort_t mi_threads[NFS4_MAX_ASYNC_QUEUES]; 10070776f5e6SVallish Vaidyeshwara /* number of active async threads */ 10087c478bd9Sstevel@tonic-gate ushort_t mi_max_threads; /* max number of async threads */ 10097c478bd9Sstevel@tonic-gate kthread_t *mi_manager_thread; /* async manager thread id */ 10107c478bd9Sstevel@tonic-gate kthread_t *mi_inactive_thread; /* inactive thread id */ 10117c478bd9Sstevel@tonic-gate kcondvar_t mi_inact_req_cv; /* notify VOP_INACTIVE thread */ 10120776f5e6SVallish Vaidyeshwara kcondvar_t mi_async_work_cv[NFS4_MAX_ASYNC_QUEUES]; 10130776f5e6SVallish Vaidyeshwara /* tell workers to work */ 10147c478bd9Sstevel@tonic-gate kcondvar_t mi_async_cv; /* all pool threads exited */ 10157c478bd9Sstevel@tonic-gate kmutex_t mi_async_lock; 10167c478bd9Sstevel@tonic-gate /* 10177c478bd9Sstevel@tonic-gate * Other stuff 10187c478bd9Sstevel@tonic-gate */ 10197c478bd9Sstevel@tonic-gate struct pathcnf *mi_pathconf; /* static pathconf kludge */ 10207c478bd9Sstevel@tonic-gate rpcprog_t mi_prog; /* RPC program number */ 10217c478bd9Sstevel@tonic-gate rpcvers_t mi_vers; /* RPC program version number */ 10227c478bd9Sstevel@tonic-gate char **mi_rfsnames; /* mapping to proc names */ 10237c478bd9Sstevel@tonic-gate kstat_named_t *mi_reqs; /* count of requests */ 10247c478bd9Sstevel@tonic-gate clock_t mi_printftime; /* last error printf time */ 10257c478bd9Sstevel@tonic-gate nfs_rwlock_t mi_recovlock; /* separate ops from recovery (v4) */ 10267c478bd9Sstevel@tonic-gate time_t mi_grace_wait; /* non-zero represents time to wait */ 10273b895386SPavel Filipensky /* when we switched nfs4_server_t - only for observability purposes */ 10283b895386SPavel Filipensky time_t mi_srvsettime; 10297c478bd9Sstevel@tonic-gate nfs_rwlock_t mi_rename_lock; /* atomic volfh rename */ 10307c478bd9Sstevel@tonic-gate struct nfs4_fname *mi_fname; /* root fname */ 10317c478bd9Sstevel@tonic-gate list_t mi_lost_state; /* resend list */ 10327c478bd9Sstevel@tonic-gate list_t mi_bseqid_list; /* bad seqid list */ 10337c478bd9Sstevel@tonic-gate /* 10347c478bd9Sstevel@tonic-gate * Client Side Failover stats 10357c478bd9Sstevel@tonic-gate */ 10367c478bd9Sstevel@tonic-gate uint_t mi_noresponse; /* server not responding count */ 10377c478bd9Sstevel@tonic-gate uint_t mi_failover; /* failover to new server count */ 10387c478bd9Sstevel@tonic-gate uint_t mi_remap; /* remap to new server count */ 10397c478bd9Sstevel@tonic-gate /* 10407c478bd9Sstevel@tonic-gate * Kstat statistics 10417c478bd9Sstevel@tonic-gate */ 10427c478bd9Sstevel@tonic-gate struct kstat *mi_io_kstats; 10437c478bd9Sstevel@tonic-gate struct kstat *mi_ro_kstats; 10447c478bd9Sstevel@tonic-gate kstat_t *mi_recov_ksp; /* ptr to the recovery kstat */ 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate /* 10477c478bd9Sstevel@tonic-gate * Volatile fh flags (nfsv4) 10487c478bd9Sstevel@tonic-gate */ 10497c478bd9Sstevel@tonic-gate uint32_t mi_fh_expire_type; 10507c478bd9Sstevel@tonic-gate /* 10517c478bd9Sstevel@tonic-gate * Lease Management 10527c478bd9Sstevel@tonic-gate */ 10537c478bd9Sstevel@tonic-gate struct mntinfo4 *mi_clientid_next; 10547c478bd9Sstevel@tonic-gate struct mntinfo4 *mi_clientid_prev; 10557c478bd9Sstevel@tonic-gate clientid4 mi_clientid; /* redundant info found in nfs4_server */ 10567c478bd9Sstevel@tonic-gate int mi_open_files; /* count of open files */ 10577c478bd9Sstevel@tonic-gate int mi_in_recovery; /* count of recovery instances */ 10587c478bd9Sstevel@tonic-gate kcondvar_t mi_cv_in_recov; /* cv for recovery threads */ 10597c478bd9Sstevel@tonic-gate /* 10607c478bd9Sstevel@tonic-gate * Open owner stuff. 10617c478bd9Sstevel@tonic-gate */ 10627c478bd9Sstevel@tonic-gate struct nfs4_oo_hash_bucket mi_oo_list[NFS4_NUM_OO_BUCKETS]; 10637c478bd9Sstevel@tonic-gate list_t mi_foo_list; 10647c478bd9Sstevel@tonic-gate int mi_foo_num; 10657c478bd9Sstevel@tonic-gate int mi_foo_max; 10667c478bd9Sstevel@tonic-gate /* 10677c478bd9Sstevel@tonic-gate * Shared filehandle pool. 10687c478bd9Sstevel@tonic-gate */ 10697c478bd9Sstevel@tonic-gate nfs_rwlock_t mi_fh_lock; 10707c478bd9Sstevel@tonic-gate avl_tree_t mi_filehandles; 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate /* 10737c478bd9Sstevel@tonic-gate * Debug message queue. 10747c478bd9Sstevel@tonic-gate */ 10757c478bd9Sstevel@tonic-gate list_t mi_msg_list; 10767c478bd9Sstevel@tonic-gate int mi_msg_count; 10777c478bd9Sstevel@tonic-gate time_t mi_lease_period; 10787c478bd9Sstevel@tonic-gate /* 10797c478bd9Sstevel@tonic-gate * not guaranteed to be accurate. 10807c478bd9Sstevel@tonic-gate * only should be used by debug queue. 10817c478bd9Sstevel@tonic-gate */ 10827c478bd9Sstevel@tonic-gate kmutex_t mi_msg_list_lock; 10837c478bd9Sstevel@tonic-gate /* 10847c478bd9Sstevel@tonic-gate * Zones support. 10857c478bd9Sstevel@tonic-gate */ 1086a19609f8Sjv227347 struct zone *mi_zone; /* Zone in which FS is mounted */ 1087a19609f8Sjv227347 zone_ref_t mi_zone_ref; /* Reference to aforementioned zone */ 10887c478bd9Sstevel@tonic-gate list_node_t mi_zone_node; /* linkage into per-zone mi list */ 1089b9238976Sth199096 1090b9238976Sth199096 /* 1091b9238976Sth199096 * Links for unmounting ephemeral mounts. 1092b9238976Sth199096 */ 1093b9238976Sth199096 struct nfs4_ephemeral *mi_ephemeral; 1094b9238976Sth199096 struct nfs4_ephemeral_tree *mi_ephemeral_tree; 10953b895386SPavel Filipensky 10963b895386SPavel Filipensky uint_t mi_srvset_cnt; /* increment when changing the nfs4_server_t */ 10973b895386SPavel Filipensky struct nfs4_server *mi_srv; /* backpointer to nfs4_server_t */ 10982f172c55SRobert Thurlow /* 10992f172c55SRobert Thurlow * Referral related info. 11002f172c55SRobert Thurlow */ 11012f172c55SRobert Thurlow int mi_vfs_referral_loop_cnt; 11028a790dc6SMarcel Telka /* 11038a790dc6SMarcel Telka * List of rnode4_t structures that belongs to this mntinfo4 11048a790dc6SMarcel Telka */ 11058a790dc6SMarcel Telka kmutex_t mi_rnodes_lock; /* protects the mi_rnodes list */ 11068a790dc6SMarcel Telka list_t mi_rnodes; /* the list */ 11077c478bd9Sstevel@tonic-gate } mntinfo4_t; 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate /* 11107c478bd9Sstevel@tonic-gate * The values for mi_flags. 11117c478bd9Sstevel@tonic-gate * 11127c478bd9Sstevel@tonic-gate * MI4_HARD hard or soft mount 11137c478bd9Sstevel@tonic-gate * MI4_PRINTED responding message printed 11147c478bd9Sstevel@tonic-gate * MI4_INT allow INTR on hard mount 11157c478bd9Sstevel@tonic-gate * MI4_DOWN server is down 11167c478bd9Sstevel@tonic-gate * MI4_NOAC don't cache attributes 11177c478bd9Sstevel@tonic-gate * MI4_NOCTO no close-to-open consistency 11187c478bd9Sstevel@tonic-gate * MI4_LLOCK local locking only (no lockmgr) 11197c478bd9Sstevel@tonic-gate * MI4_GRPID System V group id inheritance 11207c478bd9Sstevel@tonic-gate * MI4_SHUTDOWN System is rebooting or shutting down 11217c478bd9Sstevel@tonic-gate * MI4_LINK server supports link 11227c478bd9Sstevel@tonic-gate * MI4_SYMLINK server supports symlink 1123b9238976Sth199096 * MI4_EPHEMERAL_RECURSED an ephemeral mount being unmounted 1124b9238976Sth199096 * due to a recursive call - no need 1125b9238976Sth199096 * for additional recursion 11267c478bd9Sstevel@tonic-gate * MI4_ACL server supports NFSv4 ACLs 1127b9238976Sth199096 * MI4_MIRRORMOUNT is a mirrormount 11287c478bd9Sstevel@tonic-gate * MI4_NOPRINT don't print messages 11297c478bd9Sstevel@tonic-gate * MI4_DIRECTIO do direct I/O 11307c478bd9Sstevel@tonic-gate * MI4_RECOV_ACTIV filesystem has recovery a thread 11317c478bd9Sstevel@tonic-gate * MI4_REMOVE_ON_LAST_CLOSE remove from server's list 11327c478bd9Sstevel@tonic-gate * MI4_RECOV_FAIL client recovery failed 11337c478bd9Sstevel@tonic-gate * MI4_PUBLIC public/url option used 11347c478bd9Sstevel@tonic-gate * MI4_MOUNTING mount in progress, don't failover 11357c478bd9Sstevel@tonic-gate * MI4_POSIX_LOCK if server is using POSIX locking 11367c478bd9Sstevel@tonic-gate * MI4_LOCK_DEBUG cmn_err'd posix lock err msg 113750a83466Sjwahlig * MI4_DEAD zone has released it 11387c478bd9Sstevel@tonic-gate * MI4_INACTIVE_IDLE inactive thread idle 11397c478bd9Sstevel@tonic-gate * MI4_BADOWNER_DEBUG badowner error msg per mount 11407c478bd9Sstevel@tonic-gate * MI4_ASYNC_MGR_STOP tell async manager to die 11417c478bd9Sstevel@tonic-gate * MI4_TIMEDOUT saw a timeout during zone shutdown 1142b9238976Sth199096 * MI4_EPHEMERAL is an ephemeral mount 11437c478bd9Sstevel@tonic-gate */ 11447c478bd9Sstevel@tonic-gate #define MI4_HARD 0x1 11457c478bd9Sstevel@tonic-gate #define MI4_PRINTED 0x2 11467c478bd9Sstevel@tonic-gate #define MI4_INT 0x4 11477c478bd9Sstevel@tonic-gate #define MI4_DOWN 0x8 11487c478bd9Sstevel@tonic-gate #define MI4_NOAC 0x10 11497c478bd9Sstevel@tonic-gate #define MI4_NOCTO 0x20 11507c478bd9Sstevel@tonic-gate #define MI4_LLOCK 0x80 11517c478bd9Sstevel@tonic-gate #define MI4_GRPID 0x100 11527c478bd9Sstevel@tonic-gate #define MI4_SHUTDOWN 0x200 11537c478bd9Sstevel@tonic-gate #define MI4_LINK 0x400 11547c478bd9Sstevel@tonic-gate #define MI4_SYMLINK 0x800 1155b9238976Sth199096 #define MI4_EPHEMERAL_RECURSED 0x1000 11567c478bd9Sstevel@tonic-gate #define MI4_ACL 0x2000 1157b9238976Sth199096 /* MI4_MIRRORMOUNT is also defined in nfsstat.c */ 1158b9238976Sth199096 #define MI4_MIRRORMOUNT 0x4000 11592f172c55SRobert Thurlow #define MI4_REFERRAL 0x8000 11607c478bd9Sstevel@tonic-gate /* 0x10000 is available */ 11617c478bd9Sstevel@tonic-gate #define MI4_NOPRINT 0x20000 11627c478bd9Sstevel@tonic-gate #define MI4_DIRECTIO 0x40000 11637c478bd9Sstevel@tonic-gate /* 0x80000 is available */ 11647c478bd9Sstevel@tonic-gate #define MI4_RECOV_ACTIV 0x100000 11657c478bd9Sstevel@tonic-gate #define MI4_REMOVE_ON_LAST_CLOSE 0x200000 11667c478bd9Sstevel@tonic-gate #define MI4_RECOV_FAIL 0x400000 11677c478bd9Sstevel@tonic-gate #define MI4_PUBLIC 0x800000 11687c478bd9Sstevel@tonic-gate #define MI4_MOUNTING 0x1000000 11697c478bd9Sstevel@tonic-gate #define MI4_POSIX_LOCK 0x2000000 11707c478bd9Sstevel@tonic-gate #define MI4_LOCK_DEBUG 0x4000000 11717c478bd9Sstevel@tonic-gate #define MI4_DEAD 0x8000000 11727c478bd9Sstevel@tonic-gate #define MI4_INACTIVE_IDLE 0x10000000 11737c478bd9Sstevel@tonic-gate #define MI4_BADOWNER_DEBUG 0x20000000 11747c478bd9Sstevel@tonic-gate #define MI4_ASYNC_MGR_STOP 0x40000000 11757c478bd9Sstevel@tonic-gate #define MI4_TIMEDOUT 0x80000000 11767c478bd9Sstevel@tonic-gate 11772f172c55SRobert Thurlow #define MI4_EPHEMERAL (MI4_MIRRORMOUNT | MI4_REFERRAL) 1178b9238976Sth199096 11797c478bd9Sstevel@tonic-gate #define INTR4(vp) (VTOMI4(vp)->mi_flags & MI4_INT) 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate #define FAILOVER_MOUNT4(mi) (mi->mi_servers->sv_next) 11827c478bd9Sstevel@tonic-gate 11837c478bd9Sstevel@tonic-gate /* 11847c478bd9Sstevel@tonic-gate * Recovery flags. 11857c478bd9Sstevel@tonic-gate * 11867c478bd9Sstevel@tonic-gate * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag 11877c478bd9Sstevel@tonic-gate * that's important), but some flag is needed to indicate that recovery is 11887c478bd9Sstevel@tonic-gate * going on for the filesystem. 11897c478bd9Sstevel@tonic-gate */ 11907c478bd9Sstevel@tonic-gate #define MI4R_NEED_CLIENTID 0x1 11917c478bd9Sstevel@tonic-gate #define MI4R_REOPEN_FILES 0x2 11927c478bd9Sstevel@tonic-gate #define MI4R_NEED_SECINFO 0x4 11937c478bd9Sstevel@tonic-gate #define MI4R_NEED_NEW_SERVER 0x8 11947c478bd9Sstevel@tonic-gate #define MI4R_REMAP_FILES 0x10 11957c478bd9Sstevel@tonic-gate #define MI4R_SRV_REBOOT 0x20 /* server has rebooted */ 11967c478bd9Sstevel@tonic-gate #define MI4R_LOST_STATE 0x40 11977c478bd9Sstevel@tonic-gate #define MI4R_BAD_SEQID 0x80 11982f172c55SRobert Thurlow #define MI4R_MOVED 0x100 11997c478bd9Sstevel@tonic-gate 120050a83466Sjwahlig #define MI4_HOLD(mi) { \ 120150a83466Sjwahlig mi_hold(mi); \ 120250a83466Sjwahlig } 120350a83466Sjwahlig 120450a83466Sjwahlig #define MI4_RELE(mi) { \ 120550a83466Sjwahlig mi_rele(mi); \ 120650a83466Sjwahlig } 120750a83466Sjwahlig 12087c478bd9Sstevel@tonic-gate /* 12097c478bd9Sstevel@tonic-gate * vfs pointer to mount info 12107c478bd9Sstevel@tonic-gate */ 12117c478bd9Sstevel@tonic-gate #define VFTOMI4(vfsp) ((mntinfo4_t *)((vfsp)->vfs_data)) 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate /* 12147c478bd9Sstevel@tonic-gate * vnode pointer to mount info 12157c478bd9Sstevel@tonic-gate */ 12167c478bd9Sstevel@tonic-gate #define VTOMI4(vp) ((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data)) 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate /* 12197c478bd9Sstevel@tonic-gate * Lease Management 12207c478bd9Sstevel@tonic-gate * 12217c478bd9Sstevel@tonic-gate * lease_valid is initially set to NFS4_LEASE_NOT_STARTED. This is when the 12227c478bd9Sstevel@tonic-gate * nfs4_server is first created. lease_valid is then set to 12237c478bd9Sstevel@tonic-gate * NFS4_LEASE_UNITIALIZED when the renew thread is started. The extra state of 12247c478bd9Sstevel@tonic-gate * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread 12257c478bd9Sstevel@tonic-gate * already exists when we do SETCLIENTID). lease_valid is then set to 12267c478bd9Sstevel@tonic-gate * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating 12277c478bd9Sstevel@tonic-gate * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as 12287c478bd9Sstevel@tonic-gate * the lease is renewed. It is set to NFS4_LEASE_INVALID when the lease 12297c478bd9Sstevel@tonic-gate * expires. Client recovery is needed to set the lease back to 12307c478bd9Sstevel@tonic-gate * NFS4_LEASE_VALID from NFS4_LEASE_INVALID. 12317c478bd9Sstevel@tonic-gate * 12327c478bd9Sstevel@tonic-gate * The s_cred is the credential used to mount the first file system for this 12337c478bd9Sstevel@tonic-gate * server. It used as the credential for the renew thread's calls to the 12347c478bd9Sstevel@tonic-gate * server. 12357c478bd9Sstevel@tonic-gate * 12367c478bd9Sstevel@tonic-gate * The renew thread waits on the condition variable cv_thread_exit. If the cv 12377c478bd9Sstevel@tonic-gate * is signalled, then the thread knows it must check s_thread_exit to see if 12387c478bd9Sstevel@tonic-gate * it should exit. The cv is signaled when the last file system is unmounted 12397c478bd9Sstevel@tonic-gate * from a particular server. s_thread_exit is set to 0 upon thread startup, 12407c478bd9Sstevel@tonic-gate * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby 12417c478bd9Sstevel@tonic-gate * telling the thread to exit. s_thread_exit is needed to avoid spurious 12427c478bd9Sstevel@tonic-gate * wakeups. 12437c478bd9Sstevel@tonic-gate * 12447c478bd9Sstevel@tonic-gate * state_ref_count is incremented every time a new file is opened and 12457c478bd9Sstevel@tonic-gate * decremented every time a file is closed otw. This keeps track of whether 12467c478bd9Sstevel@tonic-gate * the nfs4_server has state associated with it or not. 12477c478bd9Sstevel@tonic-gate * 12487c478bd9Sstevel@tonic-gate * s_refcnt is the reference count for storage management of the struct 12497c478bd9Sstevel@tonic-gate * itself. 12507c478bd9Sstevel@tonic-gate * 12517c478bd9Sstevel@tonic-gate * mntinfo4_list points to the doubly linked list of mntinfo4s that share 12527c478bd9Sstevel@tonic-gate * this nfs4_server (ie: <clientid, saddr> pair) in the current zone. This is 12537c478bd9Sstevel@tonic-gate * needed for a nfs4_server to get a mntinfo4 for use in rfs4call. 12547c478bd9Sstevel@tonic-gate * 12557c478bd9Sstevel@tonic-gate * s_recovlock is used to synchronize recovery operations. The thread 12567c478bd9Sstevel@tonic-gate * that is recovering the client must acquire it as a writer. If the 12577c478bd9Sstevel@tonic-gate * thread is using the clientid (including recovery operations on other 12587c478bd9Sstevel@tonic-gate * state), acquire it as a reader. 12597c478bd9Sstevel@tonic-gate * 12607c478bd9Sstevel@tonic-gate * The 's_otw_call_count' keeps track of the number of outstanding over the 12617c478bd9Sstevel@tonic-gate * wire requests for this structure. The struct will not go away as long 12627c478bd9Sstevel@tonic-gate * as this is non-zero (or s_refcnt is non-zero). 12637c478bd9Sstevel@tonic-gate * 12647c478bd9Sstevel@tonic-gate * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count' 12657c478bd9Sstevel@tonic-gate * variable to let the renew thread when an outstanding otw request has 12667c478bd9Sstevel@tonic-gate * finished. 12677c478bd9Sstevel@tonic-gate * 12687c478bd9Sstevel@tonic-gate * 'zoneid' and 'zone_globals' are set at creation of this structure 12697c478bd9Sstevel@tonic-gate * and are read-only after that; no lock is required to read them. 12707c478bd9Sstevel@tonic-gate * 12717c478bd9Sstevel@tonic-gate * s_lock protects: everything except cv_thread_exit and s_recovlock. 12727c478bd9Sstevel@tonic-gate * 12737c478bd9Sstevel@tonic-gate * s_program is used as the index into the nfs4_callback_globals's 12747c478bd9Sstevel@tonic-gate * nfs4prog2server table. When a callback request comes in, we can 12757c478bd9Sstevel@tonic-gate * use that request's program number (minus NFS4_CALLBACK) as an index 12767c478bd9Sstevel@tonic-gate * into the nfs4prog2server. That entry will hold the nfs4_server_t ptr. 12777c478bd9Sstevel@tonic-gate * We can then access that nfs4_server_t and its 's_deleg_list' (its list of 12787c478bd9Sstevel@tonic-gate * delegated rnode4_ts). 12797c478bd9Sstevel@tonic-gate * 12807c478bd9Sstevel@tonic-gate * Lock order: 12817c478bd9Sstevel@tonic-gate * nfs4_server::s_lock > mntinfo4::mi_lock 12827c478bd9Sstevel@tonic-gate * nfs_rtable4_lock > s_lock 12837c478bd9Sstevel@tonic-gate * nfs4_server_lst_lock > s_lock 12847c478bd9Sstevel@tonic-gate * s_recovlock > s_lock 12857c478bd9Sstevel@tonic-gate */ 12867c478bd9Sstevel@tonic-gate struct nfs4_callback_globals; 12877c478bd9Sstevel@tonic-gate 1288*8e46f7b4SArne Jansen #define RS_SERVER_GONE 1 1289*8e46f7b4SArne Jansen typedef struct nfs4_rcsync { 1290*8e46f7b4SArne Jansen list_node_t rs_link; 1291*8e46f7b4SArne Jansen uint64_t rs_seq; 1292*8e46f7b4SArne Jansen int rs_flags; 1293*8e46f7b4SArne Jansen mntinfo4_t *rs_mi; 1294*8e46f7b4SArne Jansen } nfs4_rcsync_t; 1295*8e46f7b4SArne Jansen 12967c478bd9Sstevel@tonic-gate typedef struct nfs4_server { 12977c478bd9Sstevel@tonic-gate struct nfs4_server *forw; 12987c478bd9Sstevel@tonic-gate struct nfs4_server *back; 12997c478bd9Sstevel@tonic-gate struct netbuf saddr; 13007c478bd9Sstevel@tonic-gate uint_t s_flags; /* see below */ 13017c478bd9Sstevel@tonic-gate uint_t s_refcnt; 13027c478bd9Sstevel@tonic-gate clientid4 clientid; /* what we get from server */ 13037c478bd9Sstevel@tonic-gate nfs_client_id4 clidtosend; /* what we send to server */ 13047c478bd9Sstevel@tonic-gate mntinfo4_t *mntinfo4_list; 13057c478bd9Sstevel@tonic-gate int lease_valid; 13067c478bd9Sstevel@tonic-gate time_t s_lease_time; 13077c478bd9Sstevel@tonic-gate time_t last_renewal_time; 13087c478bd9Sstevel@tonic-gate timespec_t propagation_delay; 13097c478bd9Sstevel@tonic-gate cred_t *s_cred; 13107c478bd9Sstevel@tonic-gate kcondvar_t cv_thread_exit; 13117c478bd9Sstevel@tonic-gate int s_thread_exit; 13127c478bd9Sstevel@tonic-gate int state_ref_count; 13137c478bd9Sstevel@tonic-gate int s_otw_call_count; 13147c478bd9Sstevel@tonic-gate kcondvar_t s_cv_otw_count; 1315f86c6ccaSdm120769 kcondvar_t s_clientid_pend; 13167c478bd9Sstevel@tonic-gate kmutex_t s_lock; 13177c478bd9Sstevel@tonic-gate list_t s_deleg_list; 13187c478bd9Sstevel@tonic-gate rpcprog_t s_program; 13197c478bd9Sstevel@tonic-gate nfs_rwlock_t s_recovlock; 13207c478bd9Sstevel@tonic-gate kcondvar_t wait_cb_null; /* used to wait for CB_NULL */ 13217c478bd9Sstevel@tonic-gate zoneid_t zoneid; /* zone using this nfs4_server_t */ 13227c478bd9Sstevel@tonic-gate struct nfs4_callback_globals *zone_globals; /* globals */ 1323*8e46f7b4SArne Jansen kmutex_t s_rcsync_lock; 1324*8e46f7b4SArne Jansen kcondvar_t s_rcsync_cv; 1325*8e46f7b4SArne Jansen list_t s_rcsync_list; /* list of pending opens */ 1326*8e46f7b4SArne Jansen uint64_t s_rcsync_seq; 13277c478bd9Sstevel@tonic-gate } nfs4_server_t; 13287c478bd9Sstevel@tonic-gate 13297c478bd9Sstevel@tonic-gate /* nfs4_server flags */ 13307c478bd9Sstevel@tonic-gate #define N4S_CLIENTID_SET 1 /* server has our clientid */ 1331f86c6ccaSdm120769 #define N4S_CLIENTID_PEND 0x2 /* server doesn't have clientid */ 13327c478bd9Sstevel@tonic-gate #define N4S_CB_PINGED 0x4 /* server has sent us a CB_NULL */ 13337c478bd9Sstevel@tonic-gate #define N4S_CB_WAITER 0x8 /* is/has wait{ing/ed} for cb_null */ 1334f64c4ae1Sdm120769 #define N4S_INSERTED 0x10 /* list has reference for server */ 1335f64c4ae1Sdm120769 #define N4S_BADOWNER_DEBUG 0x20 /* bad owner err msg per client */ 13367c478bd9Sstevel@tonic-gate 13377c478bd9Sstevel@tonic-gate #define N4S_CB_PAUSE_TIME 10000 /* Amount of time to pause (10ms) */ 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate struct lease_time_arg { 13407c478bd9Sstevel@tonic-gate time_t lease_time; 13417c478bd9Sstevel@tonic-gate }; 13427c478bd9Sstevel@tonic-gate 13437c478bd9Sstevel@tonic-gate enum nfs4_delegreturn_policy { 13447c478bd9Sstevel@tonic-gate IMMEDIATE, 13457c478bd9Sstevel@tonic-gate FIRSTCLOSE, 13467c478bd9Sstevel@tonic-gate LASTCLOSE, 13477c478bd9Sstevel@tonic-gate INACTIVE 13487c478bd9Sstevel@tonic-gate }; 13497c478bd9Sstevel@tonic-gate 13507c478bd9Sstevel@tonic-gate /* 13517c478bd9Sstevel@tonic-gate * Operation hints for the recovery framework (mostly). 13527c478bd9Sstevel@tonic-gate * 13537c478bd9Sstevel@tonic-gate * EXCEPTIONS: 13547c478bd9Sstevel@tonic-gate * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR 13557c478bd9Sstevel@tonic-gate * These hints exist to allow user visit/readdir a R4SRVSTUB dir. 13567c478bd9Sstevel@tonic-gate * (dir represents the root of a server fs that has not yet been 13577c478bd9Sstevel@tonic-gate * mounted at client) 13587c478bd9Sstevel@tonic-gate */ 13597c478bd9Sstevel@tonic-gate typedef enum { 13607c478bd9Sstevel@tonic-gate OH_OTHER, 13617c478bd9Sstevel@tonic-gate OH_READ, 13627c478bd9Sstevel@tonic-gate OH_WRITE, 13637c478bd9Sstevel@tonic-gate OH_COMMIT, 13647c478bd9Sstevel@tonic-gate OH_VFH_RENAME, 13657c478bd9Sstevel@tonic-gate OH_MOUNT, 13667c478bd9Sstevel@tonic-gate OH_CLOSE, 13677c478bd9Sstevel@tonic-gate OH_LOCKU, 13687c478bd9Sstevel@tonic-gate OH_DELEGRETURN, 13697c478bd9Sstevel@tonic-gate OH_ACCESS, 13707c478bd9Sstevel@tonic-gate OH_GETACL, 13717c478bd9Sstevel@tonic-gate OH_GETATTR, 13727c478bd9Sstevel@tonic-gate OH_LOOKUP, 13737c478bd9Sstevel@tonic-gate OH_READDIR 13747c478bd9Sstevel@tonic-gate } nfs4_op_hint_t; 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate /* 1377b9238976Sth199096 * This data structure is used to track ephemeral mounts for both 1378b9238976Sth199096 * mirror mounts and referrals. 1379b9238976Sth199096 * 1380b9238976Sth199096 * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral 1381b9238976Sth199096 * pointing at it. So we don't need two backpointers to walk 1382b9238976Sth199096 * back up the tree. 1383b9238976Sth199096 * 1384b9238976Sth199096 * An ephemeral tree is pointed to by an enclosing non-ephemeral 1385b9238976Sth199096 * mntinfo4. The root is also pointed to by its ephemeral 1386b9238976Sth199096 * mntinfo4. ne_child will get us back to it, while ne_prior 1387b9238976Sth199096 * will get us back to the non-ephemeral mntinfo4. This is an 1388b9238976Sth199096 * edge case we will need to be wary of when walking back up the 1389b9238976Sth199096 * tree. 1390b9238976Sth199096 * 1391b9238976Sth199096 * The way we handle this edge case is to have ne_prior be NULL 1392b9238976Sth199096 * for the root nfs4_ephemeral node. 1393b9238976Sth199096 */ 1394b9238976Sth199096 typedef struct nfs4_ephemeral { 1395b9238976Sth199096 mntinfo4_t *ne_mount; /* who encloses us */ 1396b9238976Sth199096 struct nfs4_ephemeral *ne_child; /* first child node */ 1397b9238976Sth199096 struct nfs4_ephemeral *ne_peer; /* next sibling */ 1398b9238976Sth199096 struct nfs4_ephemeral *ne_prior; /* who points at us */ 1399b9238976Sth199096 time_t ne_ref_time; /* time last referenced */ 1400b9238976Sth199096 uint_t ne_mount_to; /* timeout at */ 1401b9238976Sth199096 int ne_state; /* used to traverse */ 1402b9238976Sth199096 } nfs4_ephemeral_t; 1403b9238976Sth199096 1404b9238976Sth199096 /* 1405b9238976Sth199096 * State for the node (set in ne_state): 1406b9238976Sth199096 */ 1407b9238976Sth199096 #define NFS4_EPHEMERAL_OK 0x0 1408b9238976Sth199096 #define NFS4_EPHEMERAL_VISIT_CHILD 0x1 1409b9238976Sth199096 #define NFS4_EPHEMERAL_VISIT_SIBLING 0x2 1410b9238976Sth199096 #define NFS4_EPHEMERAL_PROCESS_ME 0x4 1411b9238976Sth199096 #define NFS4_EPHEMERAL_CHILD_ERROR 0x8 1412b9238976Sth199096 #define NFS4_EPHEMERAL_PEER_ERROR 0x10 1413b9238976Sth199096 1414b9238976Sth199096 /* 1415b9238976Sth199096 * These are the locks used in processing ephemeral data: 1416b9238976Sth199096 * 1417b9238976Sth199096 * mi->mi_lock 1418b9238976Sth199096 * 1419b9238976Sth199096 * net->net_tree_lock 1420b9238976Sth199096 * This lock is used to gate all tree operations. 1421b9238976Sth199096 * If it is held, then no other process may 1422b9238976Sth199096 * traverse the tree. This allows us to not 1423b9238976Sth199096 * throw a hold on each vfs_t in the tree. 1424b9238976Sth199096 * Can be held for a "long" time. 1425b9238976Sth199096 * 1426b9238976Sth199096 * net->net_cnt_lock 1427b9238976Sth199096 * Used to protect refcnt and status. 1428b9238976Sth199096 * Must be held for a really short time. 1429b9238976Sth199096 * 1430b9238976Sth199096 * nfs4_ephemeral_thread_lock 1431b9238976Sth199096 * Is only held to create the harvester for the zone. 1432b9238976Sth199096 * There is no ordering imposed on it. 1433b9238976Sth199096 * Held for a really short time. 1434b9238976Sth199096 * 1435b9238976Sth199096 * Some further detail on the interactions: 1436b9238976Sth199096 * 1437b9238976Sth199096 * net_tree_lock controls access to net_root. Access needs to first be 1438b9238976Sth199096 * attempted in a non-blocking check. 1439b9238976Sth199096 * 1440b9238976Sth199096 * net_cnt_lock controls access to net_refcnt and net_status. It must only be 1441b9238976Sth199096 * held for very short periods of time, unless the refcnt is 0 and the status 1442b9238976Sth199096 * is INVALID. 1443b9238976Sth199096 * 1444b9238976Sth199096 * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock 1445b9238976Sth199096 * to bump the net_refcnt. It then releases it and does the action specific 1446b9238976Sth199096 * algorithm to get the net_tree_lock. Once it has that, then it is okay to 1447b9238976Sth199096 * grab the net_cnt_lock and change the status. The status can only be 1448b9238976Sth199096 * changed if the caller has the net_tree_lock held as well. 1449b9238976Sth199096 * 1450eabd0450Sth199096 * Note that the initial grab of net_cnt_lock must occur whilst 1451eabd0450Sth199096 * mi_lock is being held. This prevents stale data in that if the 1452eabd0450Sth199096 * ephemeral tree is non-NULL, then the harvester can not remove 1453eabd0450Sth199096 * the tree from the mntinfo node until it grabs that lock. I.e., 1454eabd0450Sth199096 * we get the pointer to the tree and hold the lock atomically 1455eabd0450Sth199096 * with respect to being in mi_lock. 1456eabd0450Sth199096 * 1457b9238976Sth199096 * When a caller is done with net_tree_lock, it can decrement the net_refcnt 1458b9238976Sth199096 * either before it releases net_tree_lock or after. 1459b9238976Sth199096 * 1460b9238976Sth199096 * In either event, to decrement net_refcnt, it must hold net_cnt_lock. 1461b9238976Sth199096 * 1462b9238976Sth199096 * Note that the overall locking scheme for the nodes is to control access 1463b9238976Sth199096 * via the tree. The current scheme could easily be extended such that 1464b9238976Sth199096 * the enclosing root referenced a "forest" of trees. The underlying trees 1465b9238976Sth199096 * would be autonomous with respect to locks. 1466b9238976Sth199096 * 1467b9238976Sth199096 * Note that net_next is controlled by external locks 1468b9238976Sth199096 * particular to the data structure that the tree is being added to. 1469b9238976Sth199096 */ 1470b9238976Sth199096 typedef struct nfs4_ephemeral_tree { 1471b9238976Sth199096 mntinfo4_t *net_mount; 1472b9238976Sth199096 nfs4_ephemeral_t *net_root; 1473b9238976Sth199096 struct nfs4_ephemeral_tree *net_next; 1474b9238976Sth199096 kmutex_t net_tree_lock; 1475b9238976Sth199096 kmutex_t net_cnt_lock; 1476b9238976Sth199096 uint_t net_status; 1477b9238976Sth199096 uint_t net_refcnt; 1478b9238976Sth199096 } nfs4_ephemeral_tree_t; 1479b9238976Sth199096 1480b9238976Sth199096 /* 1481b9238976Sth199096 * State for the tree (set in net_status): 1482b9238976Sth199096 */ 1483b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_OK 0x0 1484b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_BUILDING 0x1 1485b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_DEROOTING 0x2 1486b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_INVALID 0x4 1487b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_MOUNTING 0x8 1488b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_UMOUNTING 0x10 1489b9238976Sth199096 #define NFS4_EPHEMERAL_TREE_LOCKED 0x20 1490b9238976Sth199096 1491d3a14591SThomas Haynes #define NFS4_EPHEMERAL_TREE_PROCESSING (NFS4_EPHEMERAL_TREE_DEROOTING | \ 1492d3a14591SThomas Haynes NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \ 1493d3a14591SThomas Haynes NFS4_EPHEMERAL_TREE_LOCKED) 1494d3a14591SThomas Haynes 1495b9238976Sth199096 /* 14967c478bd9Sstevel@tonic-gate * This macro evaluates to non-zero if the given op releases state at the 14977c478bd9Sstevel@tonic-gate * server. 14987c478bd9Sstevel@tonic-gate */ 14997c478bd9Sstevel@tonic-gate #define OH_IS_STATE_RELE(op) ((op) == OH_CLOSE || (op) == OH_LOCKU || \ 15007c478bd9Sstevel@tonic-gate (op) == OH_DELEGRETURN) 15017c478bd9Sstevel@tonic-gate 15027c478bd9Sstevel@tonic-gate #ifdef _KERNEL 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate extern void nfs4_async_manager(struct vfs *); 15057c478bd9Sstevel@tonic-gate extern void nfs4_async_manager_stop(struct vfs *); 15067c478bd9Sstevel@tonic-gate extern void nfs4_async_stop(struct vfs *); 15077c478bd9Sstevel@tonic-gate extern int nfs4_async_stop_sig(struct vfs *); 15087c478bd9Sstevel@tonic-gate extern int nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t, 15097c478bd9Sstevel@tonic-gate struct seg *, cred_t *, 15107c478bd9Sstevel@tonic-gate void (*)(vnode_t *, u_offset_t, 15117c478bd9Sstevel@tonic-gate caddr_t, struct seg *, cred_t *)); 15127c478bd9Sstevel@tonic-gate extern int nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t, 15137c478bd9Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 15147c478bd9Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 15157c478bd9Sstevel@tonic-gate extern int nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t, 15167c478bd9Sstevel@tonic-gate int, cred_t *, int (*)(vnode_t *, page_t *, 15177c478bd9Sstevel@tonic-gate u_offset_t, size_t, int, cred_t *)); 15187c478bd9Sstevel@tonic-gate extern void nfs4_async_commit(vnode_t *, page_t *, offset3, count3, 15197c478bd9Sstevel@tonic-gate cred_t *, void (*)(vnode_t *, page_t *, 15207c478bd9Sstevel@tonic-gate offset3, count3, cred_t *)); 15217c478bd9Sstevel@tonic-gate extern void nfs4_async_inactive(vnode_t *, cred_t *); 15227c478bd9Sstevel@tonic-gate extern void nfs4_inactive_thread(mntinfo4_t *mi); 15237c478bd9Sstevel@tonic-gate extern void nfs4_inactive_otw(vnode_t *, cred_t *); 15247c478bd9Sstevel@tonic-gate extern int nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *); 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate extern int nfs4_setopts(vnode_t *, model_t, struct nfs_args *); 15277c478bd9Sstevel@tonic-gate extern void nfs4_mnt_kstat_init(struct vfs *); 15287c478bd9Sstevel@tonic-gate 15297c478bd9Sstevel@tonic-gate extern void rfs4call(struct mntinfo4 *, struct COMPOUND4args_clnt *, 15307c478bd9Sstevel@tonic-gate struct COMPOUND4res_clnt *, cred_t *, int *, int, 15317c478bd9Sstevel@tonic-gate nfs4_error_t *); 15327c478bd9Sstevel@tonic-gate extern void nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *); 15337c478bd9Sstevel@tonic-gate extern int nfs4_attr_otw(vnode_t *, nfs4_tag_type_t, 15347c478bd9Sstevel@tonic-gate nfs4_ga_res_t *, bitmap4, cred_t *); 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate extern void nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t); 15377c478bd9Sstevel@tonic-gate extern void nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *, 15387c478bd9Sstevel@tonic-gate hrtime_t, cred_t *, int, 15397c478bd9Sstevel@tonic-gate change_info4 *); 15407c478bd9Sstevel@tonic-gate extern void nfs4_purge_rddir_cache(vnode_t *); 15417c478bd9Sstevel@tonic-gate extern void nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *); 15427c478bd9Sstevel@tonic-gate extern void nfs4_purge_caches(vnode_t *, int, cred_t *, int); 15437c478bd9Sstevel@tonic-gate extern void nfs4_purge_stale_fh(int, vnode_t *, cred_t *); 1544d55e25c3SPavel Filipensky extern void nfs4_flush_pages(vnode_t *vp, cred_t *cr); 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate extern void nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *); 15477c478bd9Sstevel@tonic-gate extern void nfs4_update_paths(vnode_t *, char *, vnode_t *, char *, 15487c478bd9Sstevel@tonic-gate vnode_t *); 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate extern void nfs4args_lookup_free(nfs_argop4 *, int); 15517c478bd9Sstevel@tonic-gate extern void nfs4args_copen_free(OPEN4cargs *); 15527c478bd9Sstevel@tonic-gate 15537c478bd9Sstevel@tonic-gate extern void nfs4_printfhandle(nfs4_fhandle_t *); 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate extern void nfs_free_mi4(mntinfo4_t *); 15567c478bd9Sstevel@tonic-gate extern void sv4_free(servinfo4_t *); 15577c478bd9Sstevel@tonic-gate extern void nfs4_mi_zonelist_add(mntinfo4_t *); 155850a83466Sjwahlig extern int nfs4_mi_zonelist_remove(mntinfo4_t *); 15597c478bd9Sstevel@tonic-gate extern int nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *); 15607c478bd9Sstevel@tonic-gate extern void nfs4_secinfo_init(void); 15617c478bd9Sstevel@tonic-gate extern void nfs4_secinfo_fini(void); 15627c478bd9Sstevel@tonic-gate extern int nfs4_secinfo_path(mntinfo4_t *, cred_t *, int); 15637c478bd9Sstevel@tonic-gate extern int nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *); 15647c478bd9Sstevel@tonic-gate extern void secinfo_free(sv_secinfo_t *); 15657c478bd9Sstevel@tonic-gate extern void save_mnt_secinfo(servinfo4_t *); 15667c478bd9Sstevel@tonic-gate extern void check_mnt_secinfo(servinfo4_t *, vnode_t *); 15677c478bd9Sstevel@tonic-gate extern int vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int, 15687c478bd9Sstevel@tonic-gate enum nfs_opnum4, bitmap4 supp_mask); 15697c478bd9Sstevel@tonic-gate extern int nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *, 15707c478bd9Sstevel@tonic-gate int, cred_t *); 15717c478bd9Sstevel@tonic-gate extern void nfs4_write_error(vnode_t *, int, cred_t *); 15727c478bd9Sstevel@tonic-gate extern void nfs4_lockcompletion(vnode_t *, int); 15737c478bd9Sstevel@tonic-gate extern bool_t nfs4_map_lost_lock_conflict(vnode_t *); 15747c478bd9Sstevel@tonic-gate extern int vtodv(vnode_t *, vnode_t **, cred_t *, bool_t); 15752f172c55SRobert Thurlow extern int vtoname(vnode_t *, char *, ssize_t); 15767c478bd9Sstevel@tonic-gate extern void nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *, 15777c478bd9Sstevel@tonic-gate bool_t, bool_t *, nfs4_open_owner_t *, bool_t, 15787c478bd9Sstevel@tonic-gate nfs4_error_t *, int *); 15797c478bd9Sstevel@tonic-gate extern void nfs4_error_zinit(nfs4_error_t *); 15807c478bd9Sstevel@tonic-gate extern void nfs4_error_init(nfs4_error_t *, int); 1581b9238976Sth199096 extern void nfs4_free_args(struct nfs_args *); 158250a83466Sjwahlig 158350a83466Sjwahlig extern void mi_hold(mntinfo4_t *); 158450a83466Sjwahlig extern void mi_rele(mntinfo4_t *); 158550a83466Sjwahlig 15862f172c55SRobert Thurlow extern vnode_t *find_referral_stubvp(vnode_t *, char *, cred_t *); 15872f172c55SRobert Thurlow extern int nfs4_setup_referral(vnode_t *, char *, vnode_t **, cred_t *); 15882f172c55SRobert Thurlow 1589b9238976Sth199096 extern sec_data_t *copy_sec_data(sec_data_t *); 1590b9238976Sth199096 extern gss_clntdata_t *copy_sec_data_gss(gss_clntdata_t *); 1591b9238976Sth199096 15927c478bd9Sstevel@tonic-gate #ifdef DEBUG 15937c478bd9Sstevel@tonic-gate extern int nfs4_consistent_type(vnode_t *); 15947c478bd9Sstevel@tonic-gate #endif 15957c478bd9Sstevel@tonic-gate 15967c478bd9Sstevel@tonic-gate extern void nfs4_init_dot_entries(void); 15977c478bd9Sstevel@tonic-gate extern void nfs4_destroy_dot_entries(void); 15987c478bd9Sstevel@tonic-gate extern struct nfs4_callback_globals *nfs4_get_callback_globals(void); 15997c478bd9Sstevel@tonic-gate 16007c478bd9Sstevel@tonic-gate extern struct nfs4_server nfs4_server_lst; 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate extern clock_t nfs_write_error_interval; 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 16057c478bd9Sstevel@tonic-gate 16067c478bd9Sstevel@tonic-gate /* 16077c478bd9Sstevel@tonic-gate * Flags for nfs4getfh_otw. 16087c478bd9Sstevel@tonic-gate */ 16097c478bd9Sstevel@tonic-gate 16107c478bd9Sstevel@tonic-gate #define NFS4_GETFH_PUBLIC 0x01 16117c478bd9Sstevel@tonic-gate #define NFS4_GETFH_NEEDSOP 0x02 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate /* 16147c478bd9Sstevel@tonic-gate * Found through rnodes. 16157c478bd9Sstevel@tonic-gate * 16167c478bd9Sstevel@tonic-gate * The os_open_ref_count keeps track the number of open file descriptor 16177c478bd9Sstevel@tonic-gate * refernces on this data structure. It will be bumped for any successful 16187c478bd9Sstevel@tonic-gate * OTW OPEN call and any OPEN call that determines the OTW call is not 16197c478bd9Sstevel@tonic-gate * necessary and the open stream hasn't just been created (see 16207c478bd9Sstevel@tonic-gate * nfs4_is_otw_open_necessary). 16217c478bd9Sstevel@tonic-gate * 16227c478bd9Sstevel@tonic-gate * os_mapcnt is a count of the number of mmapped pages for a particular 16237c478bd9Sstevel@tonic-gate * open stream; this in conjunction w/ os_open_ref_count is used to 16247c478bd9Sstevel@tonic-gate * determine when to do a close to the server. This is necessary because 16257c478bd9Sstevel@tonic-gate * of the semantics of doing open, mmap, close; the OTW close must be wait 16267c478bd9Sstevel@tonic-gate * until all open and mmap references have vanished. 16277c478bd9Sstevel@tonic-gate * 16287c478bd9Sstevel@tonic-gate * 'os_valid' tells us whether this structure is about to be freed or not, 16297c478bd9Sstevel@tonic-gate * if it is then don't return it in find_open_stream(). 16307c478bd9Sstevel@tonic-gate * 16317c478bd9Sstevel@tonic-gate * 'os_final_close' is set when a CLOSE OTW was attempted. This is needed 16327c478bd9Sstevel@tonic-gate * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE 16337c478bd9Sstevel@tonic-gate * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE. It 16347c478bd9Sstevel@tonic-gate * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE 16357c478bd9Sstevel@tonic-gate * that tried to close OTW but failed, and left the state cleanup to 16367c478bd9Sstevel@tonic-gate * nfs4_inactive/CLOSE_FORCE. 16377c478bd9Sstevel@tonic-gate * 16387c478bd9Sstevel@tonic-gate * 'os_force_close' is used to let us know if an intervening thread came 16397c478bd9Sstevel@tonic-gate * and reopened the open stream after we decided to issue a CLOSE_FORCE, 16407c478bd9Sstevel@tonic-gate * but before we could actually process the CLOSE_FORCE. 16417c478bd9Sstevel@tonic-gate * 16427c478bd9Sstevel@tonic-gate * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the 16437c478bd9Sstevel@tonic-gate * lost state queue. 16447c478bd9Sstevel@tonic-gate * 16457c478bd9Sstevel@tonic-gate * 'open_stateid' is set the last open stateid returned by the server unless 16467c478bd9Sstevel@tonic-gate * 'os_delegation' is 1, in which case 'open_stateid' refers to the 16477c478bd9Sstevel@tonic-gate * delegation stateid returned by the server. This is used in cases where the 16487c478bd9Sstevel@tonic-gate * client tries to OPEN a file but already has a suitable delegation, so we 16497c478bd9Sstevel@tonic-gate * just stick the delegation stateid in the open stream. 16507c478bd9Sstevel@tonic-gate * 16517c478bd9Sstevel@tonic-gate * os_dc_openacc are open access bits which have been granted to the 16527c478bd9Sstevel@tonic-gate * open stream by virtue of a delegation, but which have not been seen 16537c478bd9Sstevel@tonic-gate * by the server. This applies even if the open stream does not have 16547c478bd9Sstevel@tonic-gate * os_delegation set. These bits are used when setting file locks to 16557c478bd9Sstevel@tonic-gate * determine whether an open with CLAIM_DELEGATE_CUR needs to be done 16567c478bd9Sstevel@tonic-gate * before the lock request can be sent to the server. See 16577c478bd9Sstevel@tonic-gate * nfs4frlock_check_deleg(). 16587c478bd9Sstevel@tonic-gate * 16597c478bd9Sstevel@tonic-gate * 'os_mmap_read/write' keep track of the read and write access our memory 16607c478bd9Sstevel@tonic-gate * maps require. We need to keep track of this so we can provide the proper 16617c478bd9Sstevel@tonic-gate * access bits in the open/mmap/close/reboot/reopen case. 16627c478bd9Sstevel@tonic-gate * 16637c478bd9Sstevel@tonic-gate * 'os_failed_reopen' tells us that we failed to successfully reopen this 16647c478bd9Sstevel@tonic-gate * open stream; therefore, we should not use this open stateid as it is 16657c478bd9Sstevel@tonic-gate * not valid anymore. This flag is also used to indicate an unsuccessful 16667c478bd9Sstevel@tonic-gate * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR. 16677c478bd9Sstevel@tonic-gate * 16687c478bd9Sstevel@tonic-gate * If 'os_orig_oo_name' is different than os_open_owner's oo_name 16697c478bd9Sstevel@tonic-gate * then this tells us that this open stream's open owner used a 16707c478bd9Sstevel@tonic-gate * bad seqid (that is, got NFS4ERR_BAD_SEQID). If different, this open 16717c478bd9Sstevel@tonic-gate * stream will no longer be used for future OTW state releasing calls. 16727c478bd9Sstevel@tonic-gate * 16737c478bd9Sstevel@tonic-gate * Lock ordering: 16747c478bd9Sstevel@tonic-gate * rnode4_t::r_os_lock > os_sync_lock 16757c478bd9Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statelock 16767c478bd9Sstevel@tonic-gate * os_sync_lock > rnode4_t::r_statev4_lock 16777c478bd9Sstevel@tonic-gate * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call) 16787c478bd9Sstevel@tonic-gate * 16797c478bd9Sstevel@tonic-gate * The 'os_sync_lock' protects: 16807c478bd9Sstevel@tonic-gate * open_stateid 16817c478bd9Sstevel@tonic-gate * os_dc_openacc 16827c478bd9Sstevel@tonic-gate * os_delegation 16837c478bd9Sstevel@tonic-gate * os_failed_reopen 16847c478bd9Sstevel@tonic-gate * os_final_close 16857c478bd9Sstevel@tonic-gate * os_force_close 16867c478bd9Sstevel@tonic-gate * os_mapcnt 16877c478bd9Sstevel@tonic-gate * os_mmap_read 16887c478bd9Sstevel@tonic-gate * os_mmap_write 16897c478bd9Sstevel@tonic-gate * os_open_ref_count 16907c478bd9Sstevel@tonic-gate * os_pending_close 16917c478bd9Sstevel@tonic-gate * os_share_acc_read 16927c478bd9Sstevel@tonic-gate * os_share_acc_write 16937c478bd9Sstevel@tonic-gate * os_share_deny_none 16947c478bd9Sstevel@tonic-gate * os_share_deny_read 16957c478bd9Sstevel@tonic-gate * os_share_deny_write 16967c478bd9Sstevel@tonic-gate * os_ref_count 16977c478bd9Sstevel@tonic-gate * os_valid 16987c478bd9Sstevel@tonic-gate * 16997c478bd9Sstevel@tonic-gate * The rnode4_t::r_os_lock protects: 17007c478bd9Sstevel@tonic-gate * os_node 17017c478bd9Sstevel@tonic-gate * 17027c478bd9Sstevel@tonic-gate * These fields are set at creation time and 17037c478bd9Sstevel@tonic-gate * read only after that: 17047c478bd9Sstevel@tonic-gate * os_open_owner 17057c478bd9Sstevel@tonic-gate * os_orig_oo_name 17067c478bd9Sstevel@tonic-gate */ 17077c478bd9Sstevel@tonic-gate typedef struct nfs4_open_stream { 17087c478bd9Sstevel@tonic-gate uint64_t os_share_acc_read; 17097c478bd9Sstevel@tonic-gate uint64_t os_share_acc_write; 17107c478bd9Sstevel@tonic-gate uint64_t os_mmap_read; 17117c478bd9Sstevel@tonic-gate uint64_t os_mmap_write; 17127c478bd9Sstevel@tonic-gate uint32_t os_share_deny_none; 17137c478bd9Sstevel@tonic-gate uint32_t os_share_deny_read; 17147c478bd9Sstevel@tonic-gate uint32_t os_share_deny_write; 17157c478bd9Sstevel@tonic-gate stateid4 open_stateid; 17167c478bd9Sstevel@tonic-gate int os_dc_openacc; 17177c478bd9Sstevel@tonic-gate int os_ref_count; 17187c478bd9Sstevel@tonic-gate unsigned os_valid:1; 17197c478bd9Sstevel@tonic-gate unsigned os_delegation:1; 17207c478bd9Sstevel@tonic-gate unsigned os_final_close:1; 17217c478bd9Sstevel@tonic-gate unsigned os_pending_close:1; 17227c478bd9Sstevel@tonic-gate unsigned os_failed_reopen:1; 17237c478bd9Sstevel@tonic-gate unsigned os_force_close:1; 17247c478bd9Sstevel@tonic-gate int os_open_ref_count; 17257c478bd9Sstevel@tonic-gate long os_mapcnt; 17267c478bd9Sstevel@tonic-gate list_node_t os_node; 17277c478bd9Sstevel@tonic-gate struct nfs4_open_owner *os_open_owner; 17287c478bd9Sstevel@tonic-gate uint64_t os_orig_oo_name; 17297c478bd9Sstevel@tonic-gate kmutex_t os_sync_lock; 17307c478bd9Sstevel@tonic-gate } nfs4_open_stream_t; 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate /* 17337c478bd9Sstevel@tonic-gate * This structure describes the format of the lock_owner_name 17347c478bd9Sstevel@tonic-gate * field of the lock owner. 17357c478bd9Sstevel@tonic-gate */ 17367c478bd9Sstevel@tonic-gate 17377c478bd9Sstevel@tonic-gate typedef struct nfs4_lo_name { 17387c478bd9Sstevel@tonic-gate uint64_t ln_seq_num; 17397c478bd9Sstevel@tonic-gate pid_t ln_pid; 17407c478bd9Sstevel@tonic-gate } nfs4_lo_name_t; 17417c478bd9Sstevel@tonic-gate 17427c478bd9Sstevel@tonic-gate /* 17437c478bd9Sstevel@tonic-gate * Flags for lo_flags. 17447c478bd9Sstevel@tonic-gate */ 17457c478bd9Sstevel@tonic-gate #define NFS4_LOCK_SEQID_INUSE 0x1 17467c478bd9Sstevel@tonic-gate #define NFS4_BAD_SEQID_LOCK 0x2 17477c478bd9Sstevel@tonic-gate 17487c478bd9Sstevel@tonic-gate /* 17497c478bd9Sstevel@tonic-gate * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs 17507c478bd9Sstevel@tonic-gate * off the rnode. If the links are NULL it means this object is not on the 17517c478bd9Sstevel@tonic-gate * list. 17527c478bd9Sstevel@tonic-gate * 17537c478bd9Sstevel@tonic-gate * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and 17547c478bd9Sstevel@tonic-gate * didn't get a response back. This is used to figure out if we have 17557c478bd9Sstevel@tonic-gate * possible remote v4 locks, so that we can clean up at process exit. In 17567c478bd9Sstevel@tonic-gate * theory, the client should be able to figure out if the server received 17577c478bd9Sstevel@tonic-gate * the request (based on what seqid works), so maybe we can get rid of this 17587c478bd9Sstevel@tonic-gate * flag someday. 17597c478bd9Sstevel@tonic-gate * 17607c478bd9Sstevel@tonic-gate * 'lo_ref_count' tells us how many processes/threads are using this data 17617c478bd9Sstevel@tonic-gate * structure. The rnode's list accounts for one reference. 17627c478bd9Sstevel@tonic-gate * 17637c478bd9Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the 17647c478bd9Sstevel@tonic-gate * data structure. It is then set to NFS4_PERM_CREATED when a lock request 17657c478bd9Sstevel@tonic-gate * is successful using this lock owner structure. We need to keep 'temporary' 17667c478bd9Sstevel@tonic-gate * lock owners around so we can properly keep the lock seqid synchronization 17677c478bd9Sstevel@tonic-gate * when multiple processes/threads are trying to create the lock owner for the 17687c478bd9Sstevel@tonic-gate * first time (especially with the DENIED error case). Once 17697c478bd9Sstevel@tonic-gate * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change. 17707c478bd9Sstevel@tonic-gate * 17717c478bd9Sstevel@tonic-gate * 'lo_valid' tells us whether this structure is about to be freed or not, 17727c478bd9Sstevel@tonic-gate * if it is then don't return it from find_lock_owner(). 17737c478bd9Sstevel@tonic-gate * 17747c478bd9Sstevel@tonic-gate * Retrieving and setting of 'lock_seqid' is protected by the 17757c478bd9Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag. Waiters for NFS4_LOCK_SEQID_INUSE should 17767c478bd9Sstevel@tonic-gate * use 'lo_cv_seqid_sync'. 17777c478bd9Sstevel@tonic-gate * 17787c478bd9Sstevel@tonic-gate * The setting of 'lock_stateid' is protected by the 17797c478bd9Sstevel@tonic-gate * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'. The retrieving of the 17807c478bd9Sstevel@tonic-gate * 'lock_stateid' is protected by 'lo_lock', with the additional 17817c478bd9Sstevel@tonic-gate * requirement that the calling function can handle NFS4ERR_OLD_STATEID and 17827c478bd9Sstevel@tonic-gate * NFS4ERR_BAD_STATEID as appropiate. 17837c478bd9Sstevel@tonic-gate * 17847c478bd9Sstevel@tonic-gate * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock 17857c478bd9Sstevel@tonic-gate * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID). With this set, 17867c478bd9Sstevel@tonic-gate * this lock owner will no longer be used for future OTW calls. Once set, 17877c478bd9Sstevel@tonic-gate * it is never unset. 17887c478bd9Sstevel@tonic-gate * 17897c478bd9Sstevel@tonic-gate * Lock ordering: 17907c478bd9Sstevel@tonic-gate * rnode4_t::r_statev4_lock > lo_lock 17917c478bd9Sstevel@tonic-gate */ 17927c478bd9Sstevel@tonic-gate typedef struct nfs4_lock_owner { 17937c478bd9Sstevel@tonic-gate struct nfs4_lock_owner *lo_next_rnode; 17947c478bd9Sstevel@tonic-gate struct nfs4_lock_owner *lo_prev_rnode; 17957c478bd9Sstevel@tonic-gate int lo_pid; 17967c478bd9Sstevel@tonic-gate stateid4 lock_stateid; 17977c478bd9Sstevel@tonic-gate seqid4 lock_seqid; 17987c478bd9Sstevel@tonic-gate /* 17997c478bd9Sstevel@tonic-gate * Fix this to always be 12 bytes 18007c478bd9Sstevel@tonic-gate */ 18017c478bd9Sstevel@tonic-gate nfs4_lo_name_t lock_owner_name; 18027c478bd9Sstevel@tonic-gate int lo_ref_count; 18037c478bd9Sstevel@tonic-gate int lo_valid; 18047c478bd9Sstevel@tonic-gate int lo_pending_rqsts; 18057c478bd9Sstevel@tonic-gate int lo_just_created; 18067c478bd9Sstevel@tonic-gate int lo_flags; 18077c478bd9Sstevel@tonic-gate kcondvar_t lo_cv_seqid_sync; 18087c478bd9Sstevel@tonic-gate kmutex_t lo_lock; 18097c478bd9Sstevel@tonic-gate kthread_t *lo_seqid_holder; /* debugging aid */ 18107c478bd9Sstevel@tonic-gate } nfs4_lock_owner_t; 18117c478bd9Sstevel@tonic-gate 18127c478bd9Sstevel@tonic-gate /* for nfs4_lock_owner_t lookups */ 18137c478bd9Sstevel@tonic-gate typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t; 18147c478bd9Sstevel@tonic-gate 18157c478bd9Sstevel@tonic-gate /* Number of times to retry a call that fails with state independent error */ 18167c478bd9Sstevel@tonic-gate #define NFS4_NUM_RECOV_RETRIES 3 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate typedef enum { 18197c478bd9Sstevel@tonic-gate NO_SID, 18207c478bd9Sstevel@tonic-gate DEL_SID, 18217c478bd9Sstevel@tonic-gate LOCK_SID, 18227c478bd9Sstevel@tonic-gate OPEN_SID, 18237c478bd9Sstevel@tonic-gate SPEC_SID 18247c478bd9Sstevel@tonic-gate } nfs4_stateid_type_t; 18257c478bd9Sstevel@tonic-gate 18267c478bd9Sstevel@tonic-gate typedef struct nfs4_stateid_types { 18277c478bd9Sstevel@tonic-gate stateid4 d_sid; 18287c478bd9Sstevel@tonic-gate stateid4 l_sid; 18297c478bd9Sstevel@tonic-gate stateid4 o_sid; 18307c478bd9Sstevel@tonic-gate nfs4_stateid_type_t cur_sid_type; 18317c478bd9Sstevel@tonic-gate } nfs4_stateid_types_t; 18327c478bd9Sstevel@tonic-gate 18337c478bd9Sstevel@tonic-gate /* 18347c478bd9Sstevel@tonic-gate * Per-zone data for dealing with callbacks. Included here solely for the 18357c478bd9Sstevel@tonic-gate * benefit of MDB. 18367c478bd9Sstevel@tonic-gate */ 18377c478bd9Sstevel@tonic-gate struct nfs4_callback_stats { 18387c478bd9Sstevel@tonic-gate kstat_named_t delegations; 18397c478bd9Sstevel@tonic-gate kstat_named_t cb_getattr; 18407c478bd9Sstevel@tonic-gate kstat_named_t cb_recall; 18417c478bd9Sstevel@tonic-gate kstat_named_t cb_null; 18427c478bd9Sstevel@tonic-gate kstat_named_t cb_dispatch; 18437c478bd9Sstevel@tonic-gate kstat_named_t delegaccept_r; 18447c478bd9Sstevel@tonic-gate kstat_named_t delegaccept_rw; 18457c478bd9Sstevel@tonic-gate kstat_named_t delegreturn; 18467c478bd9Sstevel@tonic-gate kstat_named_t callbacks; 18477c478bd9Sstevel@tonic-gate kstat_named_t claim_cur; 18487c478bd9Sstevel@tonic-gate kstat_named_t claim_cur_ok; 18497c478bd9Sstevel@tonic-gate kstat_named_t recall_trunc; 18507c478bd9Sstevel@tonic-gate kstat_named_t recall_failed; 18517c478bd9Sstevel@tonic-gate kstat_named_t return_limit_write; 18527c478bd9Sstevel@tonic-gate kstat_named_t return_limit_addmap; 18537c478bd9Sstevel@tonic-gate kstat_named_t deleg_recover; 18547c478bd9Sstevel@tonic-gate kstat_named_t cb_illegal; 18557c478bd9Sstevel@tonic-gate }; 18567c478bd9Sstevel@tonic-gate 18577c478bd9Sstevel@tonic-gate struct nfs4_callback_globals { 18587c478bd9Sstevel@tonic-gate kmutex_t nfs4_cb_lock; 18597c478bd9Sstevel@tonic-gate kmutex_t nfs4_dlist_lock; 18607c478bd9Sstevel@tonic-gate int nfs4_program_hint; 18617c478bd9Sstevel@tonic-gate /* this table maps the program number to the nfs4_server structure */ 18627c478bd9Sstevel@tonic-gate struct nfs4_server **nfs4prog2server; 18637c478bd9Sstevel@tonic-gate list_t nfs4_dlist; 18647c478bd9Sstevel@tonic-gate list_t nfs4_cb_ports; 18657c478bd9Sstevel@tonic-gate struct nfs4_callback_stats nfs4_callback_stats; 18667c478bd9Sstevel@tonic-gate #ifdef DEBUG 18677c478bd9Sstevel@tonic-gate int nfs4_dlistadd_c; 18687c478bd9Sstevel@tonic-gate int nfs4_dlistclean_c; 18697c478bd9Sstevel@tonic-gate #endif 18707c478bd9Sstevel@tonic-gate }; 18717c478bd9Sstevel@tonic-gate 18727c478bd9Sstevel@tonic-gate typedef enum { 18737c478bd9Sstevel@tonic-gate CLOSE_NORM, 18747c478bd9Sstevel@tonic-gate CLOSE_DELMAP, 18757c478bd9Sstevel@tonic-gate CLOSE_FORCE, 18767c478bd9Sstevel@tonic-gate CLOSE_RESEND, 18777c478bd9Sstevel@tonic-gate CLOSE_AFTER_RESEND 18787c478bd9Sstevel@tonic-gate } nfs4_close_type_t; 18797c478bd9Sstevel@tonic-gate 18807c478bd9Sstevel@tonic-gate /* 18817c478bd9Sstevel@tonic-gate * Structure to hold the bad seqid information that is passed 18827c478bd9Sstevel@tonic-gate * to the recovery framework. 18837c478bd9Sstevel@tonic-gate */ 18847c478bd9Sstevel@tonic-gate typedef struct nfs4_bseqid_entry { 18857c478bd9Sstevel@tonic-gate nfs4_open_owner_t *bs_oop; 18867c478bd9Sstevel@tonic-gate nfs4_lock_owner_t *bs_lop; 18877c478bd9Sstevel@tonic-gate vnode_t *bs_vp; 18887c478bd9Sstevel@tonic-gate pid_t bs_pid; 18897c478bd9Sstevel@tonic-gate nfs4_tag_type_t bs_tag; 18907c478bd9Sstevel@tonic-gate seqid4 bs_seqid; 18917c478bd9Sstevel@tonic-gate list_node_t bs_node; 18927c478bd9Sstevel@tonic-gate } nfs4_bseqid_entry_t; 18937c478bd9Sstevel@tonic-gate 18947c478bd9Sstevel@tonic-gate #ifdef _KERNEL 18957c478bd9Sstevel@tonic-gate 18967c478bd9Sstevel@tonic-gate extern void nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int, 18977c478bd9Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t, 18987c478bd9Sstevel@tonic-gate size_t, uint_t, uint_t); 18997c478bd9Sstevel@tonic-gate extern void nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *); 19007c478bd9Sstevel@tonic-gate extern void nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4); 19017c478bd9Sstevel@tonic-gate extern void open_owner_hold(nfs4_open_owner_t *); 19027c478bd9Sstevel@tonic-gate extern void open_owner_rele(nfs4_open_owner_t *); 19037c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t *find_or_create_open_stream(nfs4_open_owner_t *, 19047c478bd9Sstevel@tonic-gate struct rnode4 *, int *); 19057c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *, 19067c478bd9Sstevel@tonic-gate struct rnode4 *); 19077c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop, 19087c478bd9Sstevel@tonic-gate struct rnode4 *rp); 19097c478bd9Sstevel@tonic-gate extern void open_stream_hold(nfs4_open_stream_t *); 19107c478bd9Sstevel@tonic-gate extern void open_stream_rele(nfs4_open_stream_t *, struct rnode4 *); 19117c478bd9Sstevel@tonic-gate extern int nfs4close_all(vnode_t *, cred_t *); 19127c478bd9Sstevel@tonic-gate extern void lock_owner_hold(nfs4_lock_owner_t *); 19137c478bd9Sstevel@tonic-gate extern void lock_owner_rele(nfs4_lock_owner_t *); 19147c478bd9Sstevel@tonic-gate extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t); 19157c478bd9Sstevel@tonic-gate extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t); 19167c478bd9Sstevel@tonic-gate extern void nfs4_rnode_remove_lock_owner(struct rnode4 *, 19177c478bd9Sstevel@tonic-gate nfs4_lock_owner_t *); 19187c478bd9Sstevel@tonic-gate extern void nfs4_flush_lock_owners(struct rnode4 *); 19197c478bd9Sstevel@tonic-gate extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t); 19207c478bd9Sstevel@tonic-gate extern void nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *, 19217c478bd9Sstevel@tonic-gate nfs4_tag_type_t); 19227c478bd9Sstevel@tonic-gate extern void nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *); 19237c478bd9Sstevel@tonic-gate extern void nfs4_get_and_set_next_open_seqid(nfs4_open_owner_t *, 19247c478bd9Sstevel@tonic-gate nfs4_tag_type_t); 19257c478bd9Sstevel@tonic-gate extern void nfs4_end_open_seqid_sync(nfs4_open_owner_t *); 19267c478bd9Sstevel@tonic-gate extern int nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *); 19277c478bd9Sstevel@tonic-gate extern void nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *); 19287c478bd9Sstevel@tonic-gate extern int nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *); 19297c478bd9Sstevel@tonic-gate extern void nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *, 19307c478bd9Sstevel@tonic-gate nfs4_open_stream_t *, clientid4, locker4 *); 19317c478bd9Sstevel@tonic-gate extern void nfs4_destroy_open_owner(nfs4_open_owner_t *); 19327c478bd9Sstevel@tonic-gate 19337c478bd9Sstevel@tonic-gate extern void nfs4_renew_lease_thread(nfs4_server_t *); 19347c478bd9Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server(mntinfo4_t *); 19357c478bd9Sstevel@tonic-gate extern nfs4_server_t *find_nfs4_server_all(mntinfo4_t *, int all); 19367c478bd9Sstevel@tonic-gate extern nfs4_server_t *new_nfs4_server(servinfo4_t *, cred_t *); 19377c478bd9Sstevel@tonic-gate extern void nfs4_mark_srv_dead(nfs4_server_t *); 19387c478bd9Sstevel@tonic-gate extern nfs4_server_t *servinfo4_to_nfs4_server(servinfo4_t *); 19397c478bd9Sstevel@tonic-gate extern void nfs4_inc_state_ref_count(mntinfo4_t *); 19407c478bd9Sstevel@tonic-gate extern void nfs4_inc_state_ref_count_nolock(nfs4_server_t *, 19417c478bd9Sstevel@tonic-gate mntinfo4_t *); 19427c478bd9Sstevel@tonic-gate extern void nfs4_dec_state_ref_count(mntinfo4_t *); 19437c478bd9Sstevel@tonic-gate extern void nfs4_dec_state_ref_count_nolock(nfs4_server_t *, 19447c478bd9Sstevel@tonic-gate mntinfo4_t *); 19457c478bd9Sstevel@tonic-gate extern clientid4 mi2clientid(mntinfo4_t *); 19467c478bd9Sstevel@tonic-gate extern int nfs4_server_in_recovery(nfs4_server_t *); 19477c478bd9Sstevel@tonic-gate extern bool_t nfs4_server_vlock(nfs4_server_t *, int); 19487c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *); 19497c478bd9Sstevel@tonic-gate extern uint64_t nfs4_get_new_oo_name(void); 19507c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *); 19517c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *); 19527c478bd9Sstevel@tonic-gate extern void nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *, 195381d2f16dSMarcel Telka cred_t *, nfs4_error_t *, nfs4_lost_rqst_t *, int *); 19547c478bd9Sstevel@tonic-gate extern void nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *, 19557c478bd9Sstevel@tonic-gate nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *, 19567c478bd9Sstevel@tonic-gate vnode_t *, int, int); 19577c478bd9Sstevel@tonic-gate extern void nfs4_open_downgrade(int, int, nfs4_open_owner_t *, 19587c478bd9Sstevel@tonic-gate nfs4_open_stream_t *, vnode_t *, cred_t *, 19597c478bd9Sstevel@tonic-gate nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *); 19607c478bd9Sstevel@tonic-gate extern seqid4 nfs4_get_open_seqid(nfs4_open_owner_t *); 19617c478bd9Sstevel@tonic-gate extern cred_t *nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *); 19627c478bd9Sstevel@tonic-gate extern void nfs4_init_stateid_types(nfs4_stateid_types_t *); 19637c478bd9Sstevel@tonic-gate extern void nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *); 19647c478bd9Sstevel@tonic-gate 19657c478bd9Sstevel@tonic-gate extern kmutex_t nfs4_server_lst_lock; 19667c478bd9Sstevel@tonic-gate 19677c478bd9Sstevel@tonic-gate extern void nfs4callback_destroy(nfs4_server_t *); 19687c478bd9Sstevel@tonic-gate extern void nfs4_callback_init(void); 19697c478bd9Sstevel@tonic-gate extern void nfs4_callback_fini(void); 19707c478bd9Sstevel@tonic-gate extern void nfs4_cb_args(nfs4_server_t *, struct knetconfig *, 19717c478bd9Sstevel@tonic-gate SETCLIENTID4args *); 19727c478bd9Sstevel@tonic-gate extern void nfs4delegreturn_async(struct rnode4 *, int, bool_t); 19737c478bd9Sstevel@tonic-gate 19747c478bd9Sstevel@tonic-gate extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy; 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate extern void nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *); 19777c478bd9Sstevel@tonic-gate extern void nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *); 19787c478bd9Sstevel@tonic-gate extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *); 19797c478bd9Sstevel@tonic-gate extern bool_t nfs4_fs_active(nfs4_server_t *); 19807c478bd9Sstevel@tonic-gate extern void nfs4_server_rele(nfs4_server_t *); 19817c478bd9Sstevel@tonic-gate extern bool_t inlease(nfs4_server_t *); 19827c478bd9Sstevel@tonic-gate extern bool_t nfs4_has_pages(vnode_t *); 19837c478bd9Sstevel@tonic-gate extern void nfs4_log_badowner(mntinfo4_t *, nfs_opnum4); 19847c478bd9Sstevel@tonic-gate 19857c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 19867c478bd9Sstevel@tonic-gate 19877c478bd9Sstevel@tonic-gate /* 19887c478bd9Sstevel@tonic-gate * Client State Recovery 19897c478bd9Sstevel@tonic-gate */ 19907c478bd9Sstevel@tonic-gate 19917c478bd9Sstevel@tonic-gate /* 19927c478bd9Sstevel@tonic-gate * The following defines are used for rs_flags in 19937c478bd9Sstevel@tonic-gate * a nfs4_recov_state_t structure. 19947c478bd9Sstevel@tonic-gate * 19957c478bd9Sstevel@tonic-gate * NFS4_RS_RENAME_HELD Indicates that the mi_rename_lock was held. 19967c478bd9Sstevel@tonic-gate * NFS4_RS_GRACE_MSG Set once we have uprintf'ed a grace message. 19977c478bd9Sstevel@tonic-gate * NFS4_RS_DELAY_MSG Set once we have uprintf'ed a delay message. 19987c478bd9Sstevel@tonic-gate * NFS4_RS_RECALL_HELD1 r_deleg_recall_lock for vp1 was held. 19997c478bd9Sstevel@tonic-gate * NFS4_RS_RECALL_HELD2 r_deleg_recall_lock for vp2 was held. 20007c478bd9Sstevel@tonic-gate */ 20017c478bd9Sstevel@tonic-gate #define NFS4_RS_RENAME_HELD 0x000000001 20027c478bd9Sstevel@tonic-gate #define NFS4_RS_GRACE_MSG 0x000000002 20037c478bd9Sstevel@tonic-gate #define NFS4_RS_DELAY_MSG 0x000000004 20047c478bd9Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD1 0x000000008 20057c478bd9Sstevel@tonic-gate #define NFS4_RS_RECALL_HELD2 0x000000010 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate /* 20087c478bd9Sstevel@tonic-gate * Information that is retrieved from nfs4_start_op() and that is 20097c478bd9Sstevel@tonic-gate * passed into nfs4_end_op(). 20107c478bd9Sstevel@tonic-gate * 20117c478bd9Sstevel@tonic-gate * rs_sp is a reference to the nfs4_server that was found, or NULL. 20127c478bd9Sstevel@tonic-gate * 20137c478bd9Sstevel@tonic-gate * rs_num_retry_despite_err is the number times client retried an 20147c478bd9Sstevel@tonic-gate * OTW op despite a recovery error. It is only incremented for hints 20157c478bd9Sstevel@tonic-gate * exempt to normal R4RECOVERR processing 20167c478bd9Sstevel@tonic-gate * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN). (XXX this special-case code 20177c478bd9Sstevel@tonic-gate * needs review for possible removal.) 20187c478bd9Sstevel@tonic-gate * It is initialized wherever nfs4_recov_state_t is declared -- usually 20197c478bd9Sstevel@tonic-gate * very near initialization of rs_flags. 20207c478bd9Sstevel@tonic-gate */ 20217c478bd9Sstevel@tonic-gate typedef struct { 20227c478bd9Sstevel@tonic-gate nfs4_server_t *rs_sp; 20237c478bd9Sstevel@tonic-gate int rs_flags; 20247c478bd9Sstevel@tonic-gate int rs_num_retry_despite_err; 20257c478bd9Sstevel@tonic-gate } nfs4_recov_state_t; 20267c478bd9Sstevel@tonic-gate 20277c478bd9Sstevel@tonic-gate /* 20287c478bd9Sstevel@tonic-gate * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root. 20297c478bd9Sstevel@tonic-gate */ 20307c478bd9Sstevel@tonic-gate 20317c478bd9Sstevel@tonic-gate #define NFS4_REMAP_CKATTRS 1 20327c478bd9Sstevel@tonic-gate #define NFS4_REMAP_NEEDSOP 2 20337c478bd9Sstevel@tonic-gate 20347c478bd9Sstevel@tonic-gate #ifdef _KERNEL 20357c478bd9Sstevel@tonic-gate 20367c478bd9Sstevel@tonic-gate extern int nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int, 20377c478bd9Sstevel@tonic-gate vnode_t *, int, int *, int, nfs4_recov_state_t *); 20387c478bd9Sstevel@tonic-gate extern void nfs4setclientid(struct mntinfo4 *, struct cred *, bool_t, 20397c478bd9Sstevel@tonic-gate nfs4_error_t *); 20407c478bd9Sstevel@tonic-gate extern void nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *, 20417c478bd9Sstevel@tonic-gate open_claim_type4, bool_t, bool_t); 20427c478bd9Sstevel@tonic-gate extern void nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int); 20437c478bd9Sstevel@tonic-gate extern void nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int, 20447c478bd9Sstevel@tonic-gate nfs4_error_t *); 20457c478bd9Sstevel@tonic-gate extern void nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int, 20467c478bd9Sstevel@tonic-gate nfs4_error_t *); 20477c478bd9Sstevel@tonic-gate extern int nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t, 20487c478bd9Sstevel@tonic-gate vnode_t *, cred_t *, vnode_t **, int); 20497c478bd9Sstevel@tonic-gate extern void nfs4_fail_recov(vnode_t *, char *, int, nfsstat4); 20507c478bd9Sstevel@tonic-gate 20517c478bd9Sstevel@tonic-gate extern int nfs4_needs_recovery(nfs4_error_t *, bool_t, vfs_t *); 20527c478bd9Sstevel@tonic-gate extern int nfs4_recov_marks_dead(nfsstat4); 20537c478bd9Sstevel@tonic-gate extern bool_t nfs4_start_recovery(nfs4_error_t *, struct mntinfo4 *, 20547c478bd9Sstevel@tonic-gate vnode_t *, vnode_t *, stateid4 *, 20552f172c55SRobert Thurlow nfs4_lost_rqst_t *, nfs_opnum4, nfs4_bseqid_entry_t *, 20562f172c55SRobert Thurlow vnode_t *, char *); 20577c478bd9Sstevel@tonic-gate extern int nfs4_start_op(struct mntinfo4 *, vnode_t *, vnode_t *, 20587c478bd9Sstevel@tonic-gate nfs4_recov_state_t *); 20597c478bd9Sstevel@tonic-gate extern void nfs4_end_op(struct mntinfo4 *, vnode_t *, vnode_t *, 20607c478bd9Sstevel@tonic-gate nfs4_recov_state_t *, bool_t); 20617c478bd9Sstevel@tonic-gate extern int nfs4_start_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 20627c478bd9Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t *); 20637c478bd9Sstevel@tonic-gate extern void nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *, 20647c478bd9Sstevel@tonic-gate nfs4_op_hint_t, nfs4_recov_state_t *, bool_t); 20657c478bd9Sstevel@tonic-gate extern char *nfs4_recov_action_to_str(nfs4_recov_t); 20667c478bd9Sstevel@tonic-gate 2067b9238976Sth199096 /* 2068b9238976Sth199096 * In sequence, code desiring to unmount an ephemeral tree must 2069b9238976Sth199096 * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate, 2070b9238976Sth199096 * and nfs4_ephemeral_umount_unlock. The _unlock must also be 2071b9238976Sth199096 * called on all error paths that occur before it would naturally 2072b9238976Sth199096 * be invoked. 2073b9238976Sth199096 * 2074b9238976Sth199096 * The caller must also provde a pointer to a boolean to keep track 2075b9238976Sth199096 * of whether or not the code in _unlock is to be ran. 2076b9238976Sth199096 */ 2077b9238976Sth199096 extern void nfs4_ephemeral_umount_activate(mntinfo4_t *, 20782f172c55SRobert Thurlow bool_t *, nfs4_ephemeral_tree_t **); 2079b9238976Sth199096 extern int nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *, 20802f172c55SRobert Thurlow bool_t *, nfs4_ephemeral_tree_t **); 20812f172c55SRobert Thurlow extern void nfs4_ephemeral_umount_unlock(bool_t *, 2082b9238976Sth199096 nfs4_ephemeral_tree_t **); 2083b9238976Sth199096 2084d3a14591SThomas Haynes extern int nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp); 2085b9238976Sth199096 20862f172c55SRobert Thurlow extern int nfs4_callmapid(utf8string *, struct nfs_fsl_info *); 20872f172c55SRobert Thurlow extern int nfs4_fetch_locations(mntinfo4_t *, struct nfs4_sharedfh *, 20882f172c55SRobert Thurlow char *, cred_t *, nfs4_ga_res_t *, COMPOUND4res_clnt *, bool_t); 20892f172c55SRobert Thurlow 20907c478bd9Sstevel@tonic-gate extern int wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t, 20917c478bd9Sstevel@tonic-gate nfs4_recov_state_t *); 20927c478bd9Sstevel@tonic-gate extern void nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *); 20937c478bd9Sstevel@tonic-gate extern void nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t, 20947c478bd9Sstevel@tonic-gate int, nfsstat4); 20957c478bd9Sstevel@tonic-gate extern time_t nfs4err_delay_time; 20967c478bd9Sstevel@tonic-gate extern void nfs4_set_grace_wait(mntinfo4_t *); 20977c478bd9Sstevel@tonic-gate extern void nfs4_set_delay_wait(vnode_t *); 20987c478bd9Sstevel@tonic-gate extern int nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *); 20997c478bd9Sstevel@tonic-gate extern int nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *); 21007c478bd9Sstevel@tonic-gate extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *, 21017c478bd9Sstevel@tonic-gate nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t, 21027c478bd9Sstevel@tonic-gate seqid4); 21037c478bd9Sstevel@tonic-gate 21047c478bd9Sstevel@tonic-gate extern void nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *, 21057c478bd9Sstevel@tonic-gate nfs4_error_t *); 21067c478bd9Sstevel@tonic-gate extern void nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *, 21077c478bd9Sstevel@tonic-gate nfs4_server_t *); 21087c478bd9Sstevel@tonic-gate extern int nfs4_rpc_retry_error(int); 21097c478bd9Sstevel@tonic-gate extern int nfs4_try_failover(nfs4_error_t *); 21107c478bd9Sstevel@tonic-gate extern void nfs4_free_msg(nfs4_debug_msg_t *); 21117c478bd9Sstevel@tonic-gate extern void nfs4_mnt_recov_kstat_init(vfs_t *); 21127c478bd9Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_delay(mntinfo4_t *); 21137c478bd9Sstevel@tonic-gate extern void nfs4_mi_kstat_inc_no_grace(mntinfo4_t *); 21147c478bd9Sstevel@tonic-gate extern char *nfs4_stat_to_str(nfsstat4); 21157c478bd9Sstevel@tonic-gate extern char *nfs4_op_to_str(nfs_opnum4); 21167c478bd9Sstevel@tonic-gate 21177c478bd9Sstevel@tonic-gate extern void nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *, 21187c478bd9Sstevel@tonic-gate uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t, 21197c478bd9Sstevel@tonic-gate nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4); 21207c478bd9Sstevel@tonic-gate extern void nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4, 21217c478bd9Sstevel@tonic-gate nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *); 21227c478bd9Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_event) 21237c478bd9Sstevel@tonic-gate #pragma rarely_called(nfs4_queue_fact) 21247c478bd9Sstevel@tonic-gate 21257c478bd9Sstevel@tonic-gate /* Used for preformed "." and ".." dirents */ 21267c478bd9Sstevel@tonic-gate extern char *nfs4_dot_entries; 21277c478bd9Sstevel@tonic-gate extern char *nfs4_dot_dot_entry; 21287c478bd9Sstevel@tonic-gate 21297c478bd9Sstevel@tonic-gate #ifdef DEBUG 21307c478bd9Sstevel@tonic-gate extern uint_t nfs4_tsd_key; 21317c478bd9Sstevel@tonic-gate #endif 21327c478bd9Sstevel@tonic-gate 21337c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 21347c478bd9Sstevel@tonic-gate 21357c478bd9Sstevel@tonic-gate /* 21367c478bd9Sstevel@tonic-gate * Filehandle management. 21377c478bd9Sstevel@tonic-gate * 21387c478bd9Sstevel@tonic-gate * Filehandles can change in v4, so rather than storing the filehandle 21397c478bd9Sstevel@tonic-gate * directly in the rnode, etc., we manage the filehandle through one of 21407c478bd9Sstevel@tonic-gate * these objects. 21417c478bd9Sstevel@tonic-gate * Locking: sfh_fh and sfh_tree is protected by the filesystem's 21427c478bd9Sstevel@tonic-gate * mi_fh_lock. The reference count and flags are protected by sfh_lock. 21437c478bd9Sstevel@tonic-gate * sfh_mi is read-only. 21447c478bd9Sstevel@tonic-gate * 21457c478bd9Sstevel@tonic-gate * mntinfo4_t::mi_fh_lock > sfh_lock. 21467c478bd9Sstevel@tonic-gate */ 21477c478bd9Sstevel@tonic-gate 21487c478bd9Sstevel@tonic-gate typedef struct nfs4_sharedfh { 21497c478bd9Sstevel@tonic-gate nfs_fh4 sfh_fh; /* key and current filehandle */ 21507c478bd9Sstevel@tonic-gate kmutex_t sfh_lock; 21517c478bd9Sstevel@tonic-gate uint_t sfh_refcnt; /* reference count */ 21527c478bd9Sstevel@tonic-gate uint_t sfh_flags; 21537c478bd9Sstevel@tonic-gate mntinfo4_t *sfh_mi; /* backptr to filesystem */ 21547c478bd9Sstevel@tonic-gate avl_node_t sfh_tree; /* used by avl package */ 21557c478bd9Sstevel@tonic-gate } nfs4_sharedfh_t; 21567c478bd9Sstevel@tonic-gate 21577c478bd9Sstevel@tonic-gate #define SFH4_SAME(sfh1, sfh2) ((sfh1) == (sfh2)) 21587c478bd9Sstevel@tonic-gate 21597c478bd9Sstevel@tonic-gate /* 21607c478bd9Sstevel@tonic-gate * Flags. 21617c478bd9Sstevel@tonic-gate */ 21627c478bd9Sstevel@tonic-gate #define SFH4_IN_TREE 0x1 /* currently in an AVL tree */ 21637c478bd9Sstevel@tonic-gate 21647c478bd9Sstevel@tonic-gate #ifdef _KERNEL 21657c478bd9Sstevel@tonic-gate 21667c478bd9Sstevel@tonic-gate extern void sfh4_createtab(avl_tree_t *); 21677c478bd9Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *); 21687c478bd9Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *, 21697c478bd9Sstevel@tonic-gate nfs4_sharedfh_t *); 21707c478bd9Sstevel@tonic-gate extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *); 21717c478bd9Sstevel@tonic-gate extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *); 21727c478bd9Sstevel@tonic-gate extern void sfh4_hold(nfs4_sharedfh_t *); 21737c478bd9Sstevel@tonic-gate extern void sfh4_rele(nfs4_sharedfh_t **); 21747c478bd9Sstevel@tonic-gate extern void sfh4_printfhandle(const nfs4_sharedfh_t *); 21757c478bd9Sstevel@tonic-gate 21767c478bd9Sstevel@tonic-gate #endif 21777c478bd9Sstevel@tonic-gate 21787c478bd9Sstevel@tonic-gate /* 21797c478bd9Sstevel@tonic-gate * Path and file name management. 21807c478bd9Sstevel@tonic-gate * 21817c478bd9Sstevel@tonic-gate * This type stores the name of an entry in the filesystem and keeps enough 21827c478bd9Sstevel@tonic-gate * information that it can provide a complete path. All fields are 21837c478bd9Sstevel@tonic-gate * protected by fn_lock, except for the reference count, which is managed 21847c478bd9Sstevel@tonic-gate * using atomic add/subtract. 21857c478bd9Sstevel@tonic-gate * 2186bbf2a467SNagakiran Rajashekar * Additionally shared filehandle for this fname is stored. 2187bbf2a467SNagakiran Rajashekar * Normally, fn_get() when it creates this fname stores the passed in 2188bbf2a467SNagakiran Rajashekar * shared fh in fn_sfh by doing sfh_hold. Similarly the path which 2189bbf2a467SNagakiran Rajashekar * destroys this fname releases the reference on this fh by doing sfh_rele. 2190bbf2a467SNagakiran Rajashekar * 2191bbf2a467SNagakiran Rajashekar * fn_get uses the fn_sfh to refine the comparision in cases 2192bbf2a467SNagakiran Rajashekar * where we have matched the name but have differing file handles, 2193bbf2a467SNagakiran Rajashekar * this normally happens due to 2194bbf2a467SNagakiran Rajashekar * 2195bbf2a467SNagakiran Rajashekar * 1. Server side rename of a file/directory. 2196bbf2a467SNagakiran Rajashekar * 2. Another client renaming a file/directory on the server. 2197bbf2a467SNagakiran Rajashekar * 2198bbf2a467SNagakiran Rajashekar * Differing names but same filehandle is possible as in the case of hardlinks, 2199bbf2a467SNagakiran Rajashekar * but differing filehandles with same name component will later confuse 2200bbf2a467SNagakiran Rajashekar * the client and can cause various panics. 2201bbf2a467SNagakiran Rajashekar * 22027c478bd9Sstevel@tonic-gate * Lock order: child and then parent. 22037c478bd9Sstevel@tonic-gate */ 22047c478bd9Sstevel@tonic-gate 22057c478bd9Sstevel@tonic-gate typedef struct nfs4_fname { 22067c478bd9Sstevel@tonic-gate struct nfs4_fname *fn_parent; /* parent name; null if fs root */ 22077c478bd9Sstevel@tonic-gate char *fn_name; /* the actual name */ 22087c478bd9Sstevel@tonic-gate ssize_t fn_len; /* strlen(fn_name) */ 22097c478bd9Sstevel@tonic-gate uint32_t fn_refcnt; /* reference count */ 22107c478bd9Sstevel@tonic-gate kmutex_t fn_lock; 22117c478bd9Sstevel@tonic-gate avl_node_t fn_tree; 22127c478bd9Sstevel@tonic-gate avl_tree_t fn_children; /* children, if any */ 2213be6d98b1SNagakiran Rajashekar nfs4_sharedfh_t *fn_sfh; /* The fh for this fname */ 22147c478bd9Sstevel@tonic-gate } nfs4_fname_t; 22157c478bd9Sstevel@tonic-gate 22167c478bd9Sstevel@tonic-gate #ifdef _KERNEL 22177c478bd9Sstevel@tonic-gate 22187c478bd9Sstevel@tonic-gate extern vnode_t nfs4_xattr_notsupp_vnode; 22197c478bd9Sstevel@tonic-gate #define NFS4_XATTR_DIR_NOTSUPP &nfs4_xattr_notsupp_vnode 22207c478bd9Sstevel@tonic-gate 2221bbf2a467SNagakiran Rajashekar extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *); 22227c478bd9Sstevel@tonic-gate extern void fn_hold(nfs4_fname_t *); 22237c478bd9Sstevel@tonic-gate extern void fn_rele(nfs4_fname_t **); 22247c478bd9Sstevel@tonic-gate extern char *fn_name(nfs4_fname_t *); 22257c478bd9Sstevel@tonic-gate extern char *fn_path(nfs4_fname_t *); 22267c478bd9Sstevel@tonic-gate extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *); 22277c478bd9Sstevel@tonic-gate extern nfs4_fname_t *fn_parent(nfs4_fname_t *); 22287c478bd9Sstevel@tonic-gate 22292f172c55SRobert Thurlow /* Referral Support */ 22302f172c55SRobert Thurlow extern int nfs4_process_referral(mntinfo4_t *, nfs4_sharedfh_t *, char *, 22312f172c55SRobert Thurlow cred_t *, nfs4_ga_res_t *, COMPOUND4res_clnt *, struct nfs_fsl_info *); 22322f172c55SRobert Thurlow 22337c478bd9Sstevel@tonic-gate #endif 22347c478bd9Sstevel@tonic-gate 22357c478bd9Sstevel@tonic-gate /* 22367c478bd9Sstevel@tonic-gate * Per-zone data for managing client handles, included in this file for the 22377c478bd9Sstevel@tonic-gate * benefit of MDB. 22387c478bd9Sstevel@tonic-gate */ 22397c478bd9Sstevel@tonic-gate struct nfs4_clnt { 22407c478bd9Sstevel@tonic-gate struct chhead *nfscl_chtable4; 22417c478bd9Sstevel@tonic-gate kmutex_t nfscl_chtable4_lock; 22427c478bd9Sstevel@tonic-gate zoneid_t nfscl_zoneid; 22437c478bd9Sstevel@tonic-gate list_node_t nfscl_node; 22447c478bd9Sstevel@tonic-gate struct clstat4 nfscl_stat; 22457c478bd9Sstevel@tonic-gate }; 22467c478bd9Sstevel@tonic-gate 22477c478bd9Sstevel@tonic-gate #ifdef __cplusplus 22487c478bd9Sstevel@tonic-gate } 22497c478bd9Sstevel@tonic-gate #endif 22507c478bd9Sstevel@tonic-gate 22517c478bd9Sstevel@tonic-gate #endif /* _NFS4_CLNT_H */ 2252