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