Print this page
    
NEX-16452 NFS server in a zone state database needs to be per zone
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-6778 NFS kstats leak and cause system to hang
Revert "NEX-4261 Per-client NFS server IOPS, bandwidth, and latency kstats"
This reverts commit 586c3ab1927647487f01c337ddc011c642575a52.
Revert "NEX-5354 Aggregated IOPS, bandwidth, and latency kstats for NFS server"
This reverts commit c91d7614da8618ef48018102b077f60ecbbac8c2.
Revert "NEX-5667 nfssrv_stats_flags does not work for aggregated kstats"
This reverts commit 3dcf42618be7dd5f408c327f429c81e07ca08e74.
Revert "NEX-5750 Time values for aggregated NFS server kstats should be normalized"
This reverts commit 1f4d4f901153b0191027969fa4a8064f9d3b9ee1.
Revert "NEX-5942 Panic in rfs4_minorvers_mismatch() with NFSv4.1 client"
This reverts commit 40766417094a162f5e4cc8786c0fa0a7e5871cd9.
Revert "NEX-5752 NFS server: namespace collision in kstats"
This reverts commit ae81e668db86050da8e483264acb0cce0444a132.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-4261 Per-client NFS server IOPS, bandwidth, and latency kstats
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3097 IOPS, bandwidth, and latency kstats for NFS server
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/nfs/nfs4.h
          +++ new/usr/src/uts/common/nfs/nfs4.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   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  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  /*
  23      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
       24 + * Use is subject to license terms.
  24   25   */
  25   26  
  26   27  /*
  27      - * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  28      - * Use is subject to license terms.
       28 + * Copyright 2018 Nexenta Systems, Inc.
  29   29   */
  30   30  
  31   31  #ifndef _NFS4_H
  32   32  #define _NFS4_H
  33   33  
  34   34  #include <sys/types.h>
  35   35  #include <sys/vnode.h>
  36   36  #include <sys/fem.h>
  37   37  #include <rpc/rpc.h>
  38   38  #include <nfs/nfs.h>
  39   39  
  40   40  #ifdef _KERNEL
  41   41  #include <nfs/nfs4_kprot.h>
       42 +#include <nfs/nfs4_drc.h>
  42   43  #include <sys/nvpair.h>
  43   44  #else
  44   45  #include <rpcsvc/nfs4_prot.h>
  45   46  #endif
  46   47  #include <nfs/nfs4_attr.h>
  47   48  #include <sys/acl.h>
  48   49  #include <sys/list.h>
  49   50  
  50   51  #ifdef  __cplusplus
  51   52  extern "C" {
  52   53  #endif
  53   54  
  54   55  #define NFS4_MAX_SECOID4        65536
  55   56  #define NFS4_MAX_UTF8STRING     65536
  56   57  #define NFS4_MAX_LINKTEXT4      65536
  57   58  #define NFS4_MAX_PATHNAME4      65536
  58   59  
  59   60  struct nfs_fsl_info {
  60   61          uint_t netbuf_len;
  61   62          uint_t netnm_len;
  62   63          uint_t knconf_len;
  63   64          char *netname;
  64   65          struct netbuf *addr;
  65   66          struct knetconfig *knconf;
  66   67  };
  67   68  
  68   69  #ifdef _KERNEL
  69   70  
  70   71  typedef struct nfs4_fhandle {
  71   72          int fh_len;
  72   73          char fh_buf[NFS4_FHSIZE];
  73   74  } nfs4_fhandle_t;
  74   75  
  75   76  #define NFS4_MINORVERSION 0
  76   77  #define CB4_MINORVERSION 0
  77   78  
  78   79  /*
  79   80   * Set the fattr4_change variable using a time struct. Note that change
  80   81   * is 64 bits, but timestruc_t is 128 bits in a 64-bit kernel.
  81   82   */
  82   83  #define NFS4_SET_FATTR4_CHANGE(change, ts)                      \
  83   84  {                                                       \
  84   85          change = (ts).tv_sec;                           \
  85   86          change <<= 32;                                  \
  86   87          change |= (uint32_t)((ts).tv_nsec);             \
  87   88  }
  88   89  
  89   90  /*
  90   91   * Server lease period.  Value is in seconds;  Also used for grace period
  91   92   */
  92   93  extern time_t rfs4_lease_time;
  93   94  
  94   95  /*
  95   96   * This set of typedefs and interfaces represent the core or base set
  96   97   * of functionality that backs the NFSv4 server's state related data
  97   98   * structures.  Since the NFSv4 server needs inter-RPC state to be
  98   99   * available that is unrelated to the filesystem (in other words,
  99  100   * soft-state), this functionality is needed to maintain that and is
 100  101   * written to be somewhat flexible to adapt to the various types of
 101  102   * data structures contained within the server.
 102  103   *
 103  104   * The basic structure at this level is that the server maintains a
 104  105   * global "database" which consists of a set of tables.  Each table
 105  106   * contains a set of like data structures.  Each table is indexed by
 106  107   * at least one hash function and in most cases two hashes.  Each
 107  108   * table's characteristics is set when it is created at run-time via
 108  109   * rfs4_table_create().  All table creation and related functions are
 109  110   * located in nfs4_state.c.  The generic database functionality is
 110  111   * located in nfs4_db.c.
 111  112   */
  
    | 
      ↓ open down ↓ | 
    60 lines elided | 
    
      ↑ open up ↑ | 
  
 112  113  
 113  114  typedef struct rfs4_dbe rfs4_dbe_t;             /* basic opaque db entry */
 114  115  typedef struct rfs4_table rfs4_table_t;         /* basic table type */
 115  116  typedef struct rfs4_index rfs4_index_t;         /* index */
 116  117  typedef struct rfs4_database rfs4_database_t;   /* and database */
 117  118  
 118  119  typedef struct {                /* opaque entry type for later use */
 119  120          rfs4_dbe_t *dbe;
 120  121  } *rfs4_entry_t;
 121  122  
 122      -extern rfs4_table_t *rfs4_client_tab;
      123 +/*
      124 + * NFSv4 server state databases
      125 + *
      126 + * Initilized when the module is loaded and used by NFSv4 state tables.
      127 + * These kmem_cache free pools are used globally, the NFSv4 state tables
      128 + * which make use of these kmem_cache free pools are per zone.
      129 + */
      130 +extern kmem_cache_t *rfs4_client_mem_cache;
      131 +extern kmem_cache_t *rfs4_clntIP_mem_cache;
      132 +extern kmem_cache_t *rfs4_openown_mem_cache;
      133 +extern kmem_cache_t *rfs4_openstID_mem_cache;
      134 +extern kmem_cache_t *rfs4_lockstID_mem_cache;
      135 +extern kmem_cache_t *rfs4_lockown_mem_cache;
      136 +extern kmem_cache_t *rfs4_file_mem_cache;
      137 +extern kmem_cache_t *rfs4_delegstID_mem_cache;
 123  138  
 124  139  /* database, table, index creation entry points */
 125  140  extern rfs4_database_t *rfs4_database_create(uint32_t);
 126  141  extern void             rfs4_database_shutdown(rfs4_database_t *);
 127  142  extern void             rfs4_database_destroy(rfs4_database_t *);
 128  143  
 129  144  extern void             rfs4_database_destroy(rfs4_database_t *);
 130  145  
      146 +extern kmem_cache_t     *nfs4_init_mem_cache(char *, uint32_t, uint32_t,
      147 +                                uint32_t);
 131  148  extern rfs4_table_t     *rfs4_table_create(rfs4_database_t *, char *,
 132  149                                  time_t, uint32_t,
 133  150                                  bool_t (*create)(rfs4_entry_t, void *),
 134  151                                  void (*destroy)(rfs4_entry_t),
 135  152                                  bool_t (*expiry)(rfs4_entry_t),
 136  153                                  uint32_t, uint32_t, uint32_t, id_t);
 137  154  extern void             rfs4_table_destroy(rfs4_database_t *, rfs4_table_t *);
 138  155  extern rfs4_index_t     *rfs4_index_create(rfs4_table_t *, char *,
 139  156                                  uint32_t (*hash)(void *),
 140  157                                  bool_t (compare)(rfs4_entry_t, void *),
 141  158                                  void *(*mkkey)(rfs4_entry_t), bool_t);
 142  159  extern void             rfs4_index_destroy(rfs4_index_t *);
 143  160  
 144  161  /* Type used to direct rfs4_dbsearch() in what types of records to inspect */
 145  162  typedef enum {RFS4_DBS_VALID, RFS4_DBS_INVALID} rfs4_dbsearch_type_t;
 146  163  /* search and db entry manipulation entry points */
 147  164  extern rfs4_entry_t     rfs4_dbsearch(rfs4_index_t *, void *,
 148  165                                  bool_t *, void *, rfs4_dbsearch_type_t);
 149  166  extern void             rfs4_dbe_lock(rfs4_dbe_t *);
 150  167  extern void             rfs4_dbe_unlock(rfs4_dbe_t *);
 151  168  extern clock_t          rfs4_dbe_twait(rfs4_dbe_t *, clock_t);
 152  169  extern void             rfs4_dbe_cv_broadcast(rfs4_dbe_t *);
 153  170  extern void             rfs4_dbe_hold(rfs4_dbe_t *);
 154  171  extern void             rfs4_dbe_hold_nolock(rfs4_dbe_t *);
 155  172  extern void             rfs4_dbe_rele_nolock(rfs4_dbe_t *);
 156  173  extern void             rfs4_dbe_rele(rfs4_dbe_t *);
 157  174  extern uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *);
 158  175  extern id_t             rfs4_dbe_getid(rfs4_dbe_t *);
 159  176  extern void             rfs4_dbe_invalidate(rfs4_dbe_t *);
 160  177  extern bool_t           rfs4_dbe_is_invalid(rfs4_dbe_t *);
 161  178  extern time_t           rfs4_dbe_get_timerele(rfs4_dbe_t *);
 162  179  extern void             rfs4_dbe_hide(rfs4_dbe_t *);
 163  180  extern void             rfs4_dbe_unhide(rfs4_dbe_t *);
 164  181  #ifdef DEBUG
 165  182  extern bool_t           rfs4_dbe_islocked(rfs4_dbe_t *);
 166  183  #endif
 167  184  extern void             rfs4_dbe_walk(rfs4_table_t *,
 168  185                          void (*callout)(rfs4_entry_t, void *), void *);
 169  186  
 170  187  /*
 171  188   * Minimal server stable storage.
 172  189   *
 173  190   * Currently the NFSv4 server will only save the client
 174  191   * ID (the long version) so that it will be able to
 175  192   * grant possible reclaim requests during the infamous
 176  193   * grace_period.
 177  194   */
 178  195  
 179  196  #define RFS4_SS_DIRSIZE 64 * 1024
 180  197  #define NFS4_SS_VERSION 1
 181  198  
 182  199  /* handy pathname structure */
 183  200  typedef struct ss_pn {
 184  201          char *leaf;
 185  202          char pn[MAXPATHLEN];
 186  203  } rfs4_ss_pn_t;
 187  204  
 188  205  /*
 189  206   * The server will build this link list on startup. It represents the
 190  207   * clients that have had valid state on the server in a prior instance.
 191  208   *
 192  209   */
 193  210  typedef struct rfs4_oldstate {
 194  211          struct rfs4_oldstate    *next;
 195  212          struct rfs4_oldstate    *prev;
 196  213          rfs4_ss_pn_t            *ss_pn;
 197  214          nfs_client_id4          cl_id4;
 198  215  } rfs4_oldstate_t;
 199  216  
 200  217  /*
 201  218   * This union is used to overlay the server's internal treatment of
 202  219   * the protocols stateid4 datatype.  Therefore, "bits" must not exceed
 203  220   * the size of stateid4 and more importantly should match the size of
 204  221   * stateid4.  The chgseq field must the first entry since it overlays
 205  222   * stateid4.seqid.
 206  223   */
 207  224  typedef union {
 208  225          stateid4 stateid;
 209  226          struct {
 210  227                  uint32_t chgseq;        /* State changes / protocol's seqid */
 211  228                  uint32_t boottime;      /* boot time  */
 212  229                  uint32_t type:2;        /* stateid_type_t as define below */
 213  230                  uint32_t clnodeid:8;    /* cluster server nodeid */
 214  231                  uint32_t ident:22;      /* 2^22-1 openowner x fhs */
 215  232                  pid_t    pid;           /* pid of corresponding lock owner */
 216  233          } bits;
 217  234  } stateid_t;
 218  235  /*
 219  236   * Note that the way the type field above is defined, this enum must
 220  237   * not have more than 4 members.
 221  238   */
 222  239  typedef enum {OPENID, LOCKID, DELEGID} stateid_type_t;
 223  240  
 224  241  
 225  242  /*
 226  243   * Set of RPC credentials used for a particular operation.
 227  244   * Used for operations like SETCLIENTID_CONFIRM where the
 228  245   * credentials needs to match those used at SETCLIENTID.
 229  246   */
 230  247  typedef void *cred_set_t;               /* For now XXX */
 231  248  
 232  249  /*
 233  250   * "wait" struct for use in the open open and lock owner state
 234  251   * structures to provide serialization between server threads that are
 235  252   * handling requests for the same open owner or lock stateid.  This
 236  253   * way only one thread will be updating things like sequence ids,
 237  254   * replay cache and stateid at a time.
 238  255   */
 239  256  typedef struct rfs4_state_wait {
 240  257          uint32_t                sw_active;
 241  258          uint32_t                sw_wait_count;
 242  259          kmutex_t                sw_cv_lock[1];
 243  260          kcondvar_t              sw_cv[1];
 244  261  } rfs4_state_wait_t;
 245  262  
 246  263  extern void     rfs4_sw_enter(rfs4_state_wait_t *);
 247  264  extern void     rfs4_sw_exit(rfs4_state_wait_t *);
 248  265  
 249  266  /*
 250  267   * This enum and the following rfs4_cbinfo_t struct are used to
 251  268   * maintain information about the callback path used from the server
 252  269   * to client for operations like CB_GETATTR and CB_RECALL.  The
 253  270   * rfs4_cbinfo_t struct is meant to be encompassed in the client
 254  271   * struct and managed within that structure's locking scheme.
 255  272   *
 256  273   * The various states of the callback path are used by the server to
 257  274   * determine if delegations should initially be provided to a client
 258  275   * and then later on if connectivity has been lost and delegations
 259  276   * should be revoked.
 260  277   */
 261  278  
 262  279  /*
 263  280   * CB_NOCHANGE - Special value used for interfaces within the delegation
 264  281   *              code to signify that "no change" has occurred to the
 265  282   *              callback path
 266  283   * CB_UNINIT    - No callback info provided by the client
 267  284   * CB_NONE      - Callback info provided but CB_NULL call
 268  285   *                has yet to be attempted
 269  286   * CB_OK        - Callback path tested with CB_NULL with success
 270  287   * CB_INPROG    - Callback path currently being tested with CB_NULL
 271  288   * CB_FAILED    - Callback path was == CB_OK but has failed
 272  289   *                with timeout/rpc error
 273  290   * CB_BAD       - Callback info provided but CB_NULL failed
 274  291   */
 275  292  typedef enum {
 276  293          CB_NOCHANGE = 0,
 277  294          CB_UNINIT = 1,
 278  295          CB_NONE = 2,
 279  296          CB_OK = 3,
 280  297          CB_INPROG = 4,
 281  298          CB_FAILED = 5,
 282  299          CB_BAD = 6
 283  300  } rfs4_cbstate_t;
 284  301  
 285  302  #define RFS4_CBCH_MAX   10      /* size callback client handle cache */
 286  303  /*
 287  304   * Callback info for a client.
 288  305   * Client only provides: cb_client4 and cb_ident
 289  306   * The rest of the information is used to track callback path status
 290  307   * and usage.
 291  308   *
 292  309   * cb_state - used as comments for the rfs4_cbstate_t enum indicate
 293  310   * cb_notified_of_cb_path_down - if the callback path was once CB_OK and
 294  311   *      has hence CB_FAILED, the client needs to be notified via RENEW.
 295  312   * cb_timefailed - current time when cb_state transitioned from
 296  313   *      CB_OK -> CB_FAILED.  Meant for observability.  When did that happen?
 297  314   * cb_chc_free/cb_chc - cache of client handles for the callback path
 298  315   * cb_ident - SETCLIENTID provided callback_ident value
 299  316   * callback - SETCLIENTID provided cb_client4 value
 300  317   * cb_refcnt - current number of users of this structure's content
 301  318   *      protected by cb_lock
 302  319   * cb_badbehavior - how many times did a client do something we didn't like?
 303  320   * cb_lock - lock for contents of cbinfo
 304  321   * cb_cv - used to allow threads to wait on CB_NULL completion
 305  322   * cb_nullcaller - is there a thread currently taking care of
 306  323   *      new callback information?
 307  324   * cb_cv_nullcaller - used by the thread doing CB_NULL to wait on
 308  325   *      threads that may be using client handles of the current
 309  326   *      client handle cache.
 310  327   * newer - new callback info provided by a client and awaiting
 311  328   *      CB_NULL testing and move to regular cbinfo.
 312  329   */
 313  330  typedef struct {
 314  331          rfs4_cbstate_t  cb_state;
 315  332          unsigned        cb_notified_of_cb_path_down:1;
 316  333          time_t          cb_timefailed;
 317  334          int             cb_chc_free;
 318  335          CLIENT          *cb_chc[RFS4_CBCH_MAX];
 319  336          uint32_t        cb_ident;
 320  337          cb_client4      cb_callback;
 321  338          uint32_t        cb_refcnt;
 322  339          uint32_t        cb_badbehavior;
 323  340          kmutex_t        cb_lock[1];
 324  341          kcondvar_t      cb_cv[1];
 325  342          bool_t          cb_nullcaller;
 326  343          kcondvar_t      cb_cv_nullcaller[1];
 327  344          struct {
 328  345                  bool_t          cb_new;
 329  346                  bool_t          cb_confirmed;
 330  347                  uint32_t        cb_ident;
 331  348                  cb_client4      cb_callback;
 332  349          } cb_newer;
 333  350  } rfs4_cbinfo_t;
 334  351  
 335  352  /*
 336  353   * A server instance. We can associate sets of clients - via a pointer in
 337  354   * rfs4_client_t - with a given server instance, allowing us to treat clients
 338  355   * in the set differently to clients in other sets.
 339  356   *
 340  357   * Currently used only for Sun Cluster HA-NFS support, to group clients
 341  358   * on NFS resource failover so each set of clients gets its own dedicated
 342  359   * grace period and distributed stable storage data.
 343  360   */
 344  361  typedef struct rfs4_servinst {
 345  362          int                     dss_npaths;
 346  363          krwlock_t               rwlock;
 347  364          krwlock_t               oldstate_lock;
 348  365          time_t                  start_time;
 349  366          time_t                  grace_period;
 350  367          rfs4_oldstate_t         *oldstate;
 351  368          struct rfs4_dss_path    **dss_paths;
 352  369          struct rfs4_servinst    *next;
 353  370          struct rfs4_servinst    *prev;
 354  371  } rfs4_servinst_t;
 355  372  
 356  373  /*
 357  374   * DSS: distributed stable storage
 358  375   */
 359  376  
 360  377  typedef struct rfs4_dss_path {
 361  378          struct rfs4_dss_path    *next; /* for insque/remque */
  
    | 
      ↓ open down ↓ | 
    221 lines elided | 
    
      ↑ open up ↑ | 
  
 362  379          struct rfs4_dss_path    *prev; /* for insque/remque */
 363  380          char                    *path;
 364  381          struct rfs4_servinst    *sip;
 365  382          unsigned                index; /* offset in servinst's array */
 366  383  } rfs4_dss_path_t;
 367  384  
 368  385  /* array of paths passed-in from nfsd command-line; stored in nvlist */
 369  386  char            **rfs4_dss_newpaths;
 370  387  uint_t          rfs4_dss_numnewpaths;
 371  388  
 372      -/*
 373      - * Circular doubly-linked list of paths for currently-served RGs.
 374      - * No locking required: only changed on warmstart. Managed with insque/remque.
 375      - */
 376      -rfs4_dss_path_t *rfs4_dss_pathlist;
 377      -
 378  389  /* nvlists of all DSS paths: current, and before last warmstart */
 379  390  nvlist_t *rfs4_dss_paths, *rfs4_dss_oldpaths;
 380  391  
 381  392  /*
 382  393   * The server maintains a set of state on a per client basis that
 383  394   * matches that of the protocol requirements.  A client's state is
 384  395   * rooted with the rfs4_client_t struct of which there is one per
 385  396   * client and is created when SETCLIENTID/SETCLIENTID_CONFIRM are
 386  397   * received.  From there, the server then creates rfs4_openowner_t
 387  398   * structs for each new open owner from that client and are initiated
 388  399   * at OPEN/OPEN_CONFIRM (when the open owner is new to the server).
 389  400   * At OPEN, at least two other structures are created, and potentially a
 390  401   * third.  rfs4_state_t is created to track the association between an
 391  402   * open owner and a particular file. An rfs4_file_t struct may be
 392  403   * created (if the file is not already open) at OPEN as well.  The
 393  404   * rfs4_file_t struct is the only one that is per server and not per
 394  405   * client.  The rfs4_deleg_state_t struct is created in the
 395  406   * instance that the server is going to provide a delegation for the
 396  407   * file being OPENed.  Finally, the rfs4_lockowner_t is created at the
 397  408   * first use of a lock owner at the server and is a result of the LOCK
 398  409   * operation.  The rfs4_lo_state_t struct is then created to represent
 399  410   * the relation between the lock owner and the file.
 400  411   *
 401  412   */
 402  413  /*
 403  414   * The following ascii art represents each of these data structs and
 404  415   * their references to each other.  Note: "<-(x)->" represents the
 405  416   * doubly link lists (list_t).
 406  417   *
 407  418   *                          ____________________
 408  419   *                         |                    |
 409  420   *                         |    rfs4_client_t   |
 410  421   *                       ->|         (1)        |<-
 411  422   *                      /  |____________________|  \
 412  423   *                     /              ^             \
 413  424   *                    /               |              \
 414  425   *  ____________________    ____________________    ____________________
 415  426   * |                    |  |                    |  |                    |
 416  427   * |  rfs4_lockowner_t  |  |  rfs4_openowner_t  |  | rfs4_deleg_state_t |
 417  428   * |                    |  |     (3)    <-(1)-> |  |            <-(2)-> |
 418  429   * |____________________|  |____________________|  |____________________|
 419  430   *           ^                        ^                       |
 420  431   *           |                        |                       V
 421  432   *  ____________________    ____________________    ____________________
 422  433   * |                    |  |                    |  |                    |
 423  434   * |  rfs4_lo_state_t   |->|    rfs4_state_t    |->|     rfs4_file_t    |
 424  435   * |            <-(4)-> |  |     (4)    <-(3)-> |  |        (2)         |
 425  436   * |____________________|  |____________________|  |____________________|
 426  437   */
 427  438  /*
 428  439   * Each of these data types are kept in a separate rfs4_table_t and is
 429  440   * actually encapsulated within a rfs4_dbe_t struct.  The various
 430  441   * tables and their construction is done in nfs4_state.c but
 431  442   * documented here to completeness.
 432  443   *
 433  444   * Table                Data struct stored      Indexed by
 434  445   * -----                ------------------      ----------
 435  446   * rfs4_client_tab      rfs4_client_t           nfs_client_id4
 436  447   *                                              clientid4
 437  448   *
 438  449   * rfs4_openowner_tab   rfs4_openowner_t        open_owner4
 439  450   *
 440  451   * rfs4_state_tab       rfs4_state_t            open_owner4 | file
 441  452   *                                              stateid
 442  453   *
 443  454   * rfs4_lo_state_tab    rfs4_lo_state_t         lockowner | stateid
 444  455   *                                              lock_stateid
 445  456   *
 446  457   * rfs4_lockowner_tab   rfs4_lockowner_t        lockowner
 447  458   *                                              pid
 448  459   *
 449  460   * rfs4_file_tab        rfs4_file_t             filehandle
 450  461   *
 451  462   * rfs4_deleg_state_tab rfs4_deleg_state_t      clientid4 | file
 452  463   *                                              deleg_stateid
 453  464   */
 454  465  
 455  466  /*
 456  467   * The client struct, it is the root of all state for a particular
 457  468   * client.  The client is identified by the nfs_client_id4 via
 458  469   * SETCLIENTID and the server returns the clientid4 as short hand reference
 459  470   */
 460  471  /*
 461  472   * Client struct - as mentioned above it is the root of all state for
 462  473   * a single client as identified by the client supplied nfs_client_id4
 463  474   *
 464  475   * dbe - encapsulation struct
 465  476   * clientid - server assigned short hand reference to client
 466  477   * nfs_client - client supplied identifier for itself
 467  478   * confirm_verf - the value provided to the client for SETCLIENTID_CONFIRM
 468  479   * need_confirm - does this client need to be SETCLIENTID_CONFIRMed?
 469  480   *
 470  481   * unlksys_completed - has an F_UNLKSYS been done for this client which
 471  482   *              says that the use of cleanlocks() on individual files
 472  483   *              is not required?
 473  484   * can_reclaim - indicates if client is allowed to reclaim after server
 474  485   *              start-up (client had previous state at server)
 475  486   * ss_remove - indicates that the rfs4_client_destroy function should
 476  487   *              clean up stable storage file.
 477  488   * forced_expire - set if the sysadmin has used clear_locks for this client.
 478  489   * no_referrals - set if the client is Solaris and pre-dates referrals
 479  490   * deleg_revoked - how many delegations have been revoked for this client?
 480  491   *
 481  492   * cp_confirmed - this refers to a confirmed client struct that has
 482  493   * the same nfs_client_id4 as this client struct.  When/if this client
 483  494   * struct is confirmed via SETCLINETID_CONFIRM, the previously
 484  495   * confirmed client struct will be "closed" and hence this reference.
 485  496   *
 486  497   * last_access - used to determine if the client has let its lease expire
 487  498   * cbinfo - struct containing all callback related information
 488  499   * cr_set - credentials used for the SETCLIENTID/SETCLIENTID_CONFIRM pair
 489  500   * sysid - the lock manager sysid allocated for this client's file locks
 490  501   * openownerlist - root of openowners list associated with this client
 491  502   * ss_pn - Pathname to the stable storage file.
 492  503   * cl_addr - Clients network address.
 493  504   * server_instance - pointer to the currently associated server instance
 494  505   */
 495  506  typedef struct rfs4_client {
 496  507          rfs4_dbe_t              *rc_dbe;
 497  508          clientid4               rc_clientid;
 498  509          nfs_client_id4          rc_nfs_client;
 499  510          verifier4               rc_confirm_verf;
 500  511          unsigned                rc_need_confirm:1;
 501  512          unsigned                rc_unlksys_completed:1;
 502  513          unsigned                rc_can_reclaim:1;
 503  514          unsigned                rc_ss_remove:1;
 504  515          unsigned                rc_forced_expire:1;
 505  516          uint_t                  rc_deleg_revoked;
 506  517          struct rfs4_client      *rc_cp_confirmed;
 507  518          time_t                  rc_last_access;
 508  519          rfs4_cbinfo_t           rc_cbinfo;
 509  520          cred_set_t              rc_cr_set;
 510  521          sysid_t                 rc_sysidt;
 511  522          list_t                  rc_openownerlist;
 512  523          rfs4_ss_pn_t            *rc_ss_pn;
 513  524          struct sockaddr_storage rc_addr;
 514  525          rfs4_servinst_t         *rc_server_instance;
 515  526  } rfs4_client_t;
 516  527  
 517  528  /*
 518  529   * ClntIP struct - holds the diagnosis about whether the client
 519  530   * cannot support referrals.  Set to true for old Solaris clients.
 520  531   */
 521  532  
 522  533  typedef struct rfs4_clntip {
 523  534          rfs4_dbe_t              *ri_dbe;
 524  535          struct sockaddr_storage ri_addr;
 525  536          unsigned                ri_no_referrals:1;
 526  537  } rfs4_clntip_t;
 527  538  
 528  539  /*
 529  540   * The openowner contains the client supplied open_owner4 as well as
 530  541   * the matching sequence id and is used to track the client's usage of
 531  542   * the open_owner4.  Note that a reply is saved here as well for
 532  543   * processing of retransmissions.
 533  544   *
 534  545   * dbe - encapsulation struct
 535  546   * client - reference to rfs4_client_t for this openowner
 536  547   * owner - actual client supplied open_owner4
 537  548   * need_confirm - does this openowner need to be OPEN_CONFIRMed
 538  549   * postpone_confirm - set if error received on first use of open_owner
 539  550   * state2confirm - what stateid4 should be used on the OPEN_CONFIRM
 540  551   * open_seqid - what is the next open_seqid expected for this openowner
 541  552   * oo_sw - used to serialize access to the open seqid/reply handling
 542  553   * cr_set - credential used for the OPEN
 543  554   * statelist - root of state struct list associated with this openowner
 544  555   * node - node for client struct list of openowners
 545  556   * reply_fh - open replay processing needs the filehandle so that it is
 546  557   *      able to reset the current filehandle for appropriate compound
 547  558   *      processing and reply.
 548  559   * reply - last reply sent in relation to this openowner
 549  560   */
 550  561  typedef struct rfs4_openowner {
 551  562          rfs4_dbe_t              *ro_dbe;
 552  563          rfs4_client_t           *ro_client;
 553  564          open_owner4             ro_owner;
 554  565          unsigned                ro_need_confirm:1;
 555  566          unsigned                ro_postpone_confirm:1;
 556  567          seqid4                  ro_open_seqid;
 557  568          rfs4_state_wait_t       ro_sw;
 558  569          cred_set_t              ro_cr_set;
 559  570          list_t                  ro_statelist;
 560  571          list_node_t             ro_node;
 561  572          nfs_fh4                 ro_reply_fh;
 562  573          nfs_resop4              ro_reply;
 563  574  } rfs4_openowner_t;
 564  575  
 565  576  /*
 566  577   * This state struct represents the association between an openowner
 567  578   * and a file that has been OPENed by that openowner.
 568  579   *
 569  580   * dbe - encapsulation struct
 570  581   * stateid - server provided stateid
 571  582   * owner - reference back to the openowner for this state
 572  583   * finfo - reference to the open file for this state
 573  584   * open_access - how did the openowner OPEN the file (access)
 574  585   * open_deny - how did the openowner OPEN the file (deny)
 575  586   * share_access - what share reservation is on the file (access)
 576  587   * share_deny - what share reservation is on the file (deny)
 577  588   * closed - has this file been closed?
 578  589   * lostatelist - root of list of lo_state associated with this state/file
 579  590   * node - node for state struct list of states
 580  591   */
 581  592  typedef struct rfs4_state {
 582  593          rfs4_dbe_t              *rs_dbe;
 583  594          stateid_t               rs_stateid;
 584  595          rfs4_openowner_t        *rs_owner;
 585  596          struct rfs4_file        *rs_finfo;
 586  597          uint32_t                rs_open_access;
 587  598          uint32_t                rs_open_deny;
 588  599          uint32_t                rs_share_access;
 589  600          uint32_t                rs_share_deny;
 590  601          unsigned                rs_closed:1;
 591  602          list_t                  rs_lostatelist;
 592  603          list_node_t             rs_node;
 593  604  } rfs4_state_t;
 594  605  
 595  606  /*
 596  607   * Lockowner - track the lockowner and its related info
 597  608   *
 598  609   * dbe - encapsulation struct
 599  610   * client - reference to the client
 600  611   * owner - lockowner supplied by the client
 601  612   * pid - local identifier used for file locking
 602  613   */
 603  614  typedef struct rfs4_lockowner {
 604  615          rfs4_dbe_t              *rl_dbe;
 605  616          rfs4_client_t           *rl_client;
 606  617          lock_owner4             rl_owner;
 607  618          pid_t                   rl_pid;
 608  619  } rfs4_lockowner_t;
 609  620  
 610  621  /*
 611  622   * Lockowner_state associated with a state struct and lockowner
 612  623   *
 613  624   * dbe - encapsulation struct
 614  625   * state - reference back to state struct for open file
 615  626   * lockid - stateid for this lockowner/state
 616  627   * locker - reference to lockowner
 617  628   * seqid - sequence id for this lockowner/state
 618  629   * skip_seqid_check - used on initialization of struct
 619  630   * locks_cleaned - have all locks been released for this lockowner/file?
 620  631   * lock_completed - successful LOCK with lockowner/file?
 621  632   * ls_sw - used to serialize update seqid/reply/stateid handling
 622  633   * node - node for state struct list of lo_states
 623  634   * reply - last reply sent in relation to this lockowner/state
 624  635   */
 625  636  typedef struct rfs4_lo_state {
 626  637          rfs4_dbe_t              *rls_dbe;
 627  638          rfs4_state_t            *rls_state;
 628  639          stateid_t               rls_lockid;
 629  640          rfs4_lockowner_t        *rls_locker;
 630  641          seqid4                  rls_seqid;
 631  642          unsigned                rls_skip_seqid_check:1;
 632  643          unsigned                rls_locks_cleaned:1;
 633  644          unsigned                rls_lock_completed:1;
 634  645          rfs4_state_wait_t       rls_sw;
 635  646          list_node_t             rls_node;
 636  647          nfs_resop4              rls_reply;
 637  648  } rfs4_lo_state_t;
 638  649  
 639  650  /*
 640  651   * Delegation state - per client
 641  652   *
 642  653   * dbe - encapsulation struct
 643  654   * dtype - type of delegation (NONE, READ, WRITE)
 644  655   * delegid - stateid for this delegation
 645  656   * time_granted - time this delegation was assigned to client
 646  657   * time_recalled - time when the server started recall process
 647  658   * time_revoked - if revoked, time that the revoke occurred
 648  659   * finfo - reference to the file associated with this delegation
 649  660   * client - reference to client for which this delegation is associated
 650  661   * node - list of delegations for the file (WRITE == 1, READ == )
 651  662   */
 652  663  typedef struct rfs4_deleg_state {
 653  664          rfs4_dbe_t              *rds_dbe;
 654  665          open_delegation_type4   rds_dtype;
 655  666          stateid_t               rds_delegid;
 656  667          time_t                  rds_time_granted;
 657  668          time_t                  rds_time_recalled;
 658  669          time_t                  rds_time_revoked;
 659  670          struct rfs4_file        *rds_finfo;
 660  671          rfs4_client_t           *rds_client;
 661  672          list_node_t             rds_node;
 662  673  } rfs4_deleg_state_t;
 663  674  
 664  675  /*
 665  676   * Delegation info associated with the file
 666  677   *
 667  678   * dtype - type of delegation for file (NONE, READ, WRITE)
 668  679   * time_returned - time that last delegation was returned for file
 669  680   * time_recalled - time that recall sequence started
 670  681   * time_lastgrant - time that last delegation was provided to a client
 671  682   * time_lastwrite - time of last write to use the delegation stateid
 672  683   * time_rm_delayed - time of last remove/rename which was DELAYed
 673  684   * rdgrants - how many read delegations have been provided for this file
 674  685   * wrgrants - how many write delegations provided (can only be one)
 675  686   * recall_count - how many recall threads are outstanding
 676  687   * recall_lock - lock to protect contents of this struct
 677  688   * recall_cv - condition var for the "parent" thread to wait upon
 678  689   * deleg_change_grant - value for change attribute at time of write grant
 679  690   * deleg_change - most recent value of change obtained from client
 680  691   * deleg_change_ts - time of last deleg_change update
 681  692   * ever_recalled - has this particular delegation ever been recalled?
 682  693   * dont_grant - file deletion is impending, don't grant a delegation
 683  694   * conflicted_client - clientid of the client that caused a CB_RECALL
 684  695   *      to occur. This is used for delegation policy (should a delegation
 685  696   *      be granted shortly after it has been returned?)
 686  697   */
 687  698  typedef struct rfs4_dinfo {
 688  699          open_delegation_type4 rd_dtype;
 689  700          time_t          rd_time_returned;
 690  701          time_t          rd_time_recalled;
 691  702          time_t          rd_time_lastgrant;
 692  703          time_t          rd_time_lastwrite;
 693  704          time_t          rd_time_rm_delayed;
 694  705          uint32_t        rd_rdgrants;
 695  706          uint32_t        rd_wrgrants;
 696  707          int32_t         rd_recall_count;
 697  708          kmutex_t        rd_recall_lock[1];
 698  709          kcondvar_t      rd_recall_cv[1];
 699  710          bool_t          rd_ever_recalled;
 700  711          uint32_t        rd_hold_grant;
 701  712          clientid4       rd_conflicted_client;
 702  713  } rfs4_dinfo_t;
 703  714  
 704  715  /*
 705  716   * File
 706  717   *
 707  718   * dbe - encapsulation struct
 708  719   * vp - vnode for the file that is open or has a delegation
 709  720   * filehandle - the filehandle generated by the server for this file
 710  721   * delegstatelist - root of delegation list for this file
 711  722   * dinfo - see struct definition above
 712  723   * share_deny - union of all deny modes on file
 713  724   * share_access - union of all access modes on file
 714  725   * access_read - count of read access
 715  726   * access_write - count of write access
 716  727   * deny_read - count of deny reads
 717  728   * deny_write - count of deny writes
 718  729   * file_rwlock - lock for serializing the removal of a file while
 719  730   *      the state structures are active within the server
 720  731   *
 721  732   *      The only requirement for locking file_rwlock is that the
 722  733   *      caller have a reference to the containing rfs4_file.  The dbe
 723  734   *      lock may or may not be held for lock/unlock of file_rwlock.
 724  735   *      As mentioned above, the file_rwlock is used for serialization
 725  736   *      of file removal and more specifically reference to the held
 726  737   *      vnode (e.g. vp).
 727  738   */
 728  739  typedef struct rfs4_file {
 729  740          rfs4_dbe_t      *rf_dbe;
 730  741          vnode_t         *rf_vp;
 731  742          nfs_fh4         rf_filehandle;
 732  743          list_t          rf_delegstatelist;
  
    | 
      ↓ open down ↓ | 
    345 lines elided | 
    
      ↑ open up ↑ | 
  
 733  744          rfs4_dinfo_t    rf_dinfo;
 734  745          uint32_t        rf_share_deny;
 735  746          uint32_t        rf_share_access;
 736  747          uint32_t        rf_access_read;
 737  748          uint32_t        rf_access_write;
 738  749          uint32_t        rf_deny_read;
 739  750          uint32_t        rf_deny_write;
 740  751          krwlock_t       rf_file_rwlock;
 741  752  } rfs4_file_t;
 742  753  
 743      -extern int      rfs4_seen_first_compound;       /* set first time we see one */
 744      -
 745      -extern rfs4_servinst_t  *rfs4_cur_servinst;     /* current server instance */
 746      -extern kmutex_t         rfs4_servinst_lock;     /* protects linked list */
 747      -extern void             rfs4_servinst_create(int, int, char **);
 748      -extern void             rfs4_servinst_destroy_all(void);
 749      -extern void             rfs4_servinst_assign(rfs4_client_t *,
 750      -                            rfs4_servinst_t *);
 751      -extern rfs4_servinst_t  *rfs4_servinst(rfs4_client_t *);
 752      -extern int              rfs4_clnt_in_grace(rfs4_client_t *);
 753      -extern int              rfs4_servinst_in_grace(rfs4_servinst_t *);
 754      -extern int              rfs4_servinst_grace_new(rfs4_servinst_t *);
 755      -extern void             rfs4_grace_start(rfs4_servinst_t *);
 756      -extern void             rfs4_grace_start_new(void);
 757      -extern void             rfs4_grace_reset_all(void);
 758      -extern void             rfs4_ss_oldstate(rfs4_oldstate_t *, char *, char *);
 759      -extern void             rfs4_dss_readstate(int, char **);
 760      -
 761  754  /*
 762      - * rfs4_deleg_policy is used to signify the server's global delegation
      755 + * nfs4_deleg_policy is used to signify the server's global delegation
 763  756   * policy.  The default is to NEVER delegate files and the
 764  757   * administrator must configure the server to enable delegations.
 765  758   *
 766  759   * The disable/enable delegation functions are used to eliminate a
 767  760   * race with exclusive creates.
 768  761   */
 769  762  typedef enum {
 770  763          SRV_NEVER_DELEGATE = 0,
 771  764          SRV_NORMAL_DELEGATE = 1
 772  765  } srv_deleg_policy_t;
 773  766  
 774      -extern srv_deleg_policy_t rfs4_deleg_policy;
 775      -extern kmutex_t rfs4_deleg_lock;
 776  767  extern void rfs4_disable_delegation(void), rfs4_enable_delegation(void);
 777  768  
 778  769  /*
 779  770   * Request types for delegation. These correspond with
 780  771   * open_delegation_type4 with the addition of a new value, DELEG_ANY,
 781  772   * to reqequest any delegation.
 782  773   */
 783  774  typedef enum {
 784  775          DELEG_NONE = 0,         /* Corresponds to OPEN_DELEG_NONE */
 785  776          DELEG_READ = 1,         /* Corresponds to OPEN_DELEG_READ */
 786  777          DELEG_WRITE = 2,        /* Corresponds to OPEN_DELEG_WRITE */
 787  778          DELEG_ANY = -1          /* New value to request any delegation type */
 788  779  } delegreq_t;
 789  780  
 790  781  #define NFS4_DELEG4TYPE2REQTYPE(x) (delegreq_t)(x)
 791  782  
 792  783  /*
      784 + * Zone global variables of NFSv4 server
      785 + */
      786 +typedef struct nfs4_srv {
      787 +        /* Unique write verifier */
      788 +        verifier4       write4verf;
      789 +        /* Delegation lock */
      790 +        kmutex_t        deleg_lock;
      791 +        /* Used to serialize create/destroy of nfs4_server_state database */
      792 +        kmutex_t        state_lock;
      793 +        rfs4_database_t *nfs4_server_state;
      794 +        /* Used to manage access to server instance linked list */
      795 +        kmutex_t        servinst_lock;
      796 +        rfs4_servinst_t *nfs4_cur_servinst;
      797 +        /* Used to manage access to nfs4_deleg_policy */
      798 +        krwlock_t       deleg_policy_lock;
      799 +        srv_deleg_policy_t nfs4_deleg_policy;
      800 +        /* Set first time we see one */
      801 +        int             seen_first_compound;
      802 +        /*
      803 +         * Circular double-linked list of paths for currently-served RGs.
      804 +         * No locking required -- only changed on warmstart.
      805 +         * Managed with insque/remque.
      806 +         */
      807 +        rfs4_dss_path_t *dss_pathlist;
      808 +        /* Duplicate request cache */
      809 +        rfs4_drc_t      *nfs4_drc;
      810 +        /* nfsv4 server start time */
      811 +        time_t rfs4_start_time;
      812 +        /* Used to serialize lookups of clientids */
      813 +        krwlock_t rfs4_findclient_lock;
      814 +
      815 +        /* NFSv4 server state client tables */
      816 +        /* table expiry times */
      817 +        time_t rfs4_client_cache_time;
      818 +        time_t rfs4_openowner_cache_time;
      819 +        time_t rfs4_state_cache_time;
      820 +        time_t rfs4_lo_state_cache_time;
      821 +        time_t rfs4_lockowner_cache_time;
      822 +        time_t rfs4_file_cache_time;
      823 +        time_t rfs4_deleg_state_cache_time;
      824 +        time_t rfs4_clntip_cache_time;
      825 +        /* tables and indexes */
      826 +        /* client table */
      827 +        rfs4_table_t *rfs4_client_tab;
      828 +        rfs4_index_t *rfs4_clientid_idx;
      829 +        rfs4_index_t *rfs4_nfsclnt_idx;
      830 +        /* client IP table */
      831 +        rfs4_table_t *rfs4_clntip_tab;
      832 +        rfs4_index_t *rfs4_clntip_idx;
      833 +        /* Open Owner table */
      834 +        rfs4_table_t *rfs4_openowner_tab;
      835 +        rfs4_index_t *rfs4_openowner_idx;
      836 +        /* Open State ID table */
      837 +        rfs4_table_t *rfs4_state_tab;
      838 +        rfs4_index_t *rfs4_state_idx;
      839 +        rfs4_index_t *rfs4_state_owner_file_idx;
      840 +        rfs4_index_t *rfs4_state_file_idx;
      841 +        /* Lock State ID table */
      842 +        rfs4_table_t *rfs4_lo_state_tab;
      843 +        rfs4_index_t *rfs4_lo_state_idx;
      844 +        rfs4_index_t *rfs4_lo_state_owner_idx;
      845 +        /* Lock owner table */
      846 +        rfs4_table_t *rfs4_lockowner_tab;
      847 +        rfs4_index_t *rfs4_lockowner_idx;
      848 +        rfs4_index_t *rfs4_lockowner_pid_idx;
      849 +        /* File table */
      850 +        rfs4_table_t *rfs4_file_tab;
      851 +        rfs4_index_t *rfs4_file_idx;
      852 +        /* Deleg State table */
      853 +        rfs4_table_t *rfs4_deleg_state_tab;
      854 +        rfs4_index_t *rfs4_deleg_idx;
      855 +        rfs4_index_t *rfs4_deleg_state_idx;
      856 +
      857 +        /* client stable storage */
      858 +        int rfs4_ss_enabled;
      859 +} nfs4_srv_t;
      860 +
      861 +/*
      862 + * max length of the NFSv4 server database name
      863 + */
      864 +#define RFS4_MAX_MEM_CACHE_NAME 48
      865 +
      866 +/*
      867 + * global NFSv4 server kmem caches
      868 + * r_db_name - The name of the state database and the table that will use it
      869 + *             These tables are defined in nfs4_srv_t
      870 + * r_db_mem_cache - The kmem cache associated with the state database name
      871 + */
      872 +typedef struct rfs4_db_mem_cache {
      873 +        char            r_db_name[RFS4_MAX_MEM_CACHE_NAME];
      874 +        kmem_cache_t    *r_db_mem_cache;
      875 +} rfs4_db_mem_cache_t;
      876 +
      877 +#define RFS4_DB_MEM_CACHE_NUM 8
      878 +
      879 +rfs4_db_mem_cache_t rfs4_db_mem_cache_table[RFS4_DB_MEM_CACHE_NUM];
      880 +
      881 +
      882 +extern srv_deleg_policy_t nfs4_get_deleg_policy();
      883 +
      884 +extern void             rfs4_servinst_create(nfs4_srv_t *, int, int, char **);
      885 +extern void             rfs4_servinst_destroy_all(nfs4_srv_t *);
      886 +extern void             rfs4_servinst_assign(nfs4_srv_t *, rfs4_client_t *,
      887 +                            rfs4_servinst_t *);
      888 +extern rfs4_servinst_t  *rfs4_servinst(rfs4_client_t *);
      889 +extern int              rfs4_clnt_in_grace(rfs4_client_t *);
      890 +extern int              rfs4_servinst_in_grace(rfs4_servinst_t *);
      891 +extern int              rfs4_servinst_grace_new(rfs4_servinst_t *);
      892 +extern void             rfs4_grace_start(rfs4_servinst_t *);
      893 +extern void             rfs4_grace_start_new(nfs4_srv_t *);
      894 +extern void             rfs4_grace_reset_all(nfs4_srv_t *);
      895 +extern void             rfs4_ss_oldstate(rfs4_oldstate_t *, char *, char *);
      896 +extern void             rfs4_dss_readstate(nfs4_srv_t *, int, char **);
      897 +
      898 +/*
 793  899   * Various interfaces to manipulate the state structures introduced
 794  900   * above
 795  901   */
 796      -extern  kmutex_t        rfs4_state_lock;
 797  902  extern  void            rfs4_clean_state_exi(struct exportinfo *exi);
 798  903  extern  void            rfs4_free_reply(nfs_resop4 *);
 799  904  extern  void            rfs4_copy_reply(nfs_resop4 *, nfs_resop4 *);
 800  905  
 801  906  /* rfs4_client_t handling */
 802  907  extern  rfs4_client_t   *rfs4_findclient(nfs_client_id4 *,
 803  908                                          bool_t *, rfs4_client_t *);
 804  909  extern  rfs4_client_t   *rfs4_findclient_by_id(clientid4, bool_t);
 805  910  extern  rfs4_client_t   *rfs4_findclient_by_addr(struct sockaddr *);
 806  911  extern  void            rfs4_client_rele(rfs4_client_t *);
 807  912  extern  void            rfs4_client_close(rfs4_client_t *);
 808  913  extern  void            rfs4_client_state_remove(rfs4_client_t *);
 809  914  extern  void            rfs4_client_scv_next(rfs4_client_t *);
 810  915  extern  void            rfs4_update_lease(rfs4_client_t *);
 811  916  extern  bool_t          rfs4_lease_expired(rfs4_client_t *);
 812  917  extern  nfsstat4        rfs4_check_clientid(clientid4 *, int);
 813  918  
 814  919  /* rfs4_clntip_t handling */
 815  920  extern  rfs4_clntip_t   *rfs4_find_clntip(struct sockaddr *, bool_t *);
 816  921  extern  void            rfs4_invalidate_clntip(struct sockaddr *);
 817  922  
 818  923  /* rfs4_openowner_t handling */
 819  924  extern  rfs4_openowner_t *rfs4_findopenowner(open_owner4 *, bool_t *, seqid4);
 820  925  extern  void            rfs4_update_open_sequence(rfs4_openowner_t *);
 821  926  extern  void            rfs4_update_open_resp(rfs4_openowner_t *,
 822  927                                          nfs_resop4 *, nfs_fh4 *);
 823  928  extern  void            rfs4_openowner_rele(rfs4_openowner_t *);
 824  929  extern  void            rfs4_free_opens(rfs4_openowner_t *, bool_t, bool_t);
 825  930  
 826  931  /* rfs4_lockowner_t handling */
 827  932  extern  rfs4_lockowner_t *rfs4_findlockowner(lock_owner4 *, bool_t *);
 828  933  extern  rfs4_lockowner_t *rfs4_findlockowner_by_pid(pid_t);
 829  934  extern  void            rfs4_lockowner_rele(rfs4_lockowner_t *);
 830  935  
 831  936  /* rfs4_state_t handling */
 832  937  extern  rfs4_state_t    *rfs4_findstate_by_owner_file(rfs4_openowner_t *,
 833  938                                          rfs4_file_t *, bool_t *);
 834  939  extern  void            rfs4_state_rele(rfs4_state_t *);
 835  940  extern  void            rfs4_state_close(rfs4_state_t *, bool_t,
 836  941                                          bool_t, cred_t *);
 837  942  extern  void            rfs4_release_share_lock_state(rfs4_state_t *,
 838  943                                          cred_t *, bool_t);
 839  944  extern  void            rfs4_close_all_state(rfs4_file_t *);
 840  945  
 841  946  /* rfs4_lo_state_t handling */
 842  947  extern  rfs4_lo_state_t *rfs4_findlo_state_by_owner(rfs4_lockowner_t *,
 843  948                                                  rfs4_state_t *, bool_t *);
 844  949  extern  void            rfs4_lo_state_rele(rfs4_lo_state_t *, bool_t);
 845  950  extern  void            rfs4_update_lock_sequence(rfs4_lo_state_t *);
 846  951  extern  void            rfs4_update_lock_resp(rfs4_lo_state_t *,
 847  952                                          nfs_resop4 *);
 848  953  
 849  954  /* rfs4_file_t handling */
 850  955  extern  rfs4_file_t     *rfs4_findfile(vnode_t *, nfs_fh4 *, bool_t *);
 851  956  extern  rfs4_file_t     *rfs4_findfile_withlock(vnode_t *, nfs_fh4 *,
 852  957                                                  bool_t *);
 853  958  extern  void            rfs4_file_rele(rfs4_file_t *);
 854  959  
 855  960  /* General collection of "get state" functions */
 856  961  extern  nfsstat4        rfs4_get_state(stateid4 *, rfs4_state_t **,
 857  962                                          rfs4_dbsearch_type_t);
 858  963  extern  nfsstat4        rfs4_get_deleg_state(stateid4 *,
 859  964                                          rfs4_deleg_state_t **);
 860  965  extern  nfsstat4        rfs4_get_lo_state(stateid4 *, rfs4_lo_state_t **,
 861  966                                          bool_t);
 862  967  extern  nfsstat4        rfs4_check_stateid(int, vnode_t *, stateid4 *,
 863  968                                          bool_t, bool_t *, bool_t,
 864  969                                          caller_context_t *);
 865  970  extern  int             rfs4_check_stateid_seqid(rfs4_state_t *, stateid4 *);
 866  971  extern  int             rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *,
 867  972                                          stateid4 *);
 868  973  
 869  974  /* return values for rfs4_check_stateid_seqid() */
 870  975  #define NFS4_CHECK_STATEID_OKAY 1
 871  976  #define NFS4_CHECK_STATEID_OLD  2
 872  977  #define NFS4_CHECK_STATEID_BAD  3
 873  978  #define NFS4_CHECK_STATEID_EXPIRED      4
 874  979  #define NFS4_CHECK_STATEID_REPLAY       5
 875  980  #define NFS4_CHECK_STATEID_CLOSED       6
 876  981  #define NFS4_CHECK_STATEID_UNCONFIRMED  7
 877  982  
 878  983  /* delay() time that server is willing to briefly wait for a delegreturn */
 879  984  #define NFS4_DELEGATION_CONFLICT_DELAY  (hz/10)
 880  985  
 881  986  /*
 882  987   * Interfaces for handling of callback's client handle cache and
 883  988   * callback interfaces themselves.
 884  989   */
 885  990  extern  void            rfs4_cbinfo_free(rfs4_cbinfo_t *);
 886  991  extern  void            rfs4_client_setcb(rfs4_client_t *, cb_client4 *,
 887  992                                          uint32_t);
 888  993  extern  void            rfs4_deleg_cb_check(rfs4_client_t *);
 889  994  extern  nfsstat4        rfs4_vop_getattr(vnode_t *, vattr_t *, int, cred_t *);
 890  995  
 891  996  /* rfs4_deleg_state_t handling and other delegation interfaces */
 892  997  extern  rfs4_deleg_state_t *rfs4_finddeleg(rfs4_state_t *, bool_t *);
 893  998  extern  rfs4_deleg_state_t *rfs4_finddelegstate(stateid_t *);
 894  999  extern  bool_t          rfs4_check_recall(rfs4_state_t *, uint32_t);
 895 1000  extern  void            rfs4_recall_deleg(rfs4_file_t *,
 896 1001                                  bool_t, rfs4_client_t *);
 897 1002  extern  int             rfs4_get_deleg(rfs4_state_t *,  open_delegation_type4,
 898 1003                          open_delegation_type4 (*policy)(rfs4_state_t *,
 899 1004                                  open_delegation_type4 dtype));
 900 1005  extern  rfs4_deleg_state_t *rfs4_grant_delegation(delegreq_t, rfs4_state_t *,
 901 1006                                  int *);
 902 1007  extern  void            rfs4_set_deleg_response(rfs4_deleg_state_t *,
 903 1008                                  open_delegation4 *, nfsace4 *, int);
 904 1009  extern  void            rfs4_return_deleg(rfs4_deleg_state_t *, bool_t);
 905 1010  extern  bool_t          rfs4_is_deleg(rfs4_state_t *);
 906 1011  extern  void            rfs4_deleg_state_rele(rfs4_deleg_state_t *);
 907 1012  extern  bool_t          rfs4_check_delegated_byfp(int, rfs4_file_t *,
 908 1013                                          bool_t, bool_t, bool_t, clientid4 *);
 909 1014  extern  void            rfs4_clear_dont_grant(rfs4_file_t *);
 910 1015  
 911 1016  /*
 912 1017   * nfs4 monitored operations.
 913 1018   */
 914 1019  extern int deleg_rd_open(femarg_t *, int, cred_t *, caller_context_t *);
 915 1020  extern int deleg_wr_open(femarg_t *, int, cred_t *, caller_context_t *);
 916 1021  extern int deleg_wr_read(femarg_t *, uio_t *, int, cred_t *,
 917 1022              caller_context_t *);
 918 1023  extern int deleg_rd_write(femarg_t *, uio_t *, int, cred_t *,
 919 1024              caller_context_t *);
 920 1025  extern int deleg_wr_write(femarg_t *, uio_t *, int, cred_t *,
 921 1026              caller_context_t *);
 922 1027  extern int deleg_rd_setattr(femarg_t *, vattr_t *, int, cred_t *,
 923 1028                  caller_context_t *);
 924 1029  extern int deleg_wr_setattr(femarg_t *, vattr_t *, int, cred_t *,
 925 1030                  caller_context_t *);
 926 1031  extern int deleg_rd_rwlock(femarg_t *, int, caller_context_t *);
 927 1032  extern int deleg_wr_rwlock(femarg_t *, int, caller_context_t *);
 928 1033  extern int deleg_rd_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *,
 929 1034                  caller_context_t *);
 930 1035  extern int deleg_wr_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *,
 931 1036                  caller_context_t *);
 932 1037  extern int deleg_rd_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *,
 933 1038                  caller_context_t *);
 934 1039  extern int deleg_wr_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *,
 935 1040                  caller_context_t *);
 936 1041  extern int deleg_rd_vnevent(femarg_t *, vnevent_t, vnode_t *, char *,
 937 1042                  caller_context_t *);
 938 1043  extern int deleg_wr_vnevent(femarg_t *, vnevent_t, vnode_t *, char *,
  
    | 
      ↓ open down ↓ | 
    132 lines elided | 
    
      ↑ open up ↑ | 
  
 939 1044                  caller_context_t *);
 940 1045  
 941 1046  extern void rfs4_mon_hold(void *);
 942 1047  extern void rfs4_mon_rele(void *);
 943 1048  
 944 1049  extern fem_t    *deleg_rdops;
 945 1050  extern fem_t    *deleg_wrops;
 946 1051  
 947 1052  extern int rfs4_share(rfs4_state_t *, uint32_t, uint32_t);
 948 1053  extern int rfs4_unshare(rfs4_state_t *);
 949      -extern  void            rfs4_set_deleg_policy(srv_deleg_policy_t);
     1054 +extern void rfs4_set_deleg_policy(nfs4_srv_t *, srv_deleg_policy_t);
     1055 +extern void rfs4_hold_deleg_policy(nfs4_srv_t *);
     1056 +extern void rfs4_rele_deleg_policy(nfs4_srv_t *);
     1057 +
 950 1058  #ifdef DEBUG
 951 1059  #define NFS4_DEBUG(var, args) if (var) cmn_err args
 952 1060  
 953 1061  extern int rfs4_debug;
 954 1062  extern int nfs4_client_attr_debug;
 955 1063  extern int nfs4_client_state_debug;
 956 1064  extern int nfs4_client_shadow_debug;
 957 1065  extern int nfs4_client_lock_debug;
 958 1066  extern int nfs4_client_lease_debug;
 959 1067  extern int nfs4_seqid_sync;
 960 1068  extern int nfs4_client_map_debug;
 961 1069  extern int nfs4_client_inactive_debug;
 962 1070  extern int nfs4_client_recov_debug;
 963 1071  extern int nfs4_client_failover_debug;
 964 1072  extern int nfs4_client_call_debug;
 965 1073  extern int nfs4_client_foo_debug;
 966 1074  extern int nfs4_client_zone_debug;
 967 1075  extern int nfs4_lost_rqst_debug;
 968 1076  extern int nfs4_open_stream_debug;
 969 1077  extern int nfs4_client_open_dg;
 970 1078  extern int nfs4_srvmnt_debug;
 971 1079  extern int nfs4_utf8_debug;
 972 1080  
 973 1081  void rfs4_dbe_debug(rfs4_dbe_t *e);
 974 1082  
 975 1083  #ifdef NFS4_DEBUG_MUTEX
 976 1084  void nfs4_debug_mutex_enter(kmutex_t *, char *, int);
 977 1085  void nfs4_debug_mutex_exit(kmutex_t *, char *, int);
 978 1086  
 979 1087  #define mutex_enter(m) nfs4_debug_mutex_enter((m), __FILE__, __LINE__)
 980 1088  #define mutex_exit(m) nfs4_debug_mutex_exit((m), __FILE__, __LINE__)
 981 1089  #endif /* NFS4_DEBUG_MUTEX */
 982 1090  
 983 1091  #else  /* ! DEBUG */
 984 1092  #define NFS4_DEBUG(var, args)
 985 1093  #endif /* DEBUG */
 986 1094  
 987 1095  /*
 988 1096   * XXX - temporary for testing of volatile fh
 989 1097   */
 990 1098  
 991 1099  #ifdef VOLATILE_FH_TEST
 992 1100  
 993 1101  struct nfs_fh4_fmt {
 994 1102          fhandle4_t      fh4_i;
 995 1103          uint32_t        fh4_flag;
 996 1104          uint32_t        fh4_volatile_id;
 997 1105  };
 998 1106  
 999 1107  #else /* VOLATILE_FH_TEST */
