Move CallBack Server thread creation, initial processing and destruction to RPC
Cleanup some RPC code.
Remove extraneous fields from nfs41_cb_info and clean up the code.
Change KM_SLEEP in mir_nfs41_callback_thread to KM_NOSLEEP.
Fix lint warnings

   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27 /*      All Rights Reserved   */
  28 
  29 /*
  30  * Portions of this source code were derived from Berkeley 4.3 BSD
  31  * under license from the Regents of the University of California.
  32  */
  33 
  34 #ifndef _NFS4_CLNT_H
  35 #define _NFS4_CLNT_H
  36 
  37 #include <sys/errno.h>
  38 #include <sys/types.h>
  39 #include <sys/kstat.h>
  40 #include <sys/time.h>
  41 #include <sys/flock.h>
  42 #include <vm/page.h>
  43 #include <nfs/nfs4_kprot.h>
  44 #include <nfs/nfs4.h>
  45 #include <nfs/rnode.h>
  46 #include <sys/avl.h>
  47 #include <sys/list.h>
  48 #include <rpc/auth.h>
  49 #include <sys/taskq.h>
  50 
  51 #ifdef  __cplusplus
  52 extern "C" {
  53 #endif
  54 
  55 #define NFS4_SIZE_OK(size)      ((size) <= MAXOFFSET_T)
  56 
  57 /* Client Sequence Heartbeat Flag bits */
  58 #define NFS4_SEQHB_STARTED              1
  59 #define NFS4_SEQHB_EXITING              2
  60 #define NFS4_SEQHB_EXIT                 4
  61 #define NFS4_SEQHB_DESTROY              8
  62 
  63 /* Four states of nfs4_server's lease_valid */
  64 #define NFS4_LEASE_INVALID              0
  65 #define NFS4_LEASE_VALID                1
  66 #define NFS4_LEASE_UNINITIALIZED        2
  67 #define NFS4_LEASE_NOT_STARTED          3
  68 
  69 /*
  70  * rfs4call() flags
  71  * NOTE: rfscall() can take RFSCALL_SOFT which is defined as 1 so start at 2
  72  */
  73 #define RFS4CALL_SETCB  0x00000002
  74 #define RFS4CALL_NOSEQ  0x00000004      /* Don't add sequence op (4.1+ only) */
  75 
  76 #define NFS4_TAG_SWAP           0x001
  77 #define NFS4_TAG_DESTROY        0x002
  78 #define NFS4_CBSERVER_CLEANUP   0x004
  79 
  80 /* flag to tell the renew thread it should exit */
  81 #define NFS4_THREAD_EXIT        1
  82 
  83 /* Default number of seconds to wait on GRACE and DELAY errors */
  84 #define NFS4ERR_DELAY_TIME      10
  85 
  86 /* Number of hash buckets for open owners for each nfs4_server */
  87 #define NFS4_NUM_OO_BUCKETS     53
  88 
  89 /* Number of freed open owners (per mntinfo4_t) to keep around */
  90 #define NFS4_NUM_FREED_OPEN_OWNERS      8
  91 
  92 /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */
  93 #define NFS4_RETRY_SCLID_DELAY  10
  94 
  95 /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */
  96 #define NFS4_NUM_SCLID_RETRIES  3
  97 
  98 /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */
  99 #define NFS4_NUM_RETRY_BAD_SEQID        3
 100 
 101 /*
 102  * Is the attribute cache valid?  If client holds a delegation, then attrs
 103  * are by definition valid.  If not, then check to see if attrs have timed out.
 104  */
 105 #define ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \
 106         gethrtime() < VTOR4(vp)->r_time_attr_inval)
 107 
 108 /*
 109  * Flags to indicate whether to purge the DNLC for non-directory vnodes
 110  * in a call to nfs_purge_caches.
 111  */
 112 #define NFS4_NOPURGE_DNLC       0
 113 #define NFS4_PURGE_DNLC         1
 114 
 115 /*
 116  * Is cache valid?
 117  * Swap is always valid, if no attributes (attrtime == 0) or
 118  * if mtime matches cached mtime it is valid
 119  * NOTE: mtime is now a timestruc_t.
 120  * Caller should be holding the rnode r_statelock mutex.
 121  */
 122 #define CACHE4_VALID(rp, mtime, fsize)                          \
 123         ((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP ||             \
 124         (((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec &&  \
 125         (mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \
 126         ((fsize) == (rp)->r_attr.va_size)))
 127 
 128 /*
 129  * Macro to detect forced unmount or a zone shutdown.
 130  */
 131 #define FS_OR_ZONE_GONE4(vfsp) \
 132         (((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
 133         zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
 134 
 135 /*
 136  * Macro to help determine whether a request failed because the underlying
 137  * filesystem has been forcibly unmounted or because of zone shutdown.
 138  */
 139 #define NFS4_FRC_UNMT_ERR(err, vfsp) \
 140         ((err) == EIO && FS_OR_ZONE_GONE4((vfsp)))
 141 
 142 
 143 /*
 144  * Returns TRUE if there are sessions related recoverable errors
 145  */
 146 #define NFS4_NEED_SESS_RECOV(np) \
 147             (!(np->s_flags & N4S_SESSION_CREATED) || \
 148             (np->s_flags & N4S_NEED_BC2S))
 149 
 150 #define NFS41_SERVER(np) (np->s_minorversion == 1)
 151 
 152 /*
 153  * Client zone key for global zone list of callback info.
 154  */
 155 zone_key_t nfs4clnt_zone_key;
 156 
 157 /*
 158  * Due to the way the address space callbacks are used to execute a delmap,
 159  * we must keep track of how many times the same thread has called
 160  * VOP_DELMAP()->nfs4_delmap().  This is done by having a list of
 161  * nfs4_delmapcall_t's associated with each rnode4_t.  This list is protected
 162  * by the rnode4_t's r_statelock.  The individual elements do not need to be
 163  * protected as they will only ever be created, modified and destroyed by
 164  * one thread (the call_id).
 165  * See nfs4_delmap() for further explanation.
 166  */
 167 typedef struct nfs4_delmapcall {
 168         kthread_t       *call_id;
 169         int             error;  /* error from delmap */
 170         list_node_t     call_node;
 171 } nfs4_delmapcall_t;
 172 
 173 /*
 174  * delmap address space callback args
 175  */
 176 typedef struct nfs4_delmap_args {
 177         vnode_t                 *vp;
 178         offset_t                off;
 179         caddr_t                 addr;
 180         size_t                  len;
 181         uint_t                  prot;
 182         uint_t                  maxprot;
 183         uint_t                  flags;
 184         cred_t                  *cr;
 185         nfs4_delmapcall_t       *caller; /* to retrieve errors from the cb */
 186 } nfs4_delmap_args_t;
 187 
 188 /*
 189  * client side statistics
 190  */
 191 /*
 192  * Per-zone counters
 193  */
 194 struct clstat4 {
 195         kstat_named_t   calls;                  /* client requests */
 196         kstat_named_t   badcalls;               /* rpc failures */
 197         kstat_named_t   clgets;                 /* client handle gets */
 198         kstat_named_t   cltoomany;              /* client handle cache misses */
 199 };
 200 
 201 #ifdef DEBUG
 202 /*
 203  * The following are statistics that describe the behavior of the system as a
 204  * whole and don't correspond to any particular zone.
 205  */
 206 struct clstat4_debug {
 207         kstat_named_t   clalloc;                /* number of client handles */
 208         kstat_named_t   noresponse;             /* server not responding cnt */
 209         kstat_named_t   failover;               /* server failover count */
 210         kstat_named_t   remap;                  /* server remap count */
 211         kstat_named_t   nrnode;                 /* number of allocated rnodes */
 212         kstat_named_t   access;                 /* size of access cache */
 213         kstat_named_t   dirent;                 /* size of readdir cache */
 214         kstat_named_t   dirents;                /* size of readdir buf cache */
 215         kstat_named_t   reclaim;                /* number of reclaims */
 216         kstat_named_t   clreclaim;              /* number of cl reclaims */
 217         kstat_named_t   f_reclaim;              /* number of free reclaims */
 218         kstat_named_t   a_reclaim;              /* number of active reclaims */
 219         kstat_named_t   r_reclaim;              /* number of rnode reclaims */
 220         kstat_named_t   rpath;                  /* bytes used to store rpaths */
 221 };
 222 extern struct clstat4_debug clstat4_debug;
 223 
 224 #endif
 225 
 226 /*
 227  * The NFS specific async_reqs structure.
 228  */
 229 
 230 enum iotype4 {
 231         NFS4_READ_AHEAD,
 232         NFS4_PUTAPAGE,
 233         NFS4_PAGEIO,
 234         NFS4_READDIR,
 235         NFS4_INACTIVE,
 236         NFS4_COMMIT
 237 };
 238 #define NFS4_ASYNC_TYPES        (NFS4_COMMIT + 1)
 239 
 240 struct nfs4_async_read_req {
 241         void (*readahead)();            /* pointer to readahead function */
 242         u_offset_t blkoff;              /* offset in file */
 243         struct seg *seg;                /* segment to do i/o to */
 244         caddr_t addr;                   /* address to do i/o to */
 245 };
 246 
 247 struct nfs4_pageio_req {
 248         int (*pageio)();                /* pointer to pageio function */
 249         page_t *pp;                     /* page list */
 250         u_offset_t io_off;              /* offset in file */
 251         uint_t io_len;                  /* size of request */
 252         int flags;
 253 };
 254 
 255 struct nfs4_readdir_req {
 256         int (*readdir)();               /* pointer to readdir function */
 257         struct rddir4_cache *rdc;       /* pointer to cache entry to fill */
 258 };
 259 
 260 struct nfs4_commit_req {
 261         void (*commit)();               /* pointer to commit function */
 262         page_t *plist;                  /* page list */
 263         offset4 offset;                 /* starting offset */
 264         count4 count;                   /* size of range to be commited */
 265 };
 266 
 267 struct nfs4_async_reqs {
 268         struct nfs4_async_reqs *a_next; /* pointer to next arg struct */
 269 #ifdef DEBUG
 270         kthread_t *a_queuer;            /* thread id of queueing thread */
 271 #endif
 272         struct vnode *a_vp;             /* vnode pointer */
 273         struct cred *a_cred;            /* cred pointer */
 274         enum iotype4 a_io;              /* i/o type */
 275         union {
 276                 struct nfs4_async_read_req a_read_args;
 277                 struct nfs4_pageio_req a_pageio_args;
 278                 struct nfs4_readdir_req a_readdir_args;
 279                 struct nfs4_commit_req a_commit_args;
 280         } a_args;
 281 };
 282 
 283 #define a_nfs4_readahead a_args.a_read_args.readahead
 284 #define a_nfs4_blkoff a_args.a_read_args.blkoff
 285 #define a_nfs4_seg a_args.a_read_args.seg
 286 #define a_nfs4_addr a_args.a_read_args.addr
 287 
 288 #define a_nfs4_putapage a_args.a_pageio_args.pageio
 289 #define a_nfs4_pageio a_args.a_pageio_args.pageio
 290 #define a_nfs4_pp a_args.a_pageio_args.pp
 291 #define a_nfs4_off a_args.a_pageio_args.io_off
 292 #define a_nfs4_len a_args.a_pageio_args.io_len
 293 #define a_nfs4_flags a_args.a_pageio_args.flags
 294 
 295 #define a_nfs4_readdir a_args.a_readdir_args.readdir
 296 #define a_nfs4_rdc a_args.a_readdir_args.rdc
 297 
 298 #define a_nfs4_commit a_args.a_commit_args.commit
 299 #define a_nfs4_plist a_args.a_commit_args.plist
 300 #define a_nfs4_offset a_args.a_commit_args.offset
 301 #define a_nfs4_count a_args.a_commit_args.count
 302 
 303 /*
 304  * Security information
 305  */
 306 typedef struct sv_secinfo {
 307         uint_t          count;  /* how many sdata there are */
 308         uint_t          index;  /* which sdata[index] */
 309         struct sec_data *sdata;
 310 } sv_secinfo_t;
 311 
 312 /*
 313  * Hash bucket for the mi's open owner list (mi_oo_list).
 314  */
 315 typedef struct nfs4_oo_hash_bucket {
 316         list_t                  b_oo_hash_list;
 317         kmutex_t                b_lock;
 318 } nfs4_oo_hash_bucket_t;
 319 
 320 /*
 321  * Global array of ctags.
 322  */
 323 extern ctag_t nfs4_ctags[];
 324 
 325 typedef enum nfs4_tag_type {
 326         TAG_NONE,
 327         TAG_ACCESS,
 328         TAG_CLOSE,
 329         TAG_CLOSE_LOST,
 330         TAG_CLOSE_UNDO,
 331         TAG_COMMIT,
 332         TAG_DELEGRETURN,
 333         TAG_FSINFO,
 334         TAG_GET_SYMLINK,
 335         TAG_GETATTR,
 336         TAG_INACTIVE,
 337         TAG_LINK,
 338         TAG_LOCK,
 339         TAG_LOCK_RECLAIM,
 340         TAG_LOCK_RESEND,
 341         TAG_LOCK_REINSTATE,
 342         TAG_LOCK_UNKNOWN,
 343         TAG_LOCKT,
 344         TAG_LOCKU,
 345         TAG_LOCKU_RESEND,
 346         TAG_LOCKU_REINSTATE,
 347         TAG_LOOKUP,
 348         TAG_LOOKUP_PARENT,
 349         TAG_LOOKUP_VALID,
 350         TAG_LOOKUP_VPARENT,
 351         TAG_MKDIR,
 352         TAG_MKNOD,
 353         TAG_MOUNT,
 354         TAG_OPEN,
 355         TAG_OPEN_CONFIRM,
 356         TAG_OPEN_CONFIRM_LOST,
 357         TAG_OPEN_DG,
 358         TAG_OPEN_DG_LOST,
 359         TAG_OPEN_LOST,
 360         TAG_OPENATTR,
 361         TAG_PATHCONF,
 362         TAG_PUTROOTFH,
 363         TAG_READ,
 364         TAG_READAHEAD,
 365         TAG_READDIR,
 366         TAG_READLINK,
 367         TAG_RELOCK,
 368         TAG_REMAP_LOOKUP,
 369         TAG_REMAP_LOOKUP_AD,
 370         TAG_REMAP_LOOKUP_NA,
 371         TAG_REMAP_MOUNT,
 372         TAG_RMDIR,
 373         TAG_REMOVE,
 374         TAG_RENAME,
 375         TAG_RENAME_VFH,
 376         TAG_RENEW,
 377         TAG_REOPEN,
 378         TAG_REOPEN_LOST,
 379         TAG_SECINFO,
 380         TAG_SETATTR,
 381         TAG_SETCLIENTID,
 382         TAG_SETCLIENTID_CF,
 383         TAG_SYMLINK,
 384         TAG_WRITE,
 385         TAG_EXCHANGE_ID,                        /* XXX - rick */
 386         TAG_CREATE_SESSION,
 387         TAG_BIND_CONN_TO_SESSION,
 388         TAG_PNFS_READ,
 389         TAG_PNFS_WRITE,
 390         TAG_PNFS_COMMIT,
 391         TAG_PNFS_LAYOUTGET,
 392         TAG_PNFS_LAYOUTRETURN,
 393         TAG_PNFS_GETDEVLIST,
 394         TAG_SEQUENCE,
 395         TAG_DESTROY_SESSION,
 396         TAG_PNFS_GETDEVINFO,
 397         TAG_RECLAIM_COMPLETE
 398 } nfs4_tag_type_t;
 399 
 400 #define NFS4_TAG_INITIALIZER    {                               \
 401                 {TAG_NONE,              "",                     \
 402                         {0x20202020, 0x20202020, 0x20202020}},  \
 403                 {TAG_ACCESS,            "access",               \
 404                         {0x61636365, 0x73732020, 0x20202020}},  \
 405                 {TAG_CLOSE,             "close",                \
 406                         {0x636c6f73, 0x65202020, 0x20202020}},  \
 407                 {TAG_CLOSE_LOST,        "lost close",           \
 408                         {0x6c6f7374, 0x20636c6f, 0x73652020}},  \
 409                 {TAG_CLOSE_UNDO,        "undo close",           \
 410                         {0x756e646f, 0x20636c6f, 0x73652020}},  \
 411                 {TAG_COMMIT,            "commit",               \
 412                         {0x636f6d6d, 0x69742020, 0x20202020}},  \
 413                 {TAG_DELEGRETURN,       "delegreturn",          \
 414                         {0x64656c65, 0x67726574, 0x75726e20}},  \
 415                 {TAG_FSINFO,            "fsinfo",               \
 416                         {0x6673696e, 0x666f2020, 0x20202020}},  \
 417                 {TAG_GET_SYMLINK,       "get symlink text",     \
 418                         {0x67657420, 0x736c6e6b, 0x20747874}},  \
 419                 {TAG_GETATTR,           "getattr",              \
 420                         {0x67657461, 0x74747220, 0x20202020}},  \
 421                 {TAG_INACTIVE,          "inactive",             \
 422                         {0x696e6163, 0x74697665, 0x20202020}},  \
 423                 {TAG_LINK,              "link",                 \
 424                         {0x6c696e6b, 0x20202020, 0x20202020}},  \
 425                 {TAG_LOCK,              "lock",                 \
 426                         {0x6c6f636b, 0x20202020, 0x20202020}},  \
 427                 {TAG_LOCK_RECLAIM,      "reclaim lock",         \
 428                         {0x7265636c, 0x61696d20, 0x6c6f636b}},  \
 429                 {TAG_LOCK_RESEND,       "resend lock",          \
 430                         {0x72657365, 0x6e64206c, 0x6f636b20}},  \
 431                 {TAG_LOCK_REINSTATE,    "reinstate lock",       \
 432                         {0x7265696e, 0x7374206c, 0x6f636b20}},  \
 433                 {TAG_LOCK_UNKNOWN,      "unknown lock",         \
 434                         {0x756e6b6e, 0x6f776e20, 0x6c6f636b}},  \
 435                 {TAG_LOCKT,             "lock test",            \
 436                         {0x6c6f636b, 0x5f746573, 0x74202020}},  \
 437                 {TAG_LOCKU,             "unlock",               \
 438                         {0x756e6c6f, 0x636b2020, 0x20202020}},  \
 439                 {TAG_LOCKU_RESEND,      "resend locku",         \
 440                         {0x72657365, 0x6e64206c, 0x6f636b75}},  \
 441                 {TAG_LOCKU_REINSTATE,   "reinstate unlock",     \
 442                         {0x7265696e, 0x73742075, 0x6e6c636b}},  \
 443                 {TAG_LOOKUP,            "lookup",               \
 444                         {0x6c6f6f6b, 0x75702020, 0x20202020}},  \
 445                 {TAG_LOOKUP_PARENT,     "lookup parent",        \
 446                         {0x6c6f6f6b, 0x75702070, 0x6172656e}},  \
 447                 {TAG_LOOKUP_VALID,      "lookup valid",         \
 448                         {0x6c6f6f6b, 0x75702076, 0x616c6964}},  \
 449                 {TAG_LOOKUP_VPARENT,    "lookup valid parent",  \
 450                         {0x6c6f6f6b, 0x766c6420, 0x7061726e}},  \
 451                 {TAG_MKDIR,             "mkdir",                \
 452                         {0x6d6b6469, 0x72202020, 0x20202020}},  \
 453                 {TAG_MKNOD,             "mknod",                \
 454                         {0x6d6b6e6f, 0x64202020, 0x20202020}},  \
 455                 {TAG_MOUNT,             "mount",                \
 456                         {0x6d6f756e, 0x74202020, 0x20202020}},  \
 457                 {TAG_OPEN,              "open",                 \
 458                         {0x6f70656e, 0x20202020, 0x20202020}},  \
 459                 {TAG_OPEN_CONFIRM,      "open confirm",         \
 460                         {0x6f70656e, 0x5f636f6e, 0x6669726d}},  \
 461                 {TAG_OPEN_CONFIRM_LOST, "lost open confirm",    \
 462                         {0x6c6f7374, 0x206f7065, 0x6e5f636f}},  \
 463                 {TAG_OPEN_DG,           "open downgrade",       \
 464                         {0x6f70656e, 0x20646772, 0x61646520}},  \
 465                 {TAG_OPEN_DG_LOST,      "lost open downgrade",  \
 466                         {0x6c737420, 0x6f70656e, 0x20646772}},  \
 467                 {TAG_OPEN_LOST,         "lost open",            \
 468                         {0x6c6f7374, 0x206f7065, 0x6e202020}},  \
 469                 {TAG_OPENATTR,          "openattr",             \
 470                         {0x6f70656e, 0x61747472, 0x20202020}},  \
 471                 {TAG_PATHCONF,          "pathhconf",            \
 472                         {0x70617468, 0x636f6e66, 0x20202020}},  \
 473                 {TAG_PUTROOTFH,         "putrootfh",            \
 474                         {0x70757472, 0x6f6f7466, 0x68202020}},  \
 475                 {TAG_READ,              "read",                 \
 476                         {0x72656164, 0x20202020, 0x20202020}},  \
 477                 {TAG_READAHEAD,         "readahead",            \
 478                         {0x72656164, 0x61686561, 0x64202020}},  \
 479                 {TAG_READDIR,           "readdir",              \
 480                         {0x72656164, 0x64697220, 0x20202020}},  \
 481                 {TAG_READLINK,          "readlink",             \
 482                         {0x72656164, 0x6c696e6b, 0x20202020}},  \
 483                 {TAG_RELOCK,            "relock",               \
 484                         {0x72656c6f, 0x636b2020, 0x20202020}},  \
 485                 {TAG_REMAP_LOOKUP,      "remap lookup",         \
 486                         {0x72656d61, 0x70206c6f, 0x6f6b7570}},  \
 487                 {TAG_REMAP_LOOKUP_AD,   "remap lookup attr dir",        \
 488                         {0x72656d70, 0x206c6b75, 0x70206164}},  \
 489                 {TAG_REMAP_LOOKUP_NA,   "remap lookup named attrs",     \
 490                         {0x72656d70, 0x206c6b75, 0x70206e61}},  \
 491                 {TAG_REMAP_MOUNT,       "remap mount",          \
 492                         {0x72656d61, 0x70206d6f, 0x756e7420}},  \
 493                 {TAG_RMDIR,             "rmdir",                \
 494                         {0x726d6469, 0x72202020, 0x20202020}},  \
 495                 {TAG_REMOVE,            "remove",               \
 496                         {0x72656d6f, 0x76652020, 0x20202020}},  \
 497                 {TAG_RENAME,            "rename",               \
 498                         {0x72656e61, 0x6d652020, 0x20202020}},  \
 499                 {TAG_RENAME_VFH,        "rename volatile fh",   \
 500                         {0x72656e61, 0x6d652028, 0x76666829}},  \
 501                 {TAG_RENEW,             "renew",                \
 502                         {0x72656e65, 0x77202020, 0x20202020}},  \
 503                 {TAG_REOPEN,            "reopen",               \
 504                         {0x72656f70, 0x656e2020, 0x20202020}},  \
 505                 {TAG_REOPEN_LOST,       "lost reopen",          \
 506                         {0x6c6f7374, 0x2072656f, 0x70656e20}},  \
 507                 {TAG_SECINFO,           "secinfo",              \
 508                         {0x73656369, 0x6e666f20, 0x20202020}},  \
 509                 {TAG_SETATTR,           "setattr",              \
 510                         {0x73657461, 0x74747220, 0x20202020}},  \
 511                 {TAG_SETCLIENTID,       "setclientid",          \
 512                         {0x73657463, 0x6c69656e, 0x74696420}},  \
 513                 {TAG_SETCLIENTID_CF,    "setclientid_confirm",  \
 514                         {0x73636c6e, 0x7469645f, 0x636f6e66}},  \
 515                 {TAG_SYMLINK,           "symlink",              \
 516                         {0x73796d6c, 0x696e6b20, 0x20202020}},  \
 517                 {TAG_WRITE,             "write",                \
 518                         {0x77726974, 0x65202020, 0x20202020}},  \
 519                 {TAG_EXCHANGE_ID,       "exchange_id",  \
 520                         {0x65786368, 0x616e6765, 0x5f696420}},  \
 521                 {TAG_CREATE_SESSION,    "create_session",       \
 522                         {0x63726561, 0x74655f73, 0x65737369}},  \
 523                 {TAG_BIND_CONN_TO_SESSION,      "bind_conn_to_session", \
 524                         {0x62696e64, 0x5f636f6e, 0x6e5f746f}},  \
 525                 {TAG_PNFS_READ,         "pnfs read",            \
 526                         {0x706e6673, 0x20726561, 0x64202020}},  \
 527                 {TAG_PNFS_WRITE,                "pnfs write",   \
 528                         {0x706e6673, 0x20777269, 0x74652020}},  \
 529                 {TAG_PNFS_COMMIT,               "pnfs commit",  \
 530                         {0x706e6673, 0x20636f6d, 0x6d697420}},  \
 531                 {TAG_PNFS_LAYOUTGET,            "layoutget",    \
 532                         {0x6c61796f, 0x75746765, 0x74202020}},  \
 533                 {TAG_PNFS_LAYOUTRETURN,         "layoutreturn", \
 534                         {0x6c61796f, 0x75747265, 0x7475726e}},  \
 535                 {TAG_PNFS_GETDEVLIST,           "pnfs devlist", \
 536                         {0x706e6673, 0x20646576, 0x6c697374}},  \
 537                 {TAG_SEQUENCE,                  "sequence",     \
 538                         {0x73657175, 0x656e6365, 0x20202020}},  \
 539                 {TAG_DESTROY_SESSION,           "destroy session", \
 540                         {0x64657374, 0x726f7920, 0x73657373}},  \
 541                 {TAG_PNFS_GETDEVINFO,           "getdeviceinf", \
 542                         {0x67657464, 0x65766963, 0x65696e66}},  \
 543                 {TAG_RECLAIM_COMPLETE,          "reclaim complete", \
 544                         {0x7265636c, 0x61696d20, 0x636f6d70}}   \
 545         }
 546 
 547 /*
 548  * These flags are for differentiating the search criterian for
 549  * find_open_owner().  The comparison is done with the open_owners's
 550  * 'oo_just_created' flag.
 551  */
 552 #define NFS4_PERM_CREATED       0x0
 553 #define NFS4_JUST_CREATED       0x1
 554 
 555 /*
 556  * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw'
 557  * is stored upon a successful OPEN.  This is needed when the user's effective
 558  * and real uid's don't match.  The 'oo_cred_otw' overrides the credential
 559  * passed down by VFS for async read/write, commit, lock, and close operations.
 560  *
 561  * The oo_ref_count keeps track the number of active references on this
 562  * data structure + number of nfs4_open_streams point to this structure.
 563  *
 564  * 'oo_valid' tells whether this stuct is about to be freed or not.
 565  *
 566  * 'oo_just_created' tells us whether this struct has just been created but
 567  * not been fully finalized (that is created upon an OPEN request and
 568  * finalized upon the OPEN success).
 569  *
 570  * The 'oo_seqid_inuse' is for the open seqid synchronization.  If a thread
 571  * is currently using the open owner and it's open_seqid, then it sets the
 572  * oo_seqid_inuse to true if it currently is not set.  If it is set then it
 573  * does a cv_wait on the oo_cv_seqid_sync condition variable.  When the thread
 574  * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process
 575  * waiting on the condition variable.
 576  *
 577  * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW,
 578  * and 'oo_last_good_op' is the operation that issued the last valid seqid.
 579  *
 580  * Lock ordering:
 581  *      mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list)
 582  *
 583  *      oo_seqid_inuse > mntinfo4_t::mi_lock
 584  *      oo_seqid_inuse > rnode4_t::r_statelock
 585  *      oo_seqid_inuse > rnode4_t::r_statev4_lock
 586  *      oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock
 587  *
 588  * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects:
 589  *      oo_last_good_op
 590  *      oo_last_good_seqid
 591  *      oo_name
 592  *      oo_seqid
 593  *
 594  * The 'oo_lock' protects:
 595  *      oo_cred
 596  *      oo_cred_otw
 597  *      oo_foo_node
 598  *      oo_hash_node
 599  *      oo_just_created
 600  *      oo_ref_count
 601  *      oo_valid
 602  */
 603 
 604 typedef struct nfs4_open_owner {
 605         cred_t                  *oo_cred;
 606         int                     oo_ref_count;
 607         int                     oo_valid;
 608         int                     oo_just_created;
 609         seqid4                  oo_seqid;
 610         seqid4                  oo_last_good_seqid;
 611         nfs4_tag_type_t         oo_last_good_op;
 612         unsigned                oo_seqid_inuse:1;
 613         cred_t                  *oo_cred_otw;
 614         kcondvar_t              oo_cv_seqid_sync;
 615         /*
 616          * Fix this to always be 8 bytes
 617          */
 618         uint64_t                oo_name;
 619         list_node_t             oo_hash_node;
 620         list_node_t             oo_foo_node;
 621         kmutex_t                oo_lock;
 622 } nfs4_open_owner_t;
 623 
 624 /*
 625  * Static server information.
 626  * These fields are read-only once they are initialized:
 627  *      sv_addr
 628  *      sv_dhsec
 629  *      sv_hostname
 630  *      sv_hostnamelen
 631  *      sv_knconf
 632  *      sv_next
 633  *      sv_origknconf
 634  *
 635  * These fields are protected by sv_lock:
 636  *      sv_currsec
 637  *      sv_fhandle
 638  *      sv_flags
 639  *      sv_fsid
 640  *      sv_path
 641  *      sv_pathlen
 642  *      sv_pfhandle
 643  *      sv_save_secinfo
 644  *      sv_savesec
 645  *      sv_secdata
 646  *      sv_secinfo
 647  *      sv_supp_attrs
 648  *
 649  * Lock ordering:
 650  * nfs_rtable4_lock > sv_lock
 651  * rnode4_t::r_statelock > sv_lock
 652  */
 653 typedef struct servinfo4 {
 654         struct knetconfig *sv_knconf;   /* bound TLI fd */
 655         struct knetconfig *sv_origknconf;       /* For RDMA save orig knconf */
 656         struct netbuf      sv_addr;     /* server's address */
 657         nfs4_fhandle_t     sv_fhandle;  /* this server's filehandle */
 658         nfs4_fhandle_t     sv_pfhandle; /* parent dir filehandle */
 659         int                sv_pathlen;  /* Length of server path */
 660         char              *sv_path;     /* Path name on server */
 661         uint32_t           sv_flags;    /* flags for this server */
 662         sec_data_t        *sv_secdata;  /* client initiated security data */
 663         sv_secinfo_t      *sv_secinfo;  /* server security information */
 664         sec_data_t        *sv_currsec;  /* security data currently used; */
 665                                         /* points to one of the sec_data */
 666                                         /* entries in sv_secinfo */
 667         sv_secinfo_t      *sv_save_secinfo; /* saved secinfo */
 668         sec_data_t        *sv_savesec;  /* saved security data */
 669         sec_data_t        *sv_dhsec;    /* AUTH_DH data from the user land */
 670         char              *sv_hostname; /* server's hostname */
 671         int                sv_hostnamelen;  /* server's hostname length */
 672         fattr4_fsid             sv_fsid;    /* fsid of shared obj       */
 673         attrmap4        sv_supp_attrs;
 674         struct servinfo4  *sv_next;     /* next in list */
 675         nfs_rwlock_t       sv_lock;
 676         /*
 677          * XXXrsb - the following (sv_ds_n4sp) is likely to change.
 678          * If the servinfo4 refers to a pnfs data server, then the following
 679          * is a pointer to the corresponding nfs4_server.  Otherwise, NULL.
 680          */
 681         struct nfs4_server *sv_ds_n4sp;
 682         attrmap4        sv_supp_exclcreat;
 683 } servinfo4_t;
 684 
 685 /* sv_flags fields */
 686 #define SV4_TRYSECINFO          0x001   /* try secinfo data from the server */
 687 #define SV4_TRYSECDEFAULT       0x002   /* try a default flavor */
 688 #define SV4_NOTINUSE            0x004   /* servinfo4_t had fatal errors */
 689 #define SV4_ROOT_STALE          0x008   /* root vnode got ESTALE */
 690 #define SV4_ISA_DS              0x010   /* this is a data server! */
 691 
 692 /*
 693  * Lock call types.  See nfs4frlock().
 694  */
 695 typedef enum nfs4_lock_call_type {
 696         NFS4_LCK_CTYPE_NORM,
 697         NFS4_LCK_CTYPE_RECLAIM,
 698         NFS4_LCK_CTYPE_RESEND,
 699         NFS4_LCK_CTYPE_REINSTATE
 700 } nfs4_lock_call_type_t;
 701 
 702 /*
 703  * This structure holds the information for a lost open/close/open downgrade/
 704  * lock/locku request.  It is also used for requests that are queued up so
 705  * that the recovery thread can release server state after a forced
 706  * unmount.
 707  * "lr_op" is 0 if the struct is uninitialized.  Otherwise, it is set to
 708  * the proper OP_* nfs_opnum4 number.  The other fields contain information
 709  * to reconstruct the call.
 710  *
 711  * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the
 712  * parent directroy without relying on vtodv (since we may not have a vp
 713  * for the file we wish to create).
 714  *
 715  * lr_putfirst means that the request should go to the front of the resend
 716  * queue, rather than the end.
 717  */
 718 typedef struct nfs4_lost_rqst {
 719         list_node_t                     lr_node;
 720         nfs_opnum4                      lr_op;
 721         vnode_t                         *lr_vp;
 722         vnode_t                         *lr_dvp;
 723         nfs4_open_owner_t               *lr_oop;
 724         struct nfs4_open_stream         *lr_osp;
 725         struct nfs4_lock_owner          *lr_lop;
 726         cred_t                          *lr_cr;
 727         flock64_t                       *lr_flk;
 728         bool_t                          lr_putfirst;
 729         union {
 730                 struct {
 731                         nfs4_lock_call_type_t lru_ctype;
 732                         nfs_lock_type4  lru_locktype;
 733                 } lru_lockargs;         /* LOCK, LOCKU */
 734                 struct {
 735                         uint32_t                lru_oaccess;
 736                         uint32_t                lru_odeny;
 737                         enum open_claim_type4   lru_oclaim;
 738                         stateid4                lru_ostateid; /* reopen only */
 739                         component4              lru_ofile;
 740                 } lru_open_args;
 741                 struct {
 742                         uint32_t        lru_dg_access;
 743                         uint32_t        lru_dg_deny;
 744                 } lru_open_dg_args;
 745         } nfs4_lr_u;
 746 } nfs4_lost_rqst_t;
 747 
 748 #define lr_oacc         nfs4_lr_u.lru_open_args.lru_oaccess
 749 #define lr_odeny        nfs4_lr_u.lru_open_args.lru_odeny
 750 #define lr_oclaim       nfs4_lr_u.lru_open_args.lru_oclaim
 751 #define lr_ostateid     nfs4_lr_u.lru_open_args.lru_ostateid
 752 #define lr_ofile        nfs4_lr_u.lru_open_args.lru_ofile
 753 #define lr_dg_acc       nfs4_lr_u.lru_open_dg_args.lru_dg_access
 754 #define lr_dg_deny      nfs4_lr_u.lru_open_dg_args.lru_dg_deny
 755 #define lr_ctype        nfs4_lr_u.lru_lockargs.lru_ctype
 756 #define lr_locktype     nfs4_lr_u.lru_lockargs.lru_locktype
 757 
 758 /*
 759  * Recovery actions.  Some actions can imply further recovery using a
 760  * different recovery action (e.g., recovering the clientid leads to
 761  * recovering open files and locks).
 762  */
 763 
 764 typedef enum {
 765         NR_UNUSED,
 766         NR_CLIENTID,
 767         NR_OPENFILES,
 768         NR_FHEXPIRED,
 769         NR_FAILOVER,
 770         NR_WRONGSEC,
 771         NR_EXPIRED,
 772         NR_BAD_STATEID,
 773         NR_BADHANDLE,
 774         NR_BAD_SEQID,
 775         NR_OLDSTATEID,
 776         NR_GRACE,
 777         NR_DELAY,
 778         NR_LOST_LOCK,
 779         NR_LOST_STATE_RQST,
 780         NR_STALE,
 781         NR_BADSESSION,
 782         NR_BC2S
 783 } nfs4_recov_t;
 784 
 785 /*
 786  * Administrative and debug message framework.
 787  */
 788 
 789 #define NFS4_MSG_MAX    100
 790 extern int nfs4_msg_max;
 791 
 792 typedef enum {
 793         RE_BAD_SEQID,
 794         RE_BADHANDLE,
 795         RE_CLIENTID,
 796         RE_DEAD_FILE,
 797         RE_END,
 798         RE_FAIL_RELOCK,
 799         RE_FAIL_REMAP_LEN,
 800         RE_FAIL_REMAP_OP,
 801         RE_FAILOVER,
 802         RE_FILE_DIFF,
 803         RE_LOST_STATE,
 804         RE_OPENS_CHANGED,
 805         RE_SIGLOST,
 806         RE_SIGLOST_NO_DUMP,
 807         RE_START,
 808         RE_UNEXPECTED_ACTION,
 809         RE_UNEXPECTED_ERRNO,
 810         RE_UNEXPECTED_STATUS,
 811         RE_WRONGSEC,
 812         RE_LOST_STATE_BAD_OP
 813 } nfs4_event_type_t;
 814 
 815 typedef enum {
 816         RFS_NO_INSPECT,
 817         RFS_INSPECT
 818 } nfs4_fact_status_t;
 819 
 820 typedef enum {
 821         RF_BADOWNER,
 822         RF_ERR,
 823         RF_RENEW_EXPIRED,
 824         RF_SRV_NOT_RESPOND,
 825         RF_SRV_OK,
 826         RF_SRVS_NOT_RESPOND,
 827         RF_SRVS_OK,
 828         RF_DELMAP_CB_ERR
 829 } nfs4_fact_type_t;
 830 
 831 typedef enum {
 832         NFS4_MS_DUMP,
 833         NFS4_MS_NO_DUMP
 834 } nfs4_msg_status_t;
 835 
 836 typedef struct nfs4_rfact {
 837         nfs4_fact_type_t        rf_type;
 838         nfs4_fact_status_t      rf_status;
 839         bool_t                  rf_reboot;
 840         nfs4_recov_t            rf_action;
 841         nfs_opnum4              rf_op;
 842         nfsstat4                rf_stat4;
 843         timespec_t              rf_time;
 844         int                     rf_error;
 845         struct rnode4           *rf_rp1;
 846         char                    *rf_char1;
 847 } nfs4_rfact_t;
 848 
 849 typedef struct nfs4_revent {
 850         nfs4_event_type_t       re_type;
 851         nfsstat4                re_stat4;
 852         uint_t                  re_uint;
 853         pid_t                   re_pid;
 854         struct mntinfo4         *re_mi;
 855         struct rnode4           *re_rp1;
 856         struct rnode4           *re_rp2;
 857         char                    *re_char1;
 858         char                    *re_char2;
 859         nfs4_tag_type_t         re_tag1;
 860         nfs4_tag_type_t         re_tag2;
 861         seqid4                  re_seqid1;
 862         seqid4                  re_seqid2;
 863 } nfs4_revent_t;
 864 
 865 typedef enum {
 866         RM_EVENT,
 867         RM_FACT
 868 } nfs4_msg_type_t;
 869 
 870 typedef struct nfs4_debug_msg {
 871         timespec_t              msg_time;
 872         nfs4_msg_type_t         msg_type;
 873         char                    *msg_srv;
 874         char                    *msg_mntpt;
 875         union {
 876                 nfs4_rfact_t    msg_fact;
 877                 nfs4_revent_t   msg_event;
 878         } rmsg_u;
 879         nfs4_msg_status_t       msg_status;
 880         list_node_t             msg_node;
 881 } nfs4_debug_msg_t;
 882 
 883 /*
 884  * NFS private data per mounted file system
 885  *      The mi_lock mutex protects the following fields:
 886  *              mi_flags
 887  *              mi_in_recovery
 888  *              mi_recovflags
 889  *              mi_recovthread
 890  *              mi_error
 891  *              mi_printed
 892  *              mi_down
 893  *              mi_stsize
 894  *              mi_curread
 895  *              mi_curwrite
 896  *              mi_timers
 897  *              mi_curr_serv
 898  *              mi_klmconfig
 899  *              mi_oo_list
 900  *              mi_foo_list
 901  *              mi_foo_num
 902  *              mi_foo_max
 903  *              mi_lost_state
 904  *              mi_bseqid_list
 905  *              mi_ephemeral
 906  *              mi_ephemeral_tree
 907  *
 908  *      Normally the netconfig information for the mount comes from
 909  *      mi_curr_serv and mi_klmconfig is NULL.  If NLM calls need to use a
 910  *      different transport, mi_klmconfig contains the necessary netconfig
 911  *      information.
 912  *
 913  *      The mi_async_lock mutex protects the following fields:
 914  *              mi_async_reqs
 915  *              mi_async_req_count
 916  *              mi_async_tail
 917  *              mi_async_curr
 918  *              mi_async_clusters
 919  *              mi_async_init_clusters
 920  *              mi_threads
 921  *              mi_inactive_thread
 922  *              mi_manager_thread
 923  *
 924  *      The nfs4_server_t::s_lock protects the following fields:
 925  *              mi_clientid
 926  *              mi_clientid_next
 927  *              mi_clientid_prev
 928  *              mi_open_files
 929  *              mi_srvsettime
 930  *
 931  *      The mntinfo4_t::mi_recovlock protects the following fields:
 932  *              mi_srvsettime
 933  *
 934  *      Locking order:
 935  *        mi4_globals::mig_lock > mi_async_lock
 936  *        mi_async_lock > nfs4_server_t::s_lock > mi_lock
 937  *        mi_recovlock > mi_rename_lock > nfs_rtable4_lock
 938  *        nfs4_server_t::s_recovlock > mi_recovlock
 939  *        rnode4_t::r_rwlock > mi_rename_lock
 940  *        nfs_rtable4_lock > mi_lock
 941  *        nfs4_server_t::s_lock > mi_msg_list_lock
 942  *        mi_recovlock > nfs4_server_t::s_lock
 943  *        mi_recovlock > nfs4_server_lst_lock
 944  *
 945  * The 'mi_oo_list' represents the hash buckets that contain the
 946  * nfs4_open_owenrs for this particular mntinfo4.
 947  *
 948  * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4.
 949  * 'mi_foo_num' is the current number of freed open owners on the list,
 950  * 'mi_foo_max' is the maximum number of freed open owners that are allowable
 951  * on the list.
 952  *
 953  * mi_rootfh and mi_srvparentfh are read-only once created, but that just
 954  * refers to the pointer.  The contents must be updated to keep in sync
 955  * with mi_curr_serv.
 956  *
 957  * The mi_msg_list_lock protects against adding/deleting entries to the
 958  * mi_msg_list, and also the updating/retrieving of mi_lease_period;
 959  *
 960  * 'mi_zone' is initialized at structure creation time, and never
 961  * changes; it may be read without a lock.
 962  *
 963  * mi_zone_node is linkage into the mi4_globals.mig_list, and is
 964  * protected by mi4_globals.mig_list_lock.
 965  *
 966  * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an
 967  * ephemeral structure for this ephemeral mount point. It can not be
 968  * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral
 969  * tree.
 970  *
 971  * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has
 972  * to be NULL. If mi_ephemeral_tree is non-NULL, then this node
 973  * is the enclosing mntinfo4 for the ephemeral tree.
 974  */
 975 struct zone;
 976 struct nfs4_ephemeral;
 977 struct nfs4_ephemeral_tree;
 978 typedef struct mntinfo4 {
 979         kmutex_t        mi_lock;        /* protects mntinfo4 fields */
 980         struct servinfo4 *mi_servers;   /* server list */
 981         struct servinfo4 *mi_curr_serv; /* current server */
 982         struct nfs4_sharedfh *mi_rootfh; /* root filehandle */
 983         struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */
 984         uint32_t        mi_minorversion;
 985         kcondvar_t      mi_failover_cv; /* failover synchronization */
 986         struct vfs      *mi_vfsp;       /* back pointer to vfs */
 987         enum vtype      mi_type;        /* file type of the root vnode */
 988         uint_t          mi_flags;       /* see below */
 989         uint_t          mi_recovflags;  /* if recovery active; see below */
 990         kthread_t       *mi_recovthread; /* active recov thread or NULL */
 991         uint_t          mi_error;       /* only set/valid when MI4_RECOV_FAIL */
 992                                         /* is set in mi_flags */
 993         int             mi_tsize;       /* transfer size (bytes) */
 994                                         /* really read size */
 995         int             mi_stsize;      /* server's max transfer size (bytes) */
 996                                         /* really write size */
 997         int             mi_timeo;       /* inital timeout in 10th sec */
 998         int             mi_retrans;     /* times to retry request */
 999         hrtime_t        mi_acregmin;    /* min time to hold cached file attr */
1000         hrtime_t        mi_acregmax;    /* max time to hold cached file attr */
1001         hrtime_t        mi_acdirmin;    /* min time to hold cached dir attr */
1002         hrtime_t        mi_acdirmax;    /* max time to hold cached dir attr */
1003         len_t           mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
1004         int             mi_curread;     /* current read size */
1005         int             mi_curwrite;    /* current write size */
1006         uint_t          mi_count;       /* ref count */
1007         /*
1008          * async I/O management.  There may be a pool of threads to handle
1009          * async I/O requests, etc., plus there is always one thread that
1010          * handles over-the-wire requests for VOP_INACTIVE.  The async pool
1011          * can also help out with VOP_INACTIVE.
1012          */
1013         struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES];
1014         struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES];
1015         struct nfs4_async_reqs **mi_async_curr; /* current async queue */
1016         uint_t          mi_async_clusters[NFS4_ASYNC_TYPES];
1017         uint_t          mi_async_init_clusters;
1018         uint_t          mi_async_req_count; /* # outstanding work requests */
1019         kcondvar_t      mi_async_reqs_cv; /* signaled when there's work */
1020         ushort_t        mi_threads;     /* number of active async threads */
1021         ushort_t        mi_max_threads; /* max number of async threads */
1022         kthread_t       *mi_manager_thread; /* async manager thread id */
1023         kthread_t       *mi_inactive_thread; /* inactive thread id */
1024         kcondvar_t      mi_inact_req_cv; /* notify VOP_INACTIVE thread */
1025         kcondvar_t      mi_async_work_cv; /* tell workers to work */
1026         kcondvar_t      mi_async_cv;    /* all pool threads exited */
1027         kmutex_t        mi_async_lock;
1028         /*
1029          * Other stuff
1030          */
1031         struct pathcnf  *mi_pathconf;   /* static pathconf kludge */
1032         rpcprog_t       mi_prog;        /* RPC program number */
1033         rpcvers_t       mi_vers;        /* RPC program version number */
1034         char            **mi_rfsnames;  /* mapping to proc names */
1035         kstat_named_t   *mi_reqs;       /* count of requests */
1036         clock_t         mi_printftime;  /* last error printf time */
1037         nfs_rwlock_t    mi_recovlock;   /* separate ops from recovery (v4) */
1038         time_t          mi_grace_wait;  /* non-zero represents time to wait */
1039         time_t          mi_srvsettime;  /* when we switched nfs4_server_t */
1040         nfs_rwlock_t    mi_rename_lock; /* atomic volfh rename  */
1041         struct nfs4_fname *mi_fname;    /* root fname */
1042         list_t          mi_lost_state;  /* resend list */
1043         list_t          mi_bseqid_list; /* bad seqid list */
1044         /*
1045          * Client Side Failover stats
1046          */
1047         uint_t          mi_noresponse;  /* server not responding count */
1048         uint_t          mi_failover;    /* failover to new server count */
1049         uint_t          mi_remap;       /* remap to new server count */
1050         /*
1051          * Kstat statistics
1052          */
1053         struct kstat    *mi_io_kstats;
1054         struct kstat    *mi_ro_kstats;
1055         kstat_t         *mi_recov_ksp;  /* ptr to the recovery kstat */
1056 
1057         /*
1058          * Volatile fh flags (nfsv4)
1059          */
1060         uint32_t        mi_fh_expire_type;
1061         /*
1062          * Lease Management
1063          */
1064         struct mntinfo4 *mi_clientid_next;
1065         struct mntinfo4 *mi_clientid_prev;
1066         clientid4       mi_clientid; /* redundant info found in nfs4_server */
1067         int             mi_open_files;  /* count of open files */
1068         int             mi_in_recovery; /* count of recovery instances */
1069         kcondvar_t      mi_cv_in_recov; /* cv for recovery threads */
1070         /*
1071          * Open owner stuff.
1072          */
1073         struct nfs4_oo_hash_bucket      mi_oo_list[NFS4_NUM_OO_BUCKETS];
1074         list_t                          mi_foo_list;
1075         int                             mi_foo_num;
1076         int                             mi_foo_max;
1077         /*
1078          * Shared filehandle pool.
1079          */
1080         nfs_rwlock_t                    mi_fh_lock;
1081         avl_tree_t                      mi_filehandles;
1082 
1083         /*
1084          * pNFS support
1085          */
1086         kmutex_t        mi_pnfs_lock;
1087         taskq_t         *mi_pnfs_io_taskq;
1088         taskq_t         *mi_pnfs_other_taskq;
1089         clock_t         mi_last_getdevicelist;
1090 
1091         /*
1092          * Debug message queue.
1093          */
1094         list_t                  mi_msg_list;
1095         int                     mi_msg_count;
1096         time_t                  mi_lease_period;
1097                                         /*
1098                                          * not guaranteed to be accurate.
1099                                          * only should be used by debug queue.
1100                                          */
1101         kmutex_t                mi_msg_list_lock;
1102         /*
1103          * Zones support.
1104          */
1105         struct zone     *mi_zone; /* Zone mounted in */
1106         list_node_t     mi_zone_node;  /* linkage into per-zone mi list */
1107 
1108         /*
1109          * Links for unmounting ephemeral mounts.
1110          */
1111         struct nfs4_ephemeral           *mi_ephemeral;
1112         struct nfs4_ephemeral_tree      *mi_ephemeral_tree;
1113         attrvers_t                      mi_attrvers;
1114 } mntinfo4_t;
1115 
1116 /*
1117  * The values for mi_flags.
1118  *
1119  *      MI4_HARD                 hard or soft mount
1120  *      MI4_PRINTED              responding message printed
1121  *      MI4_INT                  allow INTR on hard mount
1122  *      MI4_DOWN                 server is down
1123  *      MI4_NOAC                 don't cache attributes
1124  *      MI4_NOCTO                no close-to-open consistency
1125  *      MI4_LLOCK                local locking only (no lockmgr)
1126  *      MI4_GRPID                System V group id inheritance
1127  *      MI4_SHUTDOWN             System is rebooting or shutting down
1128  *      MI4_LINK                 server supports link
1129  *      MI4_SYMLINK              server supports symlink
1130  *      MI4_EPHEMERAL_RECURSED   an ephemeral mount being unmounted
1131  *                               due to a recursive call - no need
1132  *                               for additional recursion
1133  *      MI4_PNFS                 server supports pNFS
1134  *      MI4_ACL                  server supports NFSv4 ACLs
1135  *      MI4_MIRRORMOUNT          is a mirrormount
1136  *      MI4_NOPRINT              don't print messages
1137  *      MI4_DIRECTIO             do direct I/O
1138  *      MI4_RECOV_ACTIV          filesystem has recovery a thread
1139  *      MI4_REMOVE_ON_LAST_CLOSE remove from server's list
1140  *      MI4_RECOV_FAIL           client recovery failed
1141  *      MI4_PUBLIC               public/url option used
1142  *      MI4_MOUNTING             mount in progress, don't failover
1143  *      MI4_POSIX_LOCK           if server is using POSIX locking
1144  *      MI4_LOCK_DEBUG           cmn_err'd posix lock err msg
1145  *      MI4_DEAD                 zone has released it
1146  *      MI4_INACTIVE_IDLE        inactive thread idle
1147  *      MI4_BADOWNER_DEBUG       badowner error msg per mount
1148  *      MI4_ASYNC_MGR_STOP       tell async manager to die
1149  *      MI4_TIMEDOUT             saw a timeout during zone shutdown
1150  *      MI4_EPHEMERAL            is an ephemeral mount
1151  */
1152 #define MI4_HARD                 0x1
1153 #define MI4_PRINTED              0x2
1154 #define MI4_INT                  0x4
1155 #define MI4_DOWN                 0x8
1156 #define MI4_NOAC                 0x10
1157 #define MI4_NOCTO                0x20
1158 #define MI4_LLOCK                0x80
1159 #define MI4_GRPID                0x100
1160 #define MI4_SHUTDOWN             0x200
1161 #define MI4_LINK                 0x400
1162 #define MI4_SYMLINK              0x800
1163 #define MI4_EPHEMERAL_RECURSED   0x1000
1164 #define MI4_ACL                  0x2000
1165 /* MI4_MIRRORMOUNT is also defined in nfsstat.c */
1166 #define MI4_MIRRORMOUNT          0x4000
1167 #define MI4_PNFS                0x8000
1168 /* 0x10000 is available */
1169 #define MI4_NOPRINT              0x20000
1170 #define MI4_DIRECTIO             0x40000
1171 /* 0x80000 is available */
1172 #define MI4_RECOV_ACTIV          0x100000
1173 #define MI4_REMOVE_ON_LAST_CLOSE 0x200000
1174 #define MI4_RECOV_FAIL           0x400000
1175 #define MI4_PUBLIC               0x800000
1176 #define MI4_MOUNTING             0x1000000
1177 #define MI4_POSIX_LOCK           0x2000000
1178 #define MI4_LOCK_DEBUG           0x4000000
1179 #define MI4_DEAD                 0x8000000
1180 #define MI4_INACTIVE_IDLE        0x10000000
1181 #define MI4_BADOWNER_DEBUG       0x20000000
1182 #define MI4_ASYNC_MGR_STOP       0x40000000
1183 #define MI4_TIMEDOUT             0x80000000
1184 
1185 /*
1186  * Note that when we add referrals, then MI4_EPHEMERAL
1187  * will be MI4_MIRRORMOUNT | MI4_REFERRAL.
1188  */
1189 #define MI4_EPHEMERAL           MI4_MIRRORMOUNT
1190 
1191 #define INTR4(vp)       (VTOMI4(vp)->mi_flags & MI4_INT)
1192 
1193 #define FAILOVER_MOUNT4(mi)     (mi->mi_servers->sv_next)
1194 
1195 /*
1196  * Recovery flags.
1197  *
1198  * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag
1199  * that's important), but some flag is needed to indicate that recovery is
1200  * going on for the filesystem.
1201  */
1202 #define MI4R_NEED_CLIENTID      0x1
1203 #define MI4R_REOPEN_FILES       0x2
1204 #define MI4R_NEED_SECINFO       0x4
1205 #define MI4R_NEED_NEW_SERVER    0x8
1206 #define MI4R_REMAP_FILES        0x10
1207 #define MI4R_SRV_REBOOT         0x20    /* server has rebooted */
1208 #define MI4R_LOST_STATE         0x40
1209 #define MI4R_BAD_SEQID          0x80
1210 #define MI4R_NEED_SESSION       0x100
1211 #define MI4R_NEED_BC2S          0x200
1212 
1213 #define MI4_HOLD(mi) {          \
1214         mi_hold(mi);            \
1215 }
1216 
1217 #define MI4_RELE(mi) {          \
1218         mi_rele(mi);            \
1219 }
1220 
1221 #define NFS4_MINORVERSION(mi)   (mi->mi_minorversion)
1222 
1223 /*
1224  * vfs pointer to mount info
1225  */
1226 #define VFTOMI4(vfsp)   ((mntinfo4_t *)((vfsp)->vfs_data))
1227 
1228 /*
1229  * vnode pointer to mount info
1230  */
1231 #define VTOMI4(vp)      ((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data))
1232 
1233 /*
1234  * Lease Management
1235  *
1236  * lease_valid is initially set to NFS4_LEASE_NOT_STARTED.  This is when the
1237  * nfs4_server is first created.  lease_valid is then set to
1238  * NFS4_LEASE_UNITIALIZED when the renew thread is started.  The extra state of
1239  * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread
1240  * already exists when we do SETCLIENTID).  lease_valid is then set to
1241  * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating
1242  * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as
1243  * the lease is renewed.  It is set to NFS4_LEASE_INVALID when the lease
1244  * expires.  Client recovery is needed to set the lease back to
1245  * NFS4_LEASE_VALID from NFS4_LEASE_INVALID.
1246  *
1247  * The s_cred is the credential used to mount the first file system for this
1248  * server.  It used as the credential for the renew thread's calls to the
1249  * server.
1250  *
1251  * The renew thread waits on the condition variable cv_thread_exit.  If the cv
1252  * is signalled, then the thread knows it must check s_thread_exit to see if
1253  * it should exit.  The cv is signaled when the last file system is unmounted
1254  * from a particular server.  s_thread_exit is set to 0 upon thread startup,
1255  * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby
1256  * telling the thread to exit.  s_thread_exit is needed to avoid spurious
1257  * wakeups.
1258  *
1259  * state_ref_count is incremented every time a new file is opened and
1260  * decremented every time a file is closed otw.  This keeps track of whether
1261  * the nfs4_server has state associated with it or not.
1262  *
1263  * s_refcnt is the reference count for storage management of the struct
1264  * itself.
1265  *
1266  * mntinfo4_list points to the doubly linked list of mntinfo4s that share
1267  * this nfs4_server (ie: <clientid, saddr> pair) in the current zone.  This is
1268  * needed for a nfs4_server to get a mntinfo4 for use in rfs4call.
1269  *
1270  * s_recovlock is used to synchronize recovery operations.  The thread
1271  * that is recovering the client must acquire it as a writer.  If the
1272  * thread is using the clientid (including recovery operations on other
1273  * state), acquire it as a reader.
1274  *
1275  * The 's_otw_call_count' keeps track of the number of outstanding over the
1276  * wire requests for this structure.  The struct will not go away as long
1277  * as this is non-zero (or s_refcnt is non-zero).
1278  *
1279  * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count'
1280  * variable to let the renew thread when an outstanding otw request has
1281  * finished.
1282  *
1283  * 'zoneid' and 'zone_globals' are set at creation of this structure
1284  * and are read-only after that; no lock is required to read them.
1285  *
1286  * s_lock protects: everything except cv_thread_exit and s_recovlock.
1287  *
1288  * s_program is used as the index into the nfs4_callback_globals's
1289  * nfs4prog2server table.  When a callback request comes in, we can
1290  * use that request's program number (minus NFS4_CALLBACK) as an index
1291  * into the nfs4prog2server.  That entry will hold the nfs4_server_t ptr.
1292  * We can then access that nfs4_server_t and its 's_deleg_list' (its list of
1293  * delegated rnode4_ts).
1294  *
1295  * Lock order:
1296  * nfs4_server::s_lock > mntinfo4::mi_lock
1297  * nfs_rtable4_lock > s_lock
1298  * nfs4_server_lst_lock > s_lock
1299  * s_recovlock > s_lock
1300  */
1301 struct nfs4_callback_globals;
1302 
1303 typedef struct nfs41_cb_slot {
1304         sequenceid4             cb_seq;
1305         int                     cb_slot_id;
1306         int                     cb_inuse;
1307         kmutex_t                cb_lock;
1308         void                    *cb_response;
1309 } nfs41_cb_slot_t;
1310 
1311 typedef struct nfs4_slot {
1312         sequenceid4             slot_seqid;
1313         int                     slot_id;
1314         int                     slot_inuse;
1315         int                     slot_bad;
1316 } nfs4_slot_t;
1317 
1318 /*
1319  * The nfs4_fsidlt_t will be the structure inserted as a node onto
1320  * the nfs4_server_t's fsidlt (fsid layout tree).  There will be one
1321  * per fsid that has done a layoutget.  Note that the fsid structures,
1322  * once added to the fsidlt, will remain there until the nfs4_server_t
1323  * is destroyed, even if all layouts have been returned for the fsid.
1324  *
1325  * The locking order is that, the s_lt_lock in the nfs4_server_t will
1326  * lock the fsidlt tree.  Once the appropriate fsidlt node is found, it
1327  * will be locked via its lt_rtl_lock, then the s_lt_lock can be dropped.
1328  *
1329  * Also note, that if the rnode4->r_statelock and the lt_rtl_lock are both
1330  * required, the lt_rtl_lock must be taken out before the r_statelock
1331  * and the lt_rtl_lock must be release after the r_statelock is released.
1332  */
1333 typedef struct nfs4_fsidlt
1334 {
1335         fsid4           lt_fsid; /* fsid */
1336         avl_node_t      lt_node; /* link to nfs4_fsidlt tree */
1337         kmutex_t        lt_rlt_lock; /* rnode layout tree lock */
1338         avl_tree_t      lt_rlayout_tree; /* rnode layout tree by fh */
1339 } nfs4_fsidlt_t;
1340 
1341 typedef struct nfs4_session {
1342         sessionid4              sessionid;
1343         sequenceid4             sequenceid;
1344         nfs4_slot_t             **slot_table;
1345         int                     next_slot;
1346         int                     slots_available;
1347         int                     maxslots;       /* maxslots size from server */
1348         int                     slot_table_size; /* Total slots in table */
1349         kmutex_t                slot_lock;
1350         kcondvar_t              slot_wait;      /* Wait for available slot */
1351         nfs_rwlock_t            slot_table_rwlock;
1352         nfs41_cb_slot_t         **cb_slot_table;
1353         int                     cb_slot_table_size;
1354         int                     bi_rpc;
1355         channel_attrs4          fore_chan_attr;
1356         channel_attrs4          back_chan_attr;
1357         list_node_t             ssx_list;
1358         struct netbuf           saddr;
1359 } nfs4_session_t;
1360 
1361 typedef struct nfs4_server {
1362         struct nfs4_server      *forw;
1363         struct nfs4_server      *back;
1364         struct netbuf           saddr;
1365         uint_t                  s_flags; /* see below */
1366         uint_t                  s_refcnt;
1367         clientid4               clientid;       /* what we get from server */
1368         nfs_client_id4          clidtosend;     /* what we send to server */
1369 
1370         /* seqid for the next CREATE_SESSION */
1371         sequenceid4             csa_seqid;
1372 
1373         nfs4_session_t          ssx;            /* sessions extension */
1374         int                     seqhb_flags;
1375         mntinfo4_t              *mntinfo4_list;
1376         uint32_t                s_minorversion; /* last tried minorversion */
1377         int                     lease_valid;
1378         time_t                  s_lease_time;
1379         time_t                  last_renewal_time;
1380         timespec_t              propagation_delay;
1381         cred_t                  *s_cred;
1382         kcondvar_t              cv_thread_exit;
1383         int                     s_thread_exit;
1384         int                     state_ref_count;
1385         int                     s_otw_call_count;
1386         kcondvar_t              s_cv_otw_count;
1387         kcondvar_t              s_clientid_pend;
1388         kmutex_t                s_lock;
1389         list_t                  s_deleg_list;
1390         rpcprog_t               s_program;
1391         nfs_rwlock_t            s_recovlock;
1392         kthread_t               *s_recovthread; /* active recov thrd or NULL */
1393         kcondvar_t              wait_cb_null; /* used to wait for CB_NULL */
1394         zoneid_t                zoneid; /* zone using this nfs4_server_t */
1395         struct nfs4_callback_globals *zone_globals;     /* globals */
1396         kcondvar_t              ssx_wait;       /* wait for destroy session */
1397         servinfo4_t             *s_ds_svp; /* for dataservers, the servinfo4 */
1398         kmutex_t                s_lt_lock; /* layout tree lock */
1399         avl_tree_t              s_fsidlt; /* fsid layout tree */
1400         avl_tree_t              s_devid_tree;   /* Device ID tree */
1401 } nfs4_server_t;
1402 
1403 /* nfs4_server flags */
1404 #define N4S_CLIENTID_SET        1       /* server has our clientid */
1405 #define N4S_CLIENTID_PEND       0x2     /* server doesn't have clientid */
1406 #define N4S_CB_PINGED           0x4     /* server has sent us a CB_NULL */
1407 #define N4S_CB_WAITER           0x8     /* is/has wait{ing/ed} for cb_null */
1408 #define N4S_INSERTED            0x10    /* list has reference for server */
1409 #define N4S_BADOWNER_DEBUG      0x20    /* bad owner err msg per client */
1410 #define N4S_USE_PNFS_MDS        0x40    /* server is a pnfs MDS server */
1411 #define N4S_USE_PNFS_DS         0x80    /* server is a pnfs DS server */
1412 #define N4S_SESSION_CREATED     0x100   /* Session Created To Server */
1413 #define N4S_EXID_FAILED         0x200   /* Exchange ID failed */
1414 #define N4S_USE_NON_PNFS        0x400   /* server is a non pNFS 4.1 server */
1415 #define N4S_NEED_BC2S           0x800   /* need bind_conn_to_session */
1416 #define N4S_RECOV_ACTIV         0x1000  /* Recovery is active for this server */
1417 
1418 #define N4S_CB_PAUSE_TIME       10000   /* Amount of time to pause (10ms) */
1419 
1420 struct lease_time_arg {
1421         time_t  lease_time;
1422 };
1423 
1424 enum nfs4_delegreturn_policy {
1425         IMMEDIATE,
1426         FIRSTCLOSE,
1427         LASTCLOSE,
1428         INACTIVE
1429 };
1430 
1431 /*
1432  * Operation hints for the recovery framework (mostly).
1433  *
1434  * EXCEPTIONS:
1435  * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR
1436  *      These hints exist to allow user visit/readdir a R4SRVSTUB dir.
1437  *      (dir represents the root of a server fs that has not yet been
1438  *      mounted at client)
1439  */
1440 typedef enum {
1441         OH_OTHER,
1442         OH_READ,
1443         OH_WRITE,
1444         OH_COMMIT,
1445         OH_VFH_RENAME,
1446         OH_MOUNT,
1447         OH_CLOSE,
1448         OH_LOCKU,
1449         OH_DELEGRETURN,
1450         OH_ACCESS,
1451         OH_GETACL,
1452         OH_GETATTR,
1453         OH_LOOKUP,
1454         OH_READDIR,
1455         OH_SEQUENCE
1456 } nfs4_op_hint_t;
1457 
1458 /*
1459  * This data structure is used to track ephemeral mounts for both
1460  * mirror mounts and referrals.
1461  *
1462  * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral
1463  * pointing at it. So we don't need two backpointers to walk
1464  * back up the tree.
1465  *
1466  * An ephemeral tree is pointed to by an enclosing non-ephemeral
1467  * mntinfo4. The root is also pointed to by its ephemeral
1468  * mntinfo4. ne_child will get us back to it, while ne_prior
1469  * will get us back to the non-ephemeral mntinfo4. This is an
1470  * edge case we will need to be wary of when walking back up the
1471  * tree.
1472  *
1473  * The way we handle this edge case is to have ne_prior be NULL
1474  * for the root nfs4_ephemeral node.
1475  */
1476 typedef struct nfs4_ephemeral {
1477         mntinfo4_t              *ne_mount;      /* who encloses us */
1478         struct nfs4_ephemeral   *ne_child;      /* first child node */
1479         struct nfs4_ephemeral   *ne_peer;       /* next sibling */
1480         struct nfs4_ephemeral   *ne_prior;      /* who points at us */
1481         time_t                  ne_ref_time;    /* time last referenced */
1482         uint_t                  ne_mount_to;    /* timeout at */
1483         int                     ne_state;       /* used to traverse */
1484 } nfs4_ephemeral_t;
1485 
1486 /*
1487  * State for the node (set in ne_state):
1488  */
1489 #define NFS4_EPHEMERAL_OK               0x0
1490 #define NFS4_EPHEMERAL_VISIT_CHILD      0x1
1491 #define NFS4_EPHEMERAL_VISIT_SIBLING    0x2
1492 #define NFS4_EPHEMERAL_PROCESS_ME       0x4
1493 #define NFS4_EPHEMERAL_CHILD_ERROR      0x8
1494 #define NFS4_EPHEMERAL_PEER_ERROR       0x10
1495 
1496 /*
1497  * These are the locks used in processing ephemeral data:
1498  *
1499  * mi->mi_lock
1500  *
1501  * net->net_tree_lock
1502  *     This lock is used to gate all tree operations.
1503  *     If it is held, then no other process may
1504  *     traverse the tree. This allows us to not
1505  *     throw a hold on each vfs_t in the tree.
1506  *     Can be held for a "long" time.
1507  *
1508  * net->net_cnt_lock
1509  *     Used to protect refcnt and status.
1510  *     Must be held for a really short time.
1511  *
1512  * nfs4_ephemeral_thread_lock
1513  *     Is only held to create the harvester for the zone.
1514  *     There is no ordering imposed on it.
1515  *     Held for a really short time.
1516  *
1517  * Some further detail on the interactions:
1518  *
1519  * net_tree_lock controls access to net_root. Access needs to first be
1520  * attempted in a non-blocking check.
1521  *
1522  * net_cnt_lock controls access to net_refcnt and net_status. It must only be
1523  * held for very short periods of time, unless the refcnt is 0 and the status
1524  * is INVALID.
1525  *
1526  * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock
1527  * to bump the net_refcnt. It then releases it and does the action specific
1528  * algorithm to get the net_tree_lock. Once it has that, then it is okay to
1529  * grab the net_cnt_lock and change the status. The status can only be
1530  * changed if the caller has the net_tree_lock held as well.
1531  *
1532  * Note that the initial grab of net_cnt_lock must occur whilst
1533  * mi_lock is being held. This prevents stale data in that if the
1534  * ephemeral tree is non-NULL, then the harvester can not remove
1535  * the tree from the mntinfo node until it grabs that lock. I.e.,
1536  * we get the pointer to the tree and hold the lock atomically
1537  * with respect to being in mi_lock.
1538  *
1539  * When a caller is done with net_tree_lock, it can decrement the net_refcnt
1540  * either before it releases net_tree_lock or after.
1541  *
1542  * In either event, to decrement net_refcnt, it must hold net_cnt_lock.
1543  *
1544  * Note that the overall locking scheme for the nodes is to control access
1545  * via the tree. The current scheme could easily be extended such that
1546  * the enclosing root referenced a "forest" of trees. The underlying trees
1547  * would be autonomous with respect to locks.
1548  *
1549  * Note that net_next is controlled by external locks
1550  * particular to the data structure that the tree is being added to.
1551  */
1552 typedef struct nfs4_ephemeral_tree {
1553         mntinfo4_t                      *net_mount;
1554         nfs4_ephemeral_t                *net_root;
1555         struct nfs4_ephemeral_tree      *net_next;
1556         kmutex_t                        net_tree_lock;
1557         kmutex_t                        net_cnt_lock;
1558         uint_t                          net_status;
1559         uint_t                          net_refcnt;
1560 } nfs4_ephemeral_tree_t;
1561 
1562 /*
1563  * State for the tree (set in net_status):
1564  */
1565 #define NFS4_EPHEMERAL_TREE_OK          0x0
1566 #define NFS4_EPHEMERAL_TREE_BUILDING    0x1
1567 #define NFS4_EPHEMERAL_TREE_DEROOTING   0x2
1568 #define NFS4_EPHEMERAL_TREE_INVALID     0x4
1569 #define NFS4_EPHEMERAL_TREE_MOUNTING    0x8
1570 #define NFS4_EPHEMERAL_TREE_UMOUNTING   0x10
1571 #define NFS4_EPHEMERAL_TREE_LOCKED      0x20
1572 
1573 #define NFS4_EPHEMERAL_TREE_PROCESSING  (NFS4_EPHEMERAL_TREE_DEROOTING | \
1574         NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \
1575         NFS4_EPHEMERAL_TREE_LOCKED)
1576 
1577 /*
1578  * This macro evaluates to non-zero if the given op releases state at the
1579  * server.
1580  */
1581 #define OH_IS_STATE_RELE(op)    ((op) == OH_CLOSE || (op) == OH_LOCKU || \
1582                                 (op) == OH_DELEGRETURN)
1583 
1584 #ifdef _KERNEL
1585 
1586 extern int      layoutcmp(const void *, const void *);
1587 extern void     nfs4_set_mod(vnode_t *);
1588 extern void     nfs4_set_pageerror(page_t *);
1589 extern void     nfs4_async_manager(struct vfs *);
1590 extern void     nfs4_async_manager_stop(struct vfs *);
1591 extern void     nfs4_async_stop(struct vfs *);
1592 extern int      nfs4_async_stop_sig(struct vfs *);
1593 extern int      nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t,
1594                                 struct seg *, cred_t *,
1595                                 void (*)(vnode_t *, u_offset_t,
1596                                 caddr_t, struct seg *, cred_t *));
1597 extern int      nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t,
1598                                 int, cred_t *, int (*)(vnode_t *, page_t *,
1599                                 u_offset_t, size_t, int, cred_t *));
1600 extern int      nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t,
1601                                 int, cred_t *, int (*)(vnode_t *, page_t *,
1602                                 u_offset_t, size_t, int, cred_t *));
1603 extern void     nfs4_async_commit(vnode_t *, page_t *, offset3, count3,
1604                                 cred_t *, void (*)(vnode_t *, page_t *,
1605                                 offset3, count3, cred_t *));
1606 extern void     nfs4_async_inactive(vnode_t *, cred_t *);
1607 extern void     nfs4_inactive_thread(mntinfo4_t *mi);
1608 extern void     nfs4_inactive_otw(vnode_t *, cred_t *);
1609 extern int      nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *);
1610 
1611 extern int      nfs4_setopts(vnode_t *, model_t, struct nfs_args *);
1612 extern void     nfs4_mnt_kstat_init(struct vfs *);
1613 
1614 extern void     rfs4call(struct mntinfo4 *, servinfo4_t *,
1615                         struct COMPOUND4args_clnt *,
1616                         struct COMPOUND4res_clnt *,
1617                         cred_t *, int *, int, nfs4_error_t *);
1618 extern void     nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *);
1619 extern int      nfs4_attr_otw(vnode_t *, nfs4_tag_type_t,
1620                                 nfs4_ga_res_t *, attrmap4 *, cred_t *);
1621 
1622 extern void     nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t);
1623 extern void     nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *,
1624                                 hrtime_t, cred_t *, int,
1625                                 change_info4 *);
1626 extern void     nfs4_purge_rddir_cache(vnode_t *);
1627 extern void     nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *);
1628 extern void     nfs4_purge_caches(vnode_t *, int, cred_t *, int);
1629 extern void     nfs4_purge_stale_fh(int, vnode_t *, cred_t *);
1630 
1631 extern void     nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *);
1632 extern void     nfs4_update_paths(vnode_t *, char *, vnode_t *, char *,
1633                         vnode_t *);
1634 
1635 extern void     nfs4args_lookup_free(nfs_argop4 *, int);
1636 extern void     nfs4args_copen_free(OPEN4cargs *);
1637 
1638 extern void     nfs4_printfhandle(nfs4_fhandle_t *);
1639 
1640 extern void     nfs_free_mi4(mntinfo4_t *);
1641 extern servinfo4_t *new_servinfo4(struct knetconfig *, struct netbuf *, int);
1642 extern void     sv4_free(servinfo4_t *);
1643 
1644 extern void     nfs4_mi_zonelist_add(mntinfo4_t *);
1645 extern int      nfs4_mi_zonelist_remove(mntinfo4_t *);
1646 extern int      nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *);
1647 extern void     nfs4_secinfo_init(void);
1648 extern void     nfs4_secinfo_fini(void);
1649 extern int      nfs4_secinfo_path(mntinfo4_t *, cred_t *, int);
1650 extern int      nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *);
1651 extern void     secinfo_free(sv_secinfo_t *);
1652 extern void     save_mnt_secinfo(servinfo4_t *);
1653 extern void     check_mnt_secinfo(servinfo4_t *, vnode_t *);
1654 extern int      vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int,
1655     enum nfs_opnum4, attrmap4 *, int, file_layouthint4 *);
1656 extern int      nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *,
1657                         int, cred_t *);
1658 extern void     nfs4_write_error(vnode_t *, int, cred_t *);
1659 extern void     nfs4_lockcompletion(vnode_t *, int);
1660 extern bool_t   nfs4_map_lost_lock_conflict(vnode_t *);
1661 extern int      vtodv(vnode_t *, vnode_t **, cred_t *, bool_t);
1662 extern void     nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *,
1663                     bool_t, bool_t *, nfs4_open_owner_t *, bool_t,
1664                     nfs4_error_t *, int *);
1665 extern void     nfs4_error_zinit(nfs4_error_t *);
1666 extern void     nfs4_error_init(nfs4_error_t *, int);
1667 extern void     nfs4_free_args(struct nfs_args *);
1668 extern void     nfs4_error_set(nfs4_error_t *, enum clnt_stat, enum nfsstat4);
1669 
1670 extern void     mi_hold(mntinfo4_t *);
1671 extern void     mi_rele(mntinfo4_t *);
1672 
1673 extern sec_data_t       *copy_sec_data(sec_data_t *);
1674 extern gss_clntdata_t   *copy_sec_data_gss(gss_clntdata_t *);
1675 
1676 #ifdef DEBUG
1677 extern int      nfs4_consistent_type(vnode_t *);
1678 #endif
1679 
1680 extern void     nfs4_init_dot_entries(void);
1681 extern void     nfs4_destroy_dot_entries(void);
1682 extern struct nfs4_callback_globals     *nfs4_get_callback_globals(void);
1683 extern int      nfs4_commit(vnode_t *, page_t *, offset4, count4, cred_t *);
1684 extern int      nfs4_commit_normal(vnode_t *, page_t *, offset4, count4,
1685     cred_t *);
1686 
1687 extern struct nfs4_server nfs4_server_lst;
1688 
1689 extern clock_t nfs_write_error_interval;
1690 
1691 #endif /* _KERNEL */
1692 
1693 /*
1694  * Flags for nfs4getfh_otw.
1695  */
1696 
1697 #define NFS4_GETFH_PUBLIC       0x01
1698 #define NFS4_GETFH_NEEDSOP      0x02
1699 
1700 /*
1701  * Found through rnodes.
1702  *
1703  * The os_open_ref_count keeps track the number of open file descriptor
1704  * refernces on this data structure.  It will be bumped for any successful
1705  * OTW OPEN call and any OPEN call that determines the OTW call is not
1706  * necessary and the open stream hasn't just been created (see
1707  * nfs4_is_otw_open_necessary).
1708  *
1709  * os_mapcnt is a count of the number of mmapped pages for a particular
1710  * open stream; this in conjunction w/ os_open_ref_count is used to
1711  * determine when to do a close to the server.  This is necessary because
1712  * of the semantics of doing open, mmap, close; the OTW close must be wait
1713  * until all open and mmap references have vanished.
1714  *
1715  * 'os_valid' tells us whether this structure is about to be freed or not,
1716  * if it is then don't return it in find_open_stream().
1717  *
1718  * 'os_final_close' is set when a CLOSE OTW was attempted.  This is needed
1719  * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE
1720  * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE.  It
1721  * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE
1722  * that tried to close OTW but failed, and left the state cleanup to
1723  * nfs4_inactive/CLOSE_FORCE.
1724  *
1725  * 'os_force_close' is used to let us know if an intervening thread came
1726  * and reopened the open stream after we decided to issue a CLOSE_FORCE,
1727  * but before we could actually process the CLOSE_FORCE.
1728  *
1729  * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the
1730  * lost state queue.
1731  *
1732  * 'open_stateid' is set the last open stateid returned by the server unless
1733  * 'os_delegation' is 1, in which case 'open_stateid' refers to the
1734  * delegation stateid returned by the server.  This is used in cases where the
1735  * client tries to OPEN a file but already has a suitable delegation, so we
1736  * just stick the delegation stateid in the open stream.
1737  *
1738  * os_dc_openacc are open access bits which have been granted to the
1739  * open stream by virtue of a delegation, but which have not been seen
1740  * by the server.  This applies even if the open stream does not have
1741  * os_delegation set.  These bits are used when setting file locks to
1742  * determine whether an open with CLAIM_DELEGATE_CUR needs to be done
1743  * before the lock request can be sent to the server.  See
1744  * nfs4frlock_check_deleg().
1745  *
1746  * 'os_mmap_read/write' keep track of the read and write access our memory
1747  * maps require.  We need to keep track of this so we can provide the proper
1748  * access bits in the open/mmap/close/reboot/reopen case.
1749  *
1750  * 'os_failed_reopen' tells us that we failed to successfully reopen this
1751  * open stream; therefore, we should not use this open stateid as it is
1752  * not valid anymore. This flag is also used to indicate an unsuccessful
1753  * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR.
1754  *
1755  * If 'os_orig_oo_name' is different than os_open_owner's oo_name
1756  * then this tells us that this open stream's open owner used a
1757  * bad seqid (that is, got NFS4ERR_BAD_SEQID).  If different, this open
1758  * stream will no longer be used for future OTW state releasing calls.
1759  *
1760  * Lock ordering:
1761  * rnode4_t::r_os_lock > os_sync_lock
1762  * os_sync_lock > rnode4_t::r_statelock
1763  * os_sync_lock > rnode4_t::r_statev4_lock
1764  * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call)
1765  *
1766  * The 'os_sync_lock' protects:
1767  *      open_stateid
1768  *      os_dc_openacc
1769  *      os_delegation
1770  *      os_failed_reopen
1771  *      os_final_close
1772  *      os_force_close
1773  *      os_mapcnt
1774  *      os_mmap_read
1775  *      os_mmap_write
1776  *      os_open_ref_count
1777  *      os_pending_close
1778  *      os_share_acc_read
1779  *      os_share_acc_write
1780  *      os_share_deny_none
1781  *      os_share_deny_read
1782  *      os_share_deny_write
1783  *      os_ref_count
1784  *      os_valid
1785  *
1786  * The rnode4_t::r_os_lock protects:
1787  *      os_node
1788  *
1789  * These fields are set at creation time and
1790  * read only after that:
1791  *      os_open_owner
1792  *      os_orig_oo_name
1793  */
1794 typedef struct nfs4_open_stream {
1795         uint64_t                os_share_acc_read;
1796         uint64_t                os_share_acc_write;
1797         uint64_t                os_mmap_read;
1798         uint64_t                os_mmap_write;
1799         uint32_t                os_share_deny_none;
1800         uint32_t                os_share_deny_read;
1801         uint32_t                os_share_deny_write;
1802         stateid4                open_stateid;
1803         int                     os_dc_openacc;
1804         int                     os_ref_count;
1805         unsigned                os_valid:1;
1806         unsigned                os_delegation:1;
1807         unsigned                os_final_close:1;
1808         unsigned                os_pending_close:1;
1809         unsigned                os_failed_reopen:1;
1810         unsigned                os_force_close:1;
1811         int                     os_open_ref_count;
1812         long                    os_mapcnt;
1813         list_node_t             os_node;
1814         struct nfs4_open_owner  *os_open_owner;
1815         uint64_t                os_orig_oo_name;
1816         kmutex_t                os_sync_lock;
1817 } nfs4_open_stream_t;
1818 
1819 /*
1820  * This structure describes the format of the lock_owner_name
1821  * field of the lock owner.
1822  */
1823 
1824 typedef struct nfs4_lo_name {
1825         uint64_t        ln_seq_num;
1826         pid_t           ln_pid;
1827 } nfs4_lo_name_t;
1828 
1829 /*
1830  * Flags for lo_flags.
1831  */
1832 #define NFS4_LOCK_SEQID_INUSE   0x1
1833 #define NFS4_BAD_SEQID_LOCK     0x2
1834 
1835 /*
1836  * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs
1837  * off the rnode.  If the links are NULL it means this object is not on the
1838  * list.
1839  *
1840  * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and
1841  * didn't get a response back.  This is used to figure out if we have
1842  * possible remote v4 locks, so that we can clean up at process exit.  In
1843  * theory, the client should be able to figure out if the server received
1844  * the request (based on what seqid works), so maybe we can get rid of this
1845  * flag someday.
1846  *
1847  * 'lo_ref_count' tells us how many processes/threads are using this data
1848  * structure.  The rnode's list accounts for one reference.
1849  *
1850  * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the
1851  * data structure.  It is then set to NFS4_PERM_CREATED when a lock request
1852  * is successful using this lock owner structure.  We need to keep 'temporary'
1853  * lock owners around so we can properly keep the lock seqid synchronization
1854  * when multiple processes/threads are trying to create the lock owner for the
1855  * first time (especially with the DENIED error case).  Once
1856  * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change.
1857  *
1858  * 'lo_valid' tells us whether this structure is about to be freed or not,
1859  * if it is then don't return it from find_lock_owner().
1860  *
1861  * Retrieving and setting of 'lock_seqid' is protected by the
1862  * NFS4_LOCK_SEQID_INUSE flag.  Waiters for NFS4_LOCK_SEQID_INUSE should
1863  * use 'lo_cv_seqid_sync'.
1864  *
1865  * The setting of 'lock_stateid' is protected by the
1866  * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'.  The retrieving of the
1867  * 'lock_stateid' is protected by 'lo_lock', with the additional
1868  * requirement that the calling function can handle NFS4ERR_OLD_STATEID and
1869  * NFS4ERR_BAD_STATEID as appropiate.
1870  *
1871  * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock
1872  * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID).  With this set,
1873  * this lock owner will no longer be used for future OTW calls.  Once set,
1874  * it is never unset.
1875  *
1876  * Lock ordering:
1877  * rnode4_t::r_statev4_lock > lo_lock
1878  */
1879 typedef struct nfs4_lock_owner {
1880         struct nfs4_lock_owner  *lo_next_rnode;
1881         struct nfs4_lock_owner  *lo_prev_rnode;
1882         int                     lo_pid;
1883         stateid4                lock_stateid;
1884         seqid4                  lock_seqid;
1885         /*
1886          * Fix this to always be 12 bytes
1887          */
1888         nfs4_lo_name_t          lock_owner_name;
1889         int                     lo_ref_count;
1890         int                     lo_valid;
1891         int                     lo_pending_rqsts;
1892         int                     lo_just_created;
1893         int                     lo_flags;
1894         kcondvar_t              lo_cv_seqid_sync;
1895         kmutex_t                lo_lock;
1896         kthread_t               *lo_seqid_holder; /* debugging aid */
1897 } nfs4_lock_owner_t;
1898 
1899 /* for nfs4_lock_owner_t lookups */
1900 typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t;
1901 
1902 /* Number of times to retry a call that fails with state independent error */
1903 #define NFS4_NUM_RECOV_RETRIES  3
1904 
1905 typedef enum {
1906         NO_SID,
1907         DEL_SID,
1908         LOCK_SID,
1909         OPEN_SID,
1910         SPEC_SID
1911 } nfs4_stateid_type_t;
1912 
1913 typedef struct nfs4_stateid_types {
1914         stateid4 d_sid;
1915         stateid4 l_sid;
1916         stateid4 o_sid;
1917         nfs4_stateid_type_t cur_sid_type;
1918 } nfs4_stateid_types_t;
1919 
1920 /*
1921  * Flags used to determine stateid we want.
1922  */
1923 
1924 #define GETSID_TRYNEXT  0x00000001      /* Try next stateid */
1925 #define GETSID_LAYOUT   0x00000002      /* Need Stateid For Layoutget */
1926 
1927 
1928 /*
1929  * Per-zone data for dealing with callbacks.  Included here solely for the
1930  * benefit of MDB.
1931  */
1932 struct nfs4_callback_stats {
1933         kstat_named_t   delegations;
1934         kstat_named_t   cb_getattr;
1935         kstat_named_t   cb_recall;
1936         kstat_named_t   cb_null;
1937         kstat_named_t   cb_dispatch;
1938         kstat_named_t   delegaccept_r;
1939         kstat_named_t   delegaccept_rw;
1940         kstat_named_t   delegreturn;
1941         kstat_named_t   callbacks;
1942         kstat_named_t   claim_cur;
1943         kstat_named_t   claim_cur_ok;
1944         kstat_named_t   recall_trunc;
1945         kstat_named_t   recall_failed;
1946         kstat_named_t   return_limit_write;
1947         kstat_named_t   return_limit_addmap;
1948         kstat_named_t   deleg_recover;
1949         kstat_named_t   cb_illegal;
1950         kstat_named_t   cb_sequence;
1951 };
1952 
1953 struct nfs41_cb_info {
1954         rpcprog_t               cb_prog;
1955         rpcvers_t               cb_versmin;
1956         rpcvers_t               cb_versmax;
1957         SVCCB                   *cb_rpc;
1958         SVC_DISPATCH            *cb_callback;
1959         CLIENT                  *cb_client;
1960         struct nfs4_clnt        *cb_nfscl;
1961         int                     cb_state;
1962         kthread_t               *cb_thread;     /*  server calls */
1963         kmutex_t                cb_cbconn_lock;
1964         kcondvar_t              cb_cbconn_wait; /* cbconn heartbeat */
1965         int                     cb_cbconn_exit;
1966         int                     cb_flags;
1967         int                     cb_refcnt;
1968         kmutex_t                cb_reflock;
1969         kcondvar_t              cb_destroy_wait;
1970 } nfs41_cb_info_t;
1971 
1972 /*
1973  * cb_flags
1974  */
1975 
1976 #define NFS41_CB_THREAD_EXIT    0x01    /* signal to cbserver thread exit */
1977 
1978 struct nfs4_callback_globals {
1979         kmutex_t nfs4_cb_lock;
1980         kmutex_t nfs4_dlist_lock;
1981         int nfs4_program_hint;
1982         /* this table maps the program number to the nfs4_server structure */
1983         struct nfs4_server **nfs4prog2server;
1984         struct nfs41_cb_info **nfs4prog2cbinfo;
1985         list_t nfs4_dlist;
1986         list_t nfs4_cb_ports;
1987         struct nfs4_callback_stats nfs4_callback_stats;
1988 #ifdef DEBUG
1989         int nfs4_dlistadd_c;
1990         int nfs4_dlistclean_c;
1991 #endif
1992 };
1993 
1994 typedef enum {
1995         CLOSE_NORM,
1996         CLOSE_DELMAP,
1997         CLOSE_FORCE,
1998         CLOSE_RESEND,
1999         CLOSE_AFTER_RESEND
2000 } nfs4_close_type_t;
2001 
2002 /*
2003  * Structure to hold the bad seqid information that is passed
2004  * to the recovery framework.
2005  */
2006 typedef struct nfs4_bseqid_entry {
2007         nfs4_open_owner_t       *bs_oop;
2008         nfs4_lock_owner_t       *bs_lop;
2009         vnode_t                 *bs_vp;
2010         pid_t                   bs_pid;
2011         nfs4_tag_type_t         bs_tag;
2012         seqid4                  bs_seqid;
2013         list_node_t             bs_node;
2014 } nfs4_bseqid_entry_t;
2015 
2016 typedef struct nfs4_tagswap {
2017         sessionid4 ts_oldtag;
2018         sessionid4 *ts_newtag;
2019 } nfs4_tagswap_t;
2020 
2021 #ifdef _KERNEL
2022 
2023 extern void     nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int,
2024                     nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t,
2025                     size_t, uint_t, uint_t);
2026 extern void     nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *);
2027 extern void     nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4);
2028 extern void     open_owner_hold(nfs4_open_owner_t *);
2029 extern void     open_owner_rele(nfs4_open_owner_t *);
2030 extern nfs4_open_stream_t       *find_or_create_open_stream(nfs4_open_owner_t *,
2031                                         struct rnode4 *, int *);
2032 extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *,
2033                                 struct rnode4 *);
2034 extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop,
2035                                 struct rnode4 *rp);
2036 extern void     open_stream_hold(nfs4_open_stream_t *);
2037 extern void     open_stream_rele(nfs4_open_stream_t *, struct rnode4 *);
2038 extern int      nfs4close_all(vnode_t *, cred_t *);
2039 extern void     lock_owner_hold(nfs4_lock_owner_t *);
2040 extern void     lock_owner_rele(nfs4_lock_owner_t *);
2041 extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t);
2042 extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t);
2043 extern void     nfs4_rnode_remove_lock_owner(struct rnode4 *,
2044                         nfs4_lock_owner_t *);
2045 extern void     nfs4_flush_lock_owners(struct rnode4 *);
2046 extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t);
2047 extern void     nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *,
2048                     nfs4_tag_type_t);
2049 extern void     nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *);
2050 extern void     nfs4_end_open_seqid_sync(nfs4_open_owner_t *);
2051 extern int      nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *);
2052 extern void     nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *);
2053 extern int      nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *);
2054 extern void     nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *,
2055                         nfs4_open_stream_t *, mntinfo4_t *, locker4 *);
2056 extern void     nfs4_destroy_open_owner(nfs4_open_owner_t *);
2057 
2058 extern void             nfs4_renew_lease_thread(nfs4_server_t *);
2059 extern void             nfs4_sequence_heartbeat_thread(nfs4_server_t *);
2060 extern void             nfs4_cbconn_thread(nfs4_server_t *);
2061 extern nfs4_server_t    *find_nfs4_server(mntinfo4_t *);
2062 extern nfs4_server_t    *find_nfs4_server_nolock(mntinfo4_t *);
2063 extern nfs4_server_t    *find_nfs4_server_all(mntinfo4_t *, int all);
2064 extern nfs4_server_t    *find_nfs4_server_by_addr(struct netbuf *,
2065                                 struct knetconfig *);
2066 extern nfs4_server_t    *new_nfs4_server(servinfo4_t *, cred_t *);
2067 extern nfs4_server_t    *add_new_nfs4_server(servinfo4_t *, cred_t *);
2068 extern void             nfs4_mark_srv_dead(nfs4_server_t *, uint_t);
2069 extern nfs4_server_t    *servinfo4_to_nfs4_server(servinfo4_t *);
2070 extern void             nfs4_inc_state_ref_count(mntinfo4_t *);
2071 extern void             nfs4_inc_state_ref_count_nolock(nfs4_server_t *,
2072                                 mntinfo4_t *);
2073 extern void             nfs4_dec_state_ref_count(mntinfo4_t *);
2074 extern void             nfs4_dec_state_ref_count_nolock(nfs4_server_t *,
2075                                 mntinfo4_t *);
2076 extern clientid4        mi2clientid(mntinfo4_t *);
2077 extern int              nfs4_server_in_recovery(nfs4_server_t *);
2078 extern bool_t           nfs4_server_vlock(nfs4_server_t *, int);
2079 extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *);
2080 extern uint64_t         nfs4_get_new_oo_name(void);
2081 extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *);
2082 extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *);
2083 extern void     nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *,
2084                         int, u_offset_t, cred_t *, nfs4_error_t *,
2085                         nfs4_lost_rqst_t *, int *);
2086 extern void     nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *,
2087                     nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *,
2088                     vnode_t *, int, int);
2089 extern void     nfs4_open_downgrade(int, int, nfs4_open_owner_t *,
2090                     nfs4_open_stream_t *, vnode_t *, cred_t *,
2091                     nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *);
2092 extern seqid4   nfs4_get_open_seqid(nfs4_open_owner_t *);
2093 extern cred_t   *nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *);
2094 extern void     nfs4_init_stateid_types(nfs4_stateid_types_t *);
2095 extern void     nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *);
2096 
2097 extern kmutex_t nfs4_server_lst_lock;
2098 
2099 extern void     nfs4_cleanup_oldsession(nfs4_server_t *);
2100 extern void     nfs4destroy_session(nfs4_server_t *, CLIENT *);
2101 extern void     nfs4destroy_session_otw(nfs4_session_t *, CLIENT *);
2102 extern void     nfs41_cbinfo_rele(struct nfs41_cb_info *);
2103 extern void     nfs4callback_destroy(nfs4_server_t *);
2104 extern void     nfs4_callback_init(void);
2105 extern void     nfs4_callback_fini(void);
2106 
2107 extern void     nfs41_cb_args(nfs4_server_t *, struct knetconfig *,
2108                         CREATE_SESSION4args *);
2109 extern void     nfs4_cb_args(nfs4_server_t *, struct knetconfig *,
2110                         SETCLIENTID4args *);
2111 extern void     nfs41set_callback(nfs4_server_t *, servinfo4_t *,
2112                         mntinfo4_t *, cred_t *);
2113 extern void     nfs4delegreturn_async(struct rnode4 *, int, bool_t);
2114 
2115 extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy;
2116 
2117 extern void     nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *);
2118 extern void     nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *);
2119 extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *);
2120 extern bool_t   nfs4_fs_active(nfs4_server_t *);
2121 extern void     nfs4_server_hold(nfs4_server_t *);
2122 extern void     nfs4_server_rele(nfs4_server_t *);
2123 extern void     nfs4_server_rele_lockt(nfs4_server_t *);
2124 extern bool_t   inlease(nfs4_server_t *);
2125 extern bool_t   nfs4_has_pages(vnode_t *);
2126 extern void     nfs4_log_badowner(mntinfo4_t *, nfs_opnum4);
2127 
2128 #endif /* _KERNEL */
2129 
2130 /*
2131  * Client State Recovery
2132  */
2133 
2134 /*
2135  * The following defines are used for rs_flags in
2136  * a nfs4_recov_state_t structure.
2137  *
2138  * NFS4_RS_RENAME_HELD          Indicates that the mi_rename_lock was held.
2139  * NFS4_RS_GRACE_MSG            Set once we have uprintf'ed a grace message.
2140  * NFS4_RS_DELAY_MSG            Set once we have uprintf'ed a delay message.
2141  * NFS4_RS_RECALL_HELD1         r_deleg_recall_lock for vp1 was held.
2142  * NFS4_RS_RECALL_HELD2         r_deleg_recall_lock for vp2 was held.
2143  */
2144 #define NFS4_RS_RENAME_HELD     0x000000001
2145 #define NFS4_RS_GRACE_MSG       0x000000002
2146 #define NFS4_RS_DELAY_MSG       0x000000004
2147 #define NFS4_RS_RECALL_HELD1    0x000000008
2148 #define NFS4_RS_RECALL_HELD2    0x000000010
2149 
2150 /*
2151  * Information that is retrieved from nfs4_start_op() and that is
2152  * passed into nfs4_end_op().
2153  *
2154  * rs_sp is a reference to the nfs4_server that was found, or NULL.
2155  *
2156  * rs_num_retry_despite_err is the number times client retried an
2157  * OTW op despite a recovery error.  It is only incremented for hints
2158  * exempt to normal R4RECOVERR processing
2159  * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN).  (XXX this special-case code
2160  * needs review for possible removal.)
2161  * It is initialized wherever nfs4_recov_state_t is declared -- usually
2162  * very near initialization of rs_flags.
2163  */
2164 typedef struct {
2165         nfs4_server_t   *rs_sp;
2166         int             rs_flags;
2167         int             rs_num_retry_despite_err;
2168 } nfs4_recov_state_t;
2169 
2170 /*
2171  * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root.
2172  */
2173 
2174 #define NFS4_REMAP_CKATTRS      1
2175 #define NFS4_REMAP_NEEDSOP      2
2176 
2177 #ifdef _KERNEL
2178 
2179 extern int      nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int,
2180                         vnode_t *, int, int *, int, nfs4_recov_state_t *);
2181 extern void     nfs4exchange_id(struct mntinfo4 *, struct cred *, bool_t,
2182                         nfs4_error_t *);
2183 extern void     nfs4create_session(mntinfo4_t *, servinfo4_t *, cred_t *,
2184                         nfs4_server_t *, nfs4_error_t *);
2185 extern int      nfs4bind_conn_to_session(nfs4_server_t *, servinfo4_t *,
2186                         struct mntinfo4 *, cred_t *, channel_dir_from_client4);
2187 extern int      nfs4_tag_ctl(nfs4_server_t *, mntinfo4_t *, servinfo4_t *,
2188                         sessionid4, int, cred_t *);
2189 extern void     nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *,
2190                         open_claim_type4, bool_t, bool_t);
2191 extern void     nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int);
2192 extern void     nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int,
2193                         nfs4_error_t *);
2194 extern void     nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int,
2195                         nfs4_error_t *);
2196 extern int      nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t,
2197                         vnode_t *, cred_t *, vnode_t **, int);
2198 extern void     nfs4_fail_recov(vnode_t *, char *, int, nfsstat4);
2199 
2200 extern int      nfs4_needs_recovery(nfs4_error_t *, bool_t, vfs_t *);
2201 extern int      nfs4_recov_marks_dead(nfsstat4);
2202 extern bool_t   nfs4_start_recovery(nfs4_error_t *, struct mntinfo4 *,
2203                         vnode_t *, vnode_t *, stateid4 *,
2204                         nfs4_lost_rqst_t *, nfs_opnum4, nfs4_bseqid_entry_t *);
2205 extern int      nfs4_start_op(struct mntinfo4 *, vnode_t *, vnode_t *,
2206                         nfs4_recov_state_t *);
2207 extern void     nfs4_end_op(struct mntinfo4 *, vnode_t *, vnode_t *,
2208                         nfs4_recov_state_t *, bool_t);
2209 extern int      nfs4_start_fop(struct mntinfo4 *, vnode_t *, vnode_t *,
2210                         nfs4_op_hint_t, nfs4_recov_state_t *, bool_t *);
2211 extern void     nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *,
2212                                 nfs4_op_hint_t, nfs4_recov_state_t *, bool_t);
2213 extern char     *nfs4_recov_action_to_str(nfs4_recov_t);
2214 
2215 /*
2216  * In sequence, code desiring to unmount an ephemeral tree must
2217  * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate,
2218  * and nfs4_ephemeral_umount_unlock. The _unlock must also be
2219  * called on all error paths that occur before it would naturally
2220  * be invoked.
2221  *
2222  * The caller must also provde a pointer to a boolean to keep track
2223  * of whether or not the code in _unlock is to be ran.
2224  */
2225 extern void     nfs4_ephemeral_umount_activate(mntinfo4_t *,
2226     bool_t *, bool_t *, nfs4_ephemeral_tree_t **);
2227 extern int      nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *,
2228     bool_t *, bool_t *, nfs4_ephemeral_tree_t **);
2229 extern void     nfs4_ephemeral_umount_unlock(bool_t *, bool_t *,
2230     nfs4_ephemeral_tree_t **);
2231 
2232 extern int      nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp);
2233 
2234 extern int      wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t,
2235                         nfs4_recov_state_t *);
2236 extern void     nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *);
2237 extern void     nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t,
2238                     int, nfsstat4);
2239 extern time_t   nfs4err_delay_time;
2240 extern void     nfs4_set_grace_wait(mntinfo4_t *);
2241 extern void     nfs4_set_delay_wait(vnode_t *);
2242 extern int      nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *, int);
2243 extern int      nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *, int);
2244 extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *,
2245                     nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t,
2246                     seqid4);
2247 
2248 extern void     nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *,
2249                         nfs4_error_t *);
2250 extern void     nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *,
2251                         nfs4_server_t *);
2252 extern int      nfs4_rpc_retry_error(int);
2253 extern int      nfs4_try_failover(nfs4_error_t *);
2254 extern void     nfs4_free_msg(nfs4_debug_msg_t *);
2255 extern void     nfs4_mnt_recov_kstat_init(vfs_t *);
2256 extern void     nfs4_mi_kstat_inc_delay(mntinfo4_t *);
2257 extern void     nfs4_mi_kstat_inc_no_grace(mntinfo4_t *);
2258 extern char     *nfs4_stat_to_str(nfsstat4);
2259 extern char     *nfs4_op_to_str(nfs_opnum4);
2260 extern void     nfs4exchange_id_otw(mntinfo4_t *, servinfo4_t *, cred_t *,
2261                         nfs4_server_t *, nfs4_error_t *, int *);
2262 extern void     nfs4sequence_setup(nfs4_session_t *, COMPOUND4args_clnt *,
2263                         nfs4_slot_t **);
2264 extern void     nfs4sequence_fin(nfs4_session_t *, COMPOUND4res_clnt *,
2265                         nfs4_slot_t *, nfs4_error_t *);
2266 extern void     nfs4session_init(void);
2267 extern void     nfs4_pnfs_init_n4s(struct nfs4_server *);
2268 
2269 extern void     nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *,
2270                     uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t,
2271                     nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4);
2272 extern void     nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4,
2273                     nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *);
2274 #pragma rarely_called(nfs4_queue_event)
2275 #pragma rarely_called(nfs4_queue_fact)
2276 
2277 /* Used for preformed "." and ".." dirents */
2278 extern char     *nfs4_dot_entries;
2279 extern char     *nfs4_dot_dot_entry;
2280 
2281 #ifdef  DEBUG
2282 extern uint_t   nfs4_tsd_key;
2283 #endif
2284 
2285 #endif /* _KERNEL */
2286 
2287 /*
2288  * Filehandle management.
2289  *
2290  * Filehandles can change in v4, so rather than storing the filehandle
2291  * directly in the rnode, etc., we manage the filehandle through one of
2292  * these objects.
2293  * Locking: sfh_fh and sfh_tree is protected by the filesystem's
2294  * mi_fh_lock.  The reference count and flags are protected by sfh_lock.
2295  * sfh_mi is read-only.
2296  *
2297  * mntinfo4_t::mi_fh_lock > sfh_lock.
2298  */
2299 
2300 typedef struct nfs4_sharedfh {
2301         nfs_fh4 sfh_fh;                 /* key and current filehandle */
2302         kmutex_t sfh_lock;
2303         uint_t sfh_refcnt;              /* reference count */
2304         uint_t sfh_flags;
2305         mntinfo4_t *sfh_mi;             /* backptr to filesystem */
2306         avl_node_t sfh_tree;            /* used by avl package */
2307 } nfs4_sharedfh_t;
2308 
2309 #define SFH4_SAME(sfh1, sfh2)   ((sfh1) == (sfh2))
2310 
2311 /*
2312  * Flags.
2313  */
2314 #define SFH4_IN_TREE    0x1             /* currently in an AVL tree */
2315 
2316 #ifdef _KERNEL
2317 
2318 extern void sfh4_createtab(avl_tree_t *);
2319 extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *);
2320 extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *,
2321                                 nfs4_sharedfh_t *);
2322 extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *);
2323 extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *);
2324 extern void sfh4_hold(nfs4_sharedfh_t *);
2325 extern void sfh4_rele(nfs4_sharedfh_t **);
2326 extern void sfh4_printfhandle(const nfs4_sharedfh_t *);
2327 
2328 #endif
2329 
2330 /*
2331  * Path and file name management.
2332  *
2333  * This type stores the name of an entry in the filesystem and keeps enough
2334  * information that it can provide a complete path.  All fields are
2335  * protected by fn_lock, except for the reference count, which is managed
2336  * using atomic add/subtract.
2337  *
2338  * Additionally shared filehandle for this fname is stored.
2339  * Normally, fn_get() when it creates this fname stores the passed in
2340  * shared fh in fn_sfh by doing sfh_hold. Similarly the path which
2341  * destroys this fname releases the reference on this fh by doing sfh_rele.
2342  *
2343  * fn_get uses the fn_sfh to refine the comparision in cases
2344  * where we have matched the name but have differing file handles,
2345  * this normally happens due to
2346  *
2347  *      1. Server side rename of a file/directory.
2348  *      2. Another client renaming a file/directory on the server.
2349  *
2350  * Differing names but same filehandle is possible as in the case of hardlinks,
2351  * but differing filehandles with same name component will later confuse
2352  * the client and can cause various panics.
2353  *
2354  * Lock order: child and then parent.
2355  */
2356 
2357 typedef struct nfs4_fname {
2358         struct nfs4_fname *fn_parent;   /* parent name; null if fs root */
2359         char *fn_name;                  /* the actual name */
2360         nfs4_sharedfh_t *fn_sfh;        /* The fh for this fname */
2361         ssize_t fn_len;                 /* strlen(fn_name) */
2362         uint32_t fn_refcnt;             /* reference count */
2363         kmutex_t fn_lock;
2364         avl_node_t fn_tree;
2365         avl_tree_t fn_children;         /* children, if any */
2366 } nfs4_fname_t;
2367 
2368 #ifdef _KERNEL
2369 
2370 extern vnode_t  nfs4_xattr_notsupp_vnode;
2371 #define NFS4_XATTR_DIR_NOTSUPP  &nfs4_xattr_notsupp_vnode
2372 
2373 extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *);
2374 extern void fn_hold(nfs4_fname_t *);
2375 extern void fn_rele(nfs4_fname_t **);
2376 extern char *fn_name(nfs4_fname_t *);
2377 extern char *fn_path(nfs4_fname_t *);
2378 extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *);
2379 extern nfs4_fname_t *fn_parent(nfs4_fname_t *);
2380 #endif
2381 
2382 /*
2383  * Per-zone data for managing client handles, included in this file for the
2384  * benefit of MDB.
2385  */
2386 struct nfs4_clnt {
2387         struct chhead   *nfscl_chtable4;
2388         kmutex_t        nfscl_chtable4_lock;
2389         zoneid_t        nfscl_zoneid;
2390         list_node_t     nfscl_node;
2391         /*
2392          * nfscl_stat[0] for minor version 0
2393          * nfscl_stat[1] for minor version 1
2394          */
2395         struct clstat4 nfscl_stat[NFS4_MINORVERSMAX + 1];
2396 };
2397 
2398 /*
2399  * New recovery interfaces & structures
2400  */
2401 
2402 /* @(#)nfs4_call_t.c 1.1 08/06/25 */
2403 
2404 typedef struct {
2405         nfs4_recov_state_t nc_recov_state;
2406 
2407         mntinfo4_t      *nc_mi;
2408         vnode_t         *nc_vp1;
2409         vnode_t         *nc_vp2;
2410 
2411         /* needed by nfs4_start_fop */
2412         nfs4_op_hint_t  ophint;
2413         int             start_recov;
2414 
2415         /* needed by nfs4_needs_recovery */
2416         int             stateful;
2417         nfs4_error_t    e;
2418 
2419         /* needed by start_recovery */
2420         nfs_opnum4      opnum;
2421         stateid4        *nc_sidp;
2422         nfs4_lost_rqst_t *nc_lost_rqst;
2423         nfs4_bseqid_entry_t *nc_bseqid_rqst;
2424 
2425         /* needed by rfs4call */
2426 
2427         int             nc_doqueue[1];
2428         int             rfs4call_flags; /* typically 0 */
2429         cred_t          *cr;
2430 
2431         /* new pnfs stuffs */
2432 
2433         servinfo4_t     *ds_servinfo;   /* NULL if call targets MDS */
2434         nfs4_server_t   *ds_nfs4_srv;   /* NULL if call targets MDS */
2435         kmutex_t        nc_lock[1];
2436         uint_t          nc_count;
2437         int             nc_needs_recovery;
2438         int             nc_wait_for_recovery;
2439         uint32_t        nc_startop_flags;       /* nfs4_start_op(..., flags) */
2440 } nfs4_call_t;
2441 
2442 extern nfs4_call_t *nfs4_call_init(void);
2443 extern void nfs4_call_rele(nfs4_call_t *);
2444 extern void nfs4_call_hold(nfs4_call_t *);
2445 
2446 /*
2447  * Flags for client-side recovery interfaces.
2448  * Passed in as flags to nfs4_start_op() and stored in the nfs4_call_t.
2449  */
2450 #define RCV_DONTBLOCK   0x00000001      /* Don't block, return EAGAIN */
2451 
2452 /* interim */
2453 extern int nfs4_start_op_impl(nfs4_call_t *, uint32_t);
2454 extern void nfs4_end_op_impl(nfs4_call_t *);
2455 extern int nfs4_needs_recovery_impl(nfs4_call_t *);
2456 extern int nfs4_start_recovery_impl(nfs4_call_t *);
2457 extern void rfs4call_impl(nfs4_call_t *, COMPOUND4args_clnt *,
2458     COMPOUND4res_clnt *);
2459 
2460 #ifdef  __cplusplus
2461 }
2462 #endif
2463 
2464 #endif /* _NFS4_CLNT_H */
--- EOF ---