1000 1108  
1001 1109  struct nfs_fh4_fmt {
1002 1110          fhandle4_t      fh4_i;
1003 1111          uint32_t        fh4_flag;
1004 1112  };
1005 1113  
1006 1114  #endif /* VOLATILE_FH_TEST */
1007 1115  
1008 1116  #define FH4_NAMEDATTR   1
1009 1117  #define FH4_ATTRDIR     2
1010 1118  
1011 1119  #define fh4_fsid        fh4_i.fhx_fsid
1012 1120  #define fh4_len         fh4_i.fhx_len   /* fid length */
1013 1121  #define fh4_data        fh4_i.fhx_data  /* fid bytes */
1014 1122  #define fh4_xlen        fh4_i.fhx_xlen
1015 1123  #define fh4_xdata       fh4_i.fhx_xdata
1016 1124  typedef struct nfs_fh4_fmt nfs_fh4_fmt_t;
1017 1125  
1018 1126  #define fh4_to_fmt4(fh4p) ((nfs_fh4_fmt_t *)(fh4p)->nfs_fh4_val)
1019 1127  #define get_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) & (flag))
1020 1128  #define set_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) |= (flag))
1021 1129  #define clr_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) &= ~(flag))
1022 1130  
1023 1131  #define NFS_FH4_LEN     sizeof (nfs_fh4_fmt_t)
1024 1132  
1025 1133  /*
1026 1134   * Copy fields from external (fhandle_t) to in-memory (nfs_fh4_fmt_t)
1027 1135   * format to support export info checking.  It does not copy over
1028 1136   * the complete filehandle, just the fsid, xlen and xdata.  It may
1029 1137   * need to be changed to be used in other places.
1030 1138   *
1031 1139   * NOTE: The macro expects the space to be  pre-allocated for
1032 1140   * the contents of nfs_fh4_fmt_t.
1033 1141   */
1034 1142  #define FH_TO_FMT4(exifh, nfs_fmt) {                            \
1035 1143          bzero((nfs_fmt), NFS_FH4_LEN);                          \
1036 1144          (nfs_fmt)->fh4_fsid = (exifh)->fh_fsid;                 \
1037 1145          (nfs_fmt)->fh4_xlen = (exifh)->fh_xlen;                 \
1038 1146          bcopy((exifh)->fh_xdata, (nfs_fmt)->fh4_xdata,          \
1039 1147              (exifh)->fh_xlen);                                  \
1040 1148  }
1041 1149  
1042 1150  /*
1043 1151   * A few definitions of repeatedly used constructs for nfsv4
1044 1152   */
1045 1153  #define UTF8STRING_FREE(str)                                    \
1046 1154          kmem_free((str).utf8string_val, (str).utf8string_len);  \
1047 1155          (str).utf8string_val = NULL;                            \
1048 1156          (str).utf8string_len = 0;
1049 1157  
1050 1158  /*
1051 1159   * NFS4_VOLATILE_FH yields non-zero if the filesystem uses non-persistent
1052 1160   * filehandles.
1053 1161   */
1054 1162  #define NFS4_VOLATILE_FH(mi)                                    \
1055 1163          ((mi)->mi_fh_expire_type &                              \
1056 1164          (FH4_VOLATILE_ANY | FH4_VOL_MIGRATION | FH4_VOL_RENAME))
1057 1165  
1058 1166  /*
1059 1167   * NFS_IS_DOTNAME checks if the name given represents a dot or dotdot entry
1060 1168   */
1061 1169  #define NFS_IS_DOTNAME(name)                                    \
1062 1170          (((name)[0] == '.') &&                                  \
1063 1171          (((name)[1] == '\0') || (((name)[1] == '.') && ((name)[2] == '\0'))))
1064 1172  
1065 1173  /*
1066 1174   * Define the number of bits in a bitmap word (uint32)
1067 1175   */
1068 1176  #define NFS4_BITMAP4_BITSPERWORD        (sizeof (uint32_t) * 8)
1069 1177  
1070 1178  /*
1071 1179   * Define the value for the access field of the compound_state structure
1072 1180   * based on the result of nfsauth access checking.
1073 1181   */
1074 1182  #define CS_ACCESS_OK            0x1
1075 1183  #define CS_ACCESS_DENIED        0x2
1076 1184  #define CS_ACCESS_LIMITED       0x4
1077 1185  
1078 1186  /*
1079 1187   * compound state in nfsv4 server
1080 1188   */
1081 1189  struct compound_state {
1082 1190          struct exportinfo *exi;
1083 1191          struct exportinfo *saved_exi;   /* export struct for saved_vp */
1084 1192          cred_t          *basecr;        /* UNIX cred:  only RPC request */
1085 1193          caddr_t         principal;
1086 1194          int             nfsflavor;
1087 1195          cred_t          *cr;            /* UNIX cred: RPC request and */
1088 1196                                          /* target export */
1089 1197          bool_t          cont;
1090 1198          uint_t          access;         /* access perm on vp per request */
1091 1199          bool_t          deleg;          /* TRUE if current fh has */
1092 1200                                          /* write delegated */
1093 1201          vnode_t         *vp;            /* modified by PUTFH, and by ops that */
1094 1202                                          /* input to GETFH */
1095 1203          bool_t          mandlock;       /* Is mandatory locking in effect */
1096 1204                                          /* for vp */
1097 1205          vnode_t         *saved_vp;      /* modified by SAVEFH, copied to */
1098 1206                                          /* vp by RESTOREFH */
1099 1207          nfsstat4        *statusp;
1100 1208          nfs_fh4         fh;             /* ditto. valid only if vp != NULL */
1101 1209          nfs_fh4         saved_fh;       /* ditto. valid only if */
1102 1210                                          /*      saved_vp != NULL */
1103 1211          struct svc_req  *req;
1104 1212          char            fhbuf[NFS4_FHSIZE];
1105 1213  };
1106 1214  
1107 1215  /*
1108 1216   * Conversion commands for nfsv4 server attr checking
1109 1217   */
1110 1218  enum nfs4_attr_cmd {
1111 1219          NFS4ATTR_SUPPORTED = 0,         /* check which attrs supported */
1112 1220          NFS4ATTR_GETIT = 1,             /* getattr - sys to fattr4 (r) */
1113 1221          NFS4ATTR_SETIT = 2,             /* setattr - fattr4 to sys (w) */
1114 1222          NFS4ATTR_VERIT = 3,             /* verify - fattr4 to sys (r) */
1115 1223          NFS4ATTR_FREEIT = 4             /* free any alloc'd space for attr */
1116 1224  };
1117 1225  
1118 1226  typedef enum nfs4_attr_cmd nfs4_attr_cmd_t;
1119 1227  
1120 1228  struct nfs4_svgetit_arg {
1121 1229          nfs4_attr_cmd_t op;             /* getit or setit */
1122 1230          struct compound_state *cs;
1123 1231          struct statvfs64 *sbp;
1124 1232          uint_t          flag;           /* VOP_GETATTR/VOP_SETATTR flag */
1125 1233          uint_t          xattr;          /* object is xattr */
1126 1234          bool_t          rdattr_error_req; /* if readdir & client wants */
1127 1235                                                  /* rdattr_error */
1128 1236          nfsstat4        rdattr_error;   /* used for per-entry status */
1129 1237                                          /* (if rdattr_err) */
1130 1238          bool_t          is_referral;    /* because sometimes we tell lies */
1131 1239          bool_t          mntdfid_set;
1132 1240          fattr4_mounted_on_fileid
1133 1241                          mounted_on_fileid;
1134 1242                                          /* readdir op can always return */
1135 1243                                          /* d_ino from server fs dirent  */
1136 1244                                          /* for mounted_on_fileid attr.  */
1137 1245                                          /* This field holds d_ino so    */
1138 1246                                          /* srv attr conv code can avoid */
1139 1247                                          /* doing an untraverse.         */
1140 1248          vattr_t         vap[1];
1141 1249  };
1142 1250  
1143 1251  struct nfs4_ntov_map {
1144 1252          bitmap4         fbit;           /* FATTR4_XXX_MASKY */
1145 1253          uint_t          vbit;           /* AT_XXX */
1146 1254          bool_t          vfsstat;
1147 1255          bool_t          mandatory;      /* attribute mandatory to implement? */
1148 1256          uint_t          nval;
1149 1257          int             xdr_size;       /* Size of XDR'd attr */
1150 1258          xdrproc_t       xfunc;
1151 1259          int (*sv_getit)(nfs4_attr_cmd_t, struct nfs4_svgetit_arg *,
1152 1260                  union nfs4_attr_u *);   /* subroutine for getting attr. */
1153 1261          char            *prtstr;        /* string attr for printing */
1154 1262  };
1155 1263  
1156 1264  struct nfs4attr_to_vattr {
1157 1265          vnode_t         *vp;
1158 1266          vattr_t         *vap;
1159 1267          nfs_fh4         *fhp;
1160 1268          nfsstat4        rdattr_error;
1161 1269          uint32_t        flag;
1162 1270          fattr4_change   change;
1163 1271          fattr4_fsid     srv_fsid;
1164 1272          fattr4_mounted_on_fileid        mntd_fid;
1165 1273  };
1166 1274  
1167 1275  typedef struct nfs4attr_to_vattr ntov4_t;
1168 1276  
1169 1277  /*
1170 1278   * nfs4attr_to_vattr flags
1171 1279   */
1172 1280  #define NTOV_FHP_VALID                  0x01
1173 1281  #define NTOV_RDATTR_ERROR_VALID         0x02
1174 1282  #define NTOV_CHANGE_VALID               0x04
1175 1283  #define NTOV_SUPP_VALID                 0x08
1176 1284  #define NTOV_SRV_FSID_VALID             0x10
1177 1285  #define NTOV_MOUNTED_ON_FILEID_VALID    0x20
1178 1286  
1179 1287  
1180 1288  #define FATTR4_MANDATTR_MASK (          \
1181 1289          FATTR4_SUPPORTED_ATTRS_MASK |   \
1182 1290          FATTR4_TYPE_MASK |              \
1183 1291          FATTR4_FH_EXPIRE_TYPE_MASK |    \
1184 1292          FATTR4_CHANGE_MASK |            \
1185 1293          FATTR4_SIZE_MASK |              \
1186 1294          FATTR4_LINK_SUPPORT_MASK |      \
1187 1295          FATTR4_SYMLINK_SUPPORT_MASK |   \
1188 1296          FATTR4_NAMED_ATTR_MASK |        \
1189 1297          FATTR4_FSID_MASK |              \
1190 1298          FATTR4_UNIQUE_HANDLES_MASK |    \
1191 1299          FATTR4_LEASE_TIME_MASK |        \
1192 1300          FATTR4_RDATTR_ERROR_MASK |      \
1193 1301          FATTR4_FILEHANDLE_MASK)
1194 1302  
1195 1303  
1196 1304  struct nfs4attr_to_osattr {
1197 1305          void *attrconv_arg;
1198 1306          uint_t mask;
1199 1307  };
1200 1308  
1201 1309  struct mntinfo4;
1202 1310  
1203 1311  /*
1204 1312   * lkp4_attr_setup lists the different options for attributes when calling
1205 1313   * nfs4lookup_setup - either no attributes (just lookups - e.g., secinfo),
1206 1314   * one component only (normal component lookup), get attributes for the
1207 1315   * last component (e.g., mount), attributes for each component (e.g.,
1208 1316   * failovers later), just the filehandle for the last component (e.g.,
1209 1317   * volatile filehandle recovery), or stuff that needs OPENATTR (e.g.
1210 1318   * looking up a named attribute or it's hidden directory).
1211 1319   */
1212 1320  enum lkp4_attr_setup {
1213 1321          LKP4_NO_ATTRIBUTES = 0,         /* no attrs or filehandles */
1214 1322          LKP4_ALL_ATTRIBUTES = 3,        /* multi-comp: attrs for all comps */
1215 1323          LKP4_LAST_NAMED_ATTR = 5,       /* multi-comp: named attr & attrdir */
1216 1324          LKP4_LAST_ATTRDIR = 6,          /* multi-comp: just attrdir */
1217 1325          LKP4_ALL_ATTR_SECINFO = 7       /* multi-comp: attrs for all comp and */
1218 1326                                          /*      secinfo for last comp */
1219 1327  };
1220 1328  
1221 1329  /*
1222 1330   * lookup4_param a set of parameters to nfs4lookup_setup -
1223 1331   * used to setup a path lookup compound request.
1224 1332   */
1225 1333  typedef struct lookup4_param {
1226 1334          enum lkp4_attr_setup l4_getattrs; /* (in) get attrs in the lookup? */
1227 1335          int             header_len;     /* (in) num ops before first lookup  */
1228 1336          int             trailer_len;    /* (in) num ops after last      */
1229 1337                                          /*      Lookup/Getattr          */
1230 1338          bitmap4         ga_bits;        /* (in) Which attributes for Getattr */
1231 1339          COMPOUND4args_clnt *argsp;      /* (in/out) args for compound struct */
1232 1340          COMPOUND4res_clnt  *resp;       /* (in/out) res for compound  struct */
1233 1341          int             arglen;         /* (out) argop buffer alloc'd length */
1234 1342          struct mntinfo4 *mi;
1235 1343  } lookup4_param_t;
1236 1344  
1237 1345  
1238 1346  #define NFS4_FATTR4_FINISH      -1      /* fattr4 index indicating finish */
1239 1347  
1240 1348  typedef int (*nfs4attr_to_os_t)(int, union nfs4_attr_u *,
1241 1349                  struct nfs4attr_to_osattr *);
1242 1350  
1243 1351  /*
1244 1352   * The nfs4_error_t is the basic structure to return error values
1245 1353   * from rfs4call.  It encapsulates the unix errno
1246 1354   * value, the nfsstat4 value and the rpc status value into a single
1247 1355   * structure.
1248 1356   *
1249 1357   * If error is set, then stat is ignored and rpc_status may be
1250 1358   * set if the error occurred as the result of a CLNT_CALL.  If
1251 1359   * stat is set, then rpc request succeeded, error and
1252 1360   * rpc_status are set to 0 and stat contains the result of
1253 1361   * operation, NFS4_OK or one of the NFS4ERR_* values.
1254 1362   *
1255 1363   * Functions which want to generate errors independently from
1256 1364   * rfs4call should set error to the desired errno value and
1257 1365   * set stat and rpc_status to 0.  nfs4_error_init() is a
1258 1366   * convenient function to do this.
1259 1367   */
1260 1368  typedef struct {
1261 1369          int             error;
1262 1370          nfsstat4        stat;
1263 1371          enum clnt_stat  rpc_status;
1264 1372  } nfs4_error_t;
1265 1373  
1266 1374  /*
1267 1375   * Shared functions
1268 1376   */
1269 1377  extern void     rfs4_op_readdir(nfs_argop4 *, nfs_resop4 *,
1270 1378                          struct svc_req *, struct compound_state *);
1271 1379  extern void     nfs_fh4_copy(nfs_fh4 *, nfs_fh4 *);
1272 1380  
1273 1381  extern void     nfs4_fattr4_free(fattr4 *);
1274 1382  
1275 1383  extern int      nfs4lookup_setup(char *, lookup4_param_t *, int);
1276 1384  extern void     nfs4_getattr_otw_norecovery(vnode_t *,
1277 1385                          nfs4_ga_res_t *, nfs4_error_t *, cred_t *, int);
1278 1386  extern int      nfs4_getattr_otw(vnode_t *, nfs4_ga_res_t *, cred_t *, int);
1279 1387  extern int      nfs4cmpfh(const nfs_fh4 *, const nfs_fh4 *);
1280 1388  extern int      nfs4cmpfhandle(nfs4_fhandle_t *, nfs4_fhandle_t *);
1281 1389  extern int      nfs4getattr(vnode_t *, struct vattr *, cred_t *);
1282 1390  extern int      nfs4_waitfor_purge_complete(vnode_t *);
1283 1391  extern int      nfs4_validate_caches(vnode_t *, cred_t *);
1284 1392  extern int      nfs4init(int, char *);
1285 1393  extern void     nfs4fini(void);
1286 1394  extern int      nfs4_vfsinit(void);
1287 1395  extern void     nfs4_vfsfini(void);
1288 1396  
1289 1397  extern void     nfs4_vnops_init(void);
1290 1398  extern void     nfs4_vnops_fini(void);
1291 1399  extern void     nfs_idmap_init(void);
1292 1400  extern void     nfs_idmap_flush(int);
1293 1401  extern void     nfs_idmap_fini(void);
1294 1402  extern int      nfs4_rnode_init(void);
1295 1403  extern int      nfs4_rnode_fini(void);
1296 1404  extern int      nfs4_shadow_init(void);
1297 1405  extern int      nfs4_shadow_fini(void);
1298 1406  extern int      nfs4_acache_init(void);
1299 1407  extern int      nfs4_acache_fini(void);
1300 1408  extern int      nfs4_subr_init(void);
1301 1409  extern int      nfs4_subr_fini(void);
1302 1410  extern void     nfs4_acl_init(void);
1303 1411  extern void     nfs4_acl_free_cache(vsecattr_t *);
1304 1412  
1305 1413  extern int      geterrno4(nfsstat4);
1306 1414  extern nfsstat4 puterrno4(int);
1307 1415  extern int      nfs4_need_to_bump_seqid(COMPOUND4res_clnt *);
1308 1416  extern int      nfs4tsize(void);
1309 1417  extern int      checkauth4(struct compound_state *, struct svc_req *);
1310 1418  extern nfsstat4 call_checkauth4(struct compound_state *, struct svc_req *);
1311 1419  extern int      is_exported_sec(int, struct exportinfo *);
1312 1420  extern void     nfs4_vmask_to_nmask(uint_t, bitmap4 *);
1313 1421  extern void     nfs4_vmask_to_nmask_set(uint_t, bitmap4 *);
1314 1422  extern int      nfs_idmap_str_uid(utf8string *u8s, uid_t *, bool_t);
1315 1423  extern int      nfs_idmap_str_gid(utf8string *u8s, gid_t *, bool_t);
1316 1424  extern int      nfs_idmap_uid_str(uid_t, utf8string *u8s, bool_t);
1317 1425  extern int      nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t);
1318 1426  extern int      nfs4_time_ntov(nfstime4 *, timestruc_t *);
1319 1427  extern int      nfs4_time_vton(timestruc_t *, nfstime4 *);
1320 1428  extern char     *utf8_to_str(utf8string *, uint_t *, char *);
1321 1429  extern char     *utf8_to_fn(utf8string *, uint_t *, char *);
1322 1430  extern utf8string *str_to_utf8(char *, utf8string *);
1323 1431  extern utf8string *utf8_copy(utf8string *, utf8string *);
1324 1432  extern int      utf8_compare(const utf8string *, const utf8string *);
1325 1433  extern nfsstat4 utf8_dir_verify(utf8string *);
1326 1434  extern char     *utf8_strchr(utf8string *, const char);
1327 1435  extern int      ln_ace4_cmp(nfsace4 *, nfsace4 *, int);
1328 1436  extern int      vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int);
1329 1437  extern int      vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
1330 1438      int, int);
1331 1439  extern int      vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
1332 1440      int);
1333 1441  extern int      vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int);
1334 1442  extern void     vs_acet_destroy(vsecattr_t *);
1335 1443  extern void     vs_ace4_destroy(vsecattr_t *);
1336 1444  extern void     vs_aent_destroy(vsecattr_t *);
1337 1445  
1338 1446  extern int      vn_find_nfs_record(vnode_t *, nvlist_t **, char **, char **);
1339 1447  extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
1340 1448  extern fs_locations4 *fetch_referral(vnode_t *, cred_t *);
  
    | 
      ↓ open down ↓ | 
    381 lines elided | 
    
      ↑ open up ↑ | 
  
1341 1449  extern char     *build_symlink(vnode_t *, cred_t *, size_t *);
1342 1450  
1343 1451  extern int      stateid4_cmp(stateid4 *, stateid4 *);
1344 1452  
1345 1453  extern vtype_t  nf4_to_vt[];
1346 1454  
1347 1455  extern struct nfs4_ntov_map nfs4_ntov_map[];
1348 1456  extern uint_t nfs4_ntov_map_size;
1349 1457  
1350 1458  extern kstat_named_t    *rfsproccnt_v4_ptr;
     1459 +extern kstat_t          **rfsprocio_v4_ptr;
1351 1460  extern struct vfsops    *nfs4_vfsops;
1352 1461  extern struct vnodeops  *nfs4_vnodeops;
1353 1462  extern const struct     fs_operation_def nfs4_vnodeops_template[];
1354 1463  extern vnodeops_t       *nfs4_trigger_vnodeops;
1355 1464  extern const struct     fs_operation_def nfs4_trigger_vnodeops_template[];
1356 1465  
1357 1466  extern uint_t nfs4_tsize(struct knetconfig *);
1358 1467  extern uint_t rfs4_tsize(struct svc_req *);
1359 1468  
1360 1469  extern bool_t   xdr_inline_decode_nfs_fh4(uint32_t *, nfs_fh4_fmt_t *,
1361 1470                          uint32_t);
1362 1471  extern bool_t   xdr_inline_encode_nfs_fh4(uint32_t **, uint32_t *,
1363 1472                          nfs_fh4_fmt_t *);
1364 1473  
1365 1474  #ifdef DEBUG
1366 1475  extern int              rfs4_do_pre_op_attr;
1367 1476  extern int              rfs4_do_post_op_attr;
1368 1477  #endif
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
1369 1478  
1370 1479  extern stateid4 clnt_special0;
1371 1480  extern stateid4 clnt_special1;
1372 1481  #define CLNT_ISSPECIAL(id) (stateid4_cmp(id, &clnt_special0) || \
1373 1482                                  stateid4_cmp(id, &clnt_special1))
1374 1483  
1375 1484  /*
1376 1485   * The NFS Version 4 service procedures.
1377 1486   */
1378 1487  
     1488 +extern void     rfs4_do_server_start(int, int, int);
1379 1489  extern void     rfs4_compound(COMPOUND4args *, COMPOUND4res *,
1380 1490                          struct exportinfo *, struct svc_req *, cred_t *, int *);
1381 1491  extern void     rfs4_compound_free(COMPOUND4res *);
1382 1492  extern void     rfs4_compound_flagproc(COMPOUND4args *, int *);
     1493 +extern void     rfs4_compound_kstat_args(COMPOUND4args *);
     1494 +extern void     rfs4_compound_kstat_res(COMPOUND4res *);
1383 1495  
1384      -extern int      rfs4_srvrinit(void);
     1496 +extern void     rfs4_srvrinit(void);
1385 1497  extern void     rfs4_srvrfini(void);
1386      -extern void     rfs4_state_init(void);
1387      -extern void     rfs4_state_fini(void);
     1498 +extern void     rfs4_state_g_init(void);
     1499 +extern void     rfs4_state_zone_init(nfs4_srv_t *);
     1500 +extern void     rfs4_state_g_fini(void);
     1501 +extern void     rfs4_state_zone_fini(void);
1388 1502  
1389 1503  #endif
1390 1504  #ifdef  __cplusplus
1391 1505  }
1392 1506  #endif
1393 1507  
1394 1508  #endif /* _NFS4_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX