Print this page
    
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/nfs/nfs4_state.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_state.c
   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
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
  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   23   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
       26 +/*
       27 + * Copyright 2018 Nexenta Systems, Inc.
       28 + * Copyright 2019 Nexenta by DDN, Inc.
       29 + */
       30 +
  26   31  #include <sys/systm.h>
  27   32  #include <sys/kmem.h>
  28   33  #include <sys/cmn_err.h>
  29   34  #include <sys/atomic.h>
  30   35  #include <sys/clconf.h>
  31   36  #include <sys/cladm.h>
  32   37  #include <sys/flock.h>
  33   38  #include <nfs/export.h>
  34   39  #include <nfs/nfs.h>
  35   40  #include <nfs/nfs4.h>
  36   41  #include <nfs/nfssys.h>
  37   42  #include <nfs/lm.h>
  38   43  #include <sys/pathname.h>
  39   44  #include <sys/sdt.h>
  40   45  #include <sys/nvpair.h>
  41   46  
  42   47  extern u_longlong_t nfs4_srv_caller_id;
  43   48  
  44      -extern time_t rfs4_start_time;
  45   49  extern uint_t nfs4_srv_vkey;
  46   50  
  47   51  stateid4 special0 = {
  48   52          0,
  49   53          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  50   54  };
  51   55  
  52   56  stateid4 special1 = {
  53   57          0xffffffff,
  54   58          {
  55   59                  (char)0xff, (char)0xff, (char)0xff, (char)0xff,
  56   60                  (char)0xff, (char)0xff, (char)0xff, (char)0xff,
  57   61                  (char)0xff, (char)0xff, (char)0xff, (char)0xff
  58   62          }
  59   63  };
  60   64  
  61   65  
  62   66  #define ISSPECIAL(id)  (stateid4_cmp(id, &special0) || \
  63   67                          stateid4_cmp(id, &special1))
  64   68  
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
  65   69  /* For embedding the cluster nodeid into our clientid */
  66   70  #define CLUSTER_NODEID_SHIFT    24
  67   71  #define CLUSTER_MAX_NODEID      255
  68   72  
  69   73  #ifdef DEBUG
  70   74  int rfs4_debug;
  71   75  #endif
  72   76  
  73   77  static uint32_t rfs4_database_debug = 0x00;
  74   78  
  75      -static void rfs4_ss_clid_write(rfs4_client_t *cp, char *leaf);
       79 +/* CSTYLED */
       80 +static void rfs4_ss_clid_write(nfs4_srv_t *nsrv4, rfs4_client_t *cp, char *leaf);
  76   81  static void rfs4_ss_clid_write_one(rfs4_client_t *cp, char *dir, char *leaf);
  77   82  static void rfs4_dss_clear_oldstate(rfs4_servinst_t *sip);
  78   83  static void rfs4_ss_chkclid_sip(rfs4_client_t *cp, rfs4_servinst_t *sip);
  79   84  
  80   85  /*
  81   86   * Couple of simple init/destroy functions for a general waiter
  82   87   */
  83   88  void
  84   89  rfs4_sw_init(rfs4_state_wait_t *swp)
  85   90  {
  86   91          mutex_init(swp->sw_cv_lock, NULL, MUTEX_DEFAULT, NULL);
  87   92          cv_init(swp->sw_cv, NULL, CV_DEFAULT, NULL);
  88   93          swp->sw_active = FALSE;
  89   94          swp->sw_wait_count = 0;
  90   95  }
  91   96  
  92   97  void
  93   98  rfs4_sw_destroy(rfs4_state_wait_t *swp)
  94   99  {
  95  100          mutex_destroy(swp->sw_cv_lock);
  96  101          cv_destroy(swp->sw_cv);
  97  102  }
  98  103  
  99  104  void
 100  105  rfs4_sw_enter(rfs4_state_wait_t *swp)
 101  106  {
 102  107          mutex_enter(swp->sw_cv_lock);
 103  108          while (swp->sw_active) {
 104  109                  swp->sw_wait_count++;
 105  110                  cv_wait(swp->sw_cv, swp->sw_cv_lock);
 106  111                  swp->sw_wait_count--;
 107  112          }
 108  113          ASSERT(swp->sw_active == FALSE);
 109  114          swp->sw_active = TRUE;
 110  115          mutex_exit(swp->sw_cv_lock);
 111  116  }
 112  117  
 113  118  void
  
    | 
      ↓ open down ↓ | 
    28 lines elided | 
    
      ↑ open up ↑ | 
  
 114  119  rfs4_sw_exit(rfs4_state_wait_t *swp)
 115  120  {
 116  121          mutex_enter(swp->sw_cv_lock);
 117  122          ASSERT(swp->sw_active == TRUE);
 118  123          swp->sw_active = FALSE;
 119  124          if (swp->sw_wait_count != 0)
 120  125                  cv_broadcast(swp->sw_cv);
 121  126          mutex_exit(swp->sw_cv_lock);
 122  127  }
 123  128  
 124      -/*
 125      - * CPR callback id -- not related to v4 callbacks
 126      - */
 127      -static callb_id_t cpr_id = 0;
 128      -
 129  129  static void
 130  130  deep_lock_copy(LOCK4res *dres, LOCK4res *sres)
 131  131  {
 132  132          lock_owner4 *slo = &sres->LOCK4res_u.denied.owner;
 133  133          lock_owner4 *dlo = &dres->LOCK4res_u.denied.owner;
 134  134  
 135  135          if (sres->status == NFS4ERR_DENIED) {
 136  136                  dlo->owner_val = kmem_alloc(slo->owner_len, KM_SLEEP);
 137  137                  bcopy(slo->owner_val, dlo->owner_val, slo->owner_len);
 138  138          }
 139  139  }
 140  140  
      141 +/*
      142 + * CPR callback id -- not related to v4 callbacks
      143 + */
      144 +static callb_id_t cpr_id = 0;
      145 +
 141  146  static void
 142  147  deep_lock_free(LOCK4res *res)
 143  148  {
 144  149          lock_owner4 *lo = &res->LOCK4res_u.denied.owner;
 145  150  
 146  151          if (res->status == NFS4ERR_DENIED)
 147  152                  kmem_free(lo->owner_val, lo->owner_len);
 148  153  }
 149  154  
 150  155  static void
 151  156  deep_open_copy(OPEN4res *dres, OPEN4res *sres)
 152  157  {
 153  158          nfsace4 *sacep, *dacep;
 154  159  
 155  160          if (sres->status != NFS4_OK) {
 156  161                  return;
 157  162          }
 158  163  
 159  164          dres->attrset = sres->attrset;
 160  165  
 161  166          switch (sres->delegation.delegation_type) {
 162  167          case OPEN_DELEGATE_NONE:
 163  168                  return;
 164  169          case OPEN_DELEGATE_READ:
 165  170                  sacep = &sres->delegation.open_delegation4_u.read.permissions;
 166  171                  dacep = &dres->delegation.open_delegation4_u.read.permissions;
 167  172                  break;
 168  173          case OPEN_DELEGATE_WRITE:
 169  174                  sacep = &sres->delegation.open_delegation4_u.write.permissions;
 170  175                  dacep = &dres->delegation.open_delegation4_u.write.permissions;
 171  176                  break;
 172  177          }
 173  178          dacep->who.utf8string_val =
 174  179              kmem_alloc(sacep->who.utf8string_len, KM_SLEEP);
 175  180          bcopy(sacep->who.utf8string_val, dacep->who.utf8string_val,
 176  181              sacep->who.utf8string_len);
 177  182  }
 178  183  
 179  184  static void
 180  185  deep_open_free(OPEN4res *res)
 181  186  {
 182  187          nfsace4 *acep;
 183  188          if (res->status != NFS4_OK)
 184  189                  return;
 185  190  
 186  191          switch (res->delegation.delegation_type) {
 187  192          case OPEN_DELEGATE_NONE:
 188  193                  return;
 189  194          case OPEN_DELEGATE_READ:
 190  195                  acep = &res->delegation.open_delegation4_u.read.permissions;
 191  196                  break;
 192  197          case OPEN_DELEGATE_WRITE:
 193  198                  acep = &res->delegation.open_delegation4_u.write.permissions;
 194  199                  break;
 195  200          }
 196  201  
 197  202          if (acep->who.utf8string_val) {
 198  203                  kmem_free(acep->who.utf8string_val, acep->who.utf8string_len);
 199  204                  acep->who.utf8string_val = NULL;
 200  205          }
 201  206  }
 202  207  
 203  208  void
 204  209  rfs4_free_reply(nfs_resop4 *rp)
 205  210  {
 206  211          switch (rp->resop) {
 207  212          case OP_LOCK:
 208  213                  deep_lock_free(&rp->nfs_resop4_u.oplock);
 209  214                  break;
 210  215          case OP_OPEN:
 211  216                  deep_open_free(&rp->nfs_resop4_u.opopen);
 212  217          default:
 213  218                  break;
 214  219          }
 215  220  }
 216  221  
 217  222  void
 218  223  rfs4_copy_reply(nfs_resop4 *dst, nfs_resop4 *src)
 219  224  {
 220  225          *dst = *src;
 221  226  
 222  227          /* Handle responses that need deep copy */
 223  228          switch (src->resop) {
 224  229          case OP_LOCK:
 225  230                  deep_lock_copy(&dst->nfs_resop4_u.oplock,
 226  231                      &src->nfs_resop4_u.oplock);
 227  232                  break;
 228  233          case OP_OPEN:
 229  234                  deep_open_copy(&dst->nfs_resop4_u.opopen,
 230  235                      &src->nfs_resop4_u.opopen);
 231  236                  break;
 232  237          default:
 233  238                  break;
 234  239          };
 235  240  }
 236  241  
 237  242  /*
 238  243   * This is the implementation of the underlying state engine. The
 239  244   * public interface to this engine is described by
 240  245   * nfs4_state.h. Callers to the engine should hold no state engine
 241  246   * locks when they call in to it. If the protocol needs to lock data
 242  247   * structures it should do so after acquiring all references to them
 243  248   * first and then follow the following lock order:
 244  249   *
 245  250   *      client > openowner > state > lo_state > lockowner > file.
 246  251   *
 247  252   * Internally we only allow a thread to hold one hash bucket lock at a
 248  253   * time and the lock is higher in the lock order (must be acquired
 249  254   * first) than the data structure that is on that hash list.
 250  255   *
 251  256   * If a new reference was acquired by the caller, that reference needs
 252  257   * to be released after releasing all acquired locks with the
 253  258   * corresponding rfs4_*_rele routine.
 254  259   */
 255  260  
 256  261  /*
 257  262   * This code is some what prototypical for now. Its purpose currently is to
 258  263   * implement the interfaces sufficiently to finish the higher protocol
 259  264   * elements. This will be replaced by a dynamically resizeable tables
 260  265   * backed by kmem_cache allocator. However synchronization is handled
 261  266   * correctly (I hope) and will not change by much.  The mutexes for
 262  267   * the hash buckets that can be used to create new instances of data
 263  268   * structures  might be good candidates to evolve into reader writer
 264  269   * locks. If it has to do a creation, it would be holding the
 265  270   * mutex across a kmem_alloc with KM_SLEEP specified.
  
    | 
      ↓ open down ↓ | 
    115 lines elided | 
    
      ↑ open up ↑ | 
  
 266  271   */
 267  272  
 268  273  #ifdef DEBUG
 269  274  #define TABSIZE 17
 270  275  #else
 271  276  #define TABSIZE 2047
 272  277  #endif
 273  278  
 274  279  #define ADDRHASH(key) ((unsigned long)(key) >> 3)
 275  280  
 276      -/* Used to serialize create/destroy of rfs4_server_state database */
 277      -kmutex_t        rfs4_state_lock;
 278      -static rfs4_database_t *rfs4_server_state = NULL;
 279      -
 280      -/* Used to serialize lookups of clientids */
 281      -static  krwlock_t       rfs4_findclient_lock;
 282      -
 283      -/*
 284      - * For now this "table" is exposed so that the CPR callback
 285      - * function can tromp through it..
 286      - */
 287      -rfs4_table_t *rfs4_client_tab;
 288      -
 289      -static rfs4_index_t *rfs4_clientid_idx;
 290      -static rfs4_index_t *rfs4_nfsclnt_idx;
 291      -static rfs4_table_t *rfs4_clntip_tab;
 292      -static rfs4_index_t *rfs4_clntip_idx;
 293      -static rfs4_table_t *rfs4_openowner_tab;
 294      -static rfs4_index_t *rfs4_openowner_idx;
 295      -static rfs4_table_t *rfs4_state_tab;
 296      -static rfs4_index_t *rfs4_state_idx;
 297      -static rfs4_index_t *rfs4_state_owner_file_idx;
 298      -static rfs4_index_t *rfs4_state_file_idx;
 299      -static rfs4_table_t *rfs4_lo_state_tab;
 300      -static rfs4_index_t *rfs4_lo_state_idx;
 301      -static rfs4_index_t *rfs4_lo_state_owner_idx;
 302      -static rfs4_table_t *rfs4_lockowner_tab;
 303      -static rfs4_index_t *rfs4_lockowner_idx;
 304      -static rfs4_index_t *rfs4_lockowner_pid_idx;
 305      -static rfs4_table_t *rfs4_file_tab;
 306      -static rfs4_index_t *rfs4_file_idx;
 307      -static rfs4_table_t *rfs4_deleg_state_tab;
 308      -static rfs4_index_t *rfs4_deleg_idx;
 309      -static rfs4_index_t *rfs4_deleg_state_idx;
 310      -
 311  281  #define MAXTABSZ 1024*1024
 312  282  
 313  283  /* The values below are rfs4_lease_time units */
 314  284  
 315  285  #ifdef DEBUG
 316  286  #define CLIENT_CACHE_TIME 1
 317  287  #define OPENOWNER_CACHE_TIME 1
 318  288  #define STATE_CACHE_TIME 1
 319  289  #define LO_STATE_CACHE_TIME 1
 320  290  #define LOCKOWNER_CACHE_TIME 1
 321  291  #define FILE_CACHE_TIME 3
 322  292  #define DELEG_STATE_CACHE_TIME 1
  
    | 
      ↓ open down ↓ | 
    2 lines elided | 
    
      ↑ open up ↑ | 
  
 323  293  #else
 324  294  #define CLIENT_CACHE_TIME 10
 325  295  #define OPENOWNER_CACHE_TIME 5
 326  296  #define STATE_CACHE_TIME 1
 327  297  #define LO_STATE_CACHE_TIME 1
 328  298  #define LOCKOWNER_CACHE_TIME 3
 329  299  #define FILE_CACHE_TIME 40
 330  300  #define DELEG_STATE_CACHE_TIME 1
 331  301  #endif
 332  302  
      303 +/*
      304 + * NFSv4 server state databases
      305 + *
      306 + * Initilized when the module is loaded and used by NFSv4 state tables.
      307 + * These kmem_cache databases are global, the tables that make use of these
      308 + * are per zone.
      309 + */
      310 +kmem_cache_t *rfs4_client_mem_cache;
      311 +kmem_cache_t *rfs4_clntIP_mem_cache;
      312 +kmem_cache_t *rfs4_openown_mem_cache;
      313 +kmem_cache_t *rfs4_openstID_mem_cache;
      314 +kmem_cache_t *rfs4_lockstID_mem_cache;
      315 +kmem_cache_t *rfs4_lockown_mem_cache;
      316 +kmem_cache_t *rfs4_file_mem_cache;
      317 +kmem_cache_t *rfs4_delegstID_mem_cache;
 333  318  
 334      -static time_t rfs4_client_cache_time = 0;
 335      -static time_t rfs4_clntip_cache_time = 0;
 336      -static time_t rfs4_openowner_cache_time = 0;
 337      -static time_t rfs4_state_cache_time = 0;
 338      -static time_t rfs4_lo_state_cache_time = 0;
 339      -static time_t rfs4_lockowner_cache_time = 0;
 340      -static time_t rfs4_file_cache_time = 0;
 341      -static time_t rfs4_deleg_state_cache_time = 0;
 342      -
      319 +/*
      320 + * NFSv4 state table functions
      321 + */
 343  322  static bool_t rfs4_client_create(rfs4_entry_t, void *);
 344  323  static void rfs4_dss_remove_cpleaf(rfs4_client_t *);
 345  324  static void rfs4_dss_remove_leaf(rfs4_servinst_t *, char *, char *);
 346  325  static void rfs4_client_destroy(rfs4_entry_t);
 347  326  static bool_t rfs4_client_expiry(rfs4_entry_t);
 348  327  static uint32_t clientid_hash(void *);
 349  328  static bool_t clientid_compare(rfs4_entry_t, void *);
 350  329  static void *clientid_mkkey(rfs4_entry_t);
 351  330  static uint32_t nfsclnt_hash(void *);
 352  331  static bool_t nfsclnt_compare(rfs4_entry_t, void *);
 353  332  static void *nfsclnt_mkkey(rfs4_entry_t);
 354  333  static bool_t rfs4_clntip_expiry(rfs4_entry_t);
 355  334  static void rfs4_clntip_destroy(rfs4_entry_t);
 356  335  static bool_t rfs4_clntip_create(rfs4_entry_t, void *);
 357  336  static uint32_t clntip_hash(void *);
 358  337  static bool_t clntip_compare(rfs4_entry_t, void *);
 359  338  static void *clntip_mkkey(rfs4_entry_t);
 360  339  static bool_t rfs4_openowner_create(rfs4_entry_t, void *);
 361  340  static void rfs4_openowner_destroy(rfs4_entry_t);
 362  341  static bool_t rfs4_openowner_expiry(rfs4_entry_t);
 363  342  static uint32_t openowner_hash(void *);
 364  343  static bool_t openowner_compare(rfs4_entry_t, void *);
 365  344  static void *openowner_mkkey(rfs4_entry_t);
 366  345  static bool_t rfs4_state_create(rfs4_entry_t, void *);
 367  346  static void rfs4_state_destroy(rfs4_entry_t);
 368  347  static bool_t rfs4_state_expiry(rfs4_entry_t);
 369  348  static uint32_t state_hash(void *);
 370  349  static bool_t state_compare(rfs4_entry_t, void *);
 371  350  static void *state_mkkey(rfs4_entry_t);
 372  351  static uint32_t state_owner_file_hash(void *);
 373  352  static bool_t state_owner_file_compare(rfs4_entry_t, void *);
 374  353  static void *state_owner_file_mkkey(rfs4_entry_t);
 375  354  static uint32_t state_file_hash(void *);
 376  355  static bool_t state_file_compare(rfs4_entry_t, void *);
 377  356  static void *state_file_mkkey(rfs4_entry_t);
 378  357  static bool_t rfs4_lo_state_create(rfs4_entry_t, void *);
 379  358  static void rfs4_lo_state_destroy(rfs4_entry_t);
 380  359  static bool_t rfs4_lo_state_expiry(rfs4_entry_t);
 381  360  static uint32_t lo_state_hash(void *);
 382  361  static bool_t lo_state_compare(rfs4_entry_t, void *);
 383  362  static void *lo_state_mkkey(rfs4_entry_t);
 384  363  static uint32_t lo_state_lo_hash(void *);
 385  364  static bool_t lo_state_lo_compare(rfs4_entry_t, void *);
 386  365  static void *lo_state_lo_mkkey(rfs4_entry_t);
 387  366  static bool_t rfs4_lockowner_create(rfs4_entry_t, void *);
 388  367  static void rfs4_lockowner_destroy(rfs4_entry_t);
 389  368  static bool_t rfs4_lockowner_expiry(rfs4_entry_t);
 390  369  static uint32_t lockowner_hash(void *);
 391  370  static bool_t lockowner_compare(rfs4_entry_t, void *);
 392  371  static void *lockowner_mkkey(rfs4_entry_t);
 393  372  static uint32_t pid_hash(void *);
 394  373  static bool_t pid_compare(rfs4_entry_t, void *);
 395  374  static void *pid_mkkey(rfs4_entry_t);
 396  375  static bool_t rfs4_file_create(rfs4_entry_t, void *);
 397  376  static void rfs4_file_destroy(rfs4_entry_t);
 398  377  static uint32_t file_hash(void *);
 399  378  static bool_t file_compare(rfs4_entry_t, void *);
 400  379  static void *file_mkkey(rfs4_entry_t);
 401  380  static bool_t rfs4_deleg_state_create(rfs4_entry_t, void *);
 402  381  static void rfs4_deleg_state_destroy(rfs4_entry_t);
 403  382  static bool_t rfs4_deleg_state_expiry(rfs4_entry_t);
 404  383  static uint32_t deleg_hash(void *);
 405  384  static bool_t deleg_compare(rfs4_entry_t, void *);
 406  385  static void *deleg_mkkey(rfs4_entry_t);
 407  386  static uint32_t deleg_state_hash(void *);
 408  387  static bool_t deleg_state_compare(rfs4_entry_t, void *);
 409  388  static void *deleg_state_mkkey(rfs4_entry_t);
 410  389  
 411  390  static void rfs4_state_rele_nounlock(rfs4_state_t *);
 412  391  
 413  392  static int rfs4_ss_enabled = 0;
 414  393  
 415  394  extern void (*rfs4_client_clrst)(struct nfs4clrst_args *);
 416  395  
  
    | 
      ↓ open down ↓ | 
    64 lines elided | 
    
      ↑ open up ↑ | 
  
 417  396  void
 418  397  rfs4_ss_pnfree(rfs4_ss_pn_t *ss_pn)
 419  398  {
 420  399          kmem_free(ss_pn, sizeof (rfs4_ss_pn_t));
 421  400  }
 422  401  
 423  402  static rfs4_ss_pn_t *
 424  403  rfs4_ss_pnalloc(char *dir, char *leaf)
 425  404  {
 426  405          rfs4_ss_pn_t *ss_pn;
 427      -        int     dir_len, leaf_len;
      406 +        int dir_len, leaf_len;
 428  407  
 429  408          /*
 430  409           * validate we have a resonable path
 431  410           * (account for the '/' and trailing null)
 432  411           */
 433  412          if ((dir_len = strlen(dir)) > MAXPATHLEN ||
 434  413              (leaf_len = strlen(leaf)) > MAXNAMELEN ||
 435  414              (dir_len + leaf_len + 2) > MAXPATHLEN) {
 436  415                  return (NULL);
 437  416          }
 438  417  
 439  418          ss_pn = kmem_alloc(sizeof (rfs4_ss_pn_t), KM_SLEEP);
 440  419  
 441  420          (void) snprintf(ss_pn->pn, MAXPATHLEN, "%s/%s", dir, leaf);
 442  421          /* Handy pointer to just the leaf name */
 443  422          ss_pn->leaf = ss_pn->pn + dir_len + 1;
 444  423          return (ss_pn);
 445  424  }
 446  425  
 447  426  
 448  427  /*
 449  428   * Move the "leaf" filename from "sdir" directory
 450  429   * to the "ddir" directory. Return the pathname of
 451  430   * the destination unless the rename fails in which
 452  431   * case we need to return the source pathname.
 453  432   */
 454  433  static rfs4_ss_pn_t *
 455  434  rfs4_ss_movestate(char *sdir, char *ddir, char *leaf)
 456  435  {
 457  436          rfs4_ss_pn_t *src, *dst;
 458  437  
 459  438          if ((src = rfs4_ss_pnalloc(sdir, leaf)) == NULL)
 460  439                  return (NULL);
 461  440  
 462  441          if ((dst = rfs4_ss_pnalloc(ddir, leaf)) == NULL) {
 463  442                  rfs4_ss_pnfree(src);
 464  443                  return (NULL);
 465  444          }
 466  445  
 467  446          /*
 468  447           * If the rename fails we shall return the src
 469  448           * pathname and free the dst. Otherwise we need
 470  449           * to free the src and return the dst pathanme.
 471  450           */
 472  451          if (vn_rename(src->pn, dst->pn, UIO_SYSSPACE)) {
 473  452                  rfs4_ss_pnfree(dst);
 474  453                  return (src);
 475  454          }
 476  455          rfs4_ss_pnfree(src);
 477  456          return (dst);
 478  457  }
 479  458  
 480  459  
 481  460  static rfs4_oldstate_t *
 482  461  rfs4_ss_getstate(vnode_t *dvp, rfs4_ss_pn_t *ss_pn)
 483  462  {
 484  463          struct uio uio;
 485  464          struct iovec iov[3];
 486  465  
 487  466          rfs4_oldstate_t *cl_ss = NULL;
 488  467          vnode_t *vp;
 489  468          vattr_t va;
 490  469          uint_t id_len;
 491  470          int err, kill_file, file_vers;
 492  471  
 493  472          if (ss_pn == NULL)
 494  473                  return (NULL);
 495  474  
 496  475          /*
 497  476           * open the state file.
 498  477           */
 499  478          if (vn_open(ss_pn->pn, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0) != 0) {
 500  479                  return (NULL);
 501  480          }
 502  481  
 503  482          if (vp->v_type != VREG) {
 504  483                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 505  484                  VN_RELE(vp);
 506  485                  return (NULL);
 507  486          }
 508  487  
 509  488          err = VOP_ACCESS(vp, VREAD, 0, CRED(), NULL);
 510  489          if (err) {
 511  490                  /*
 512  491                   * We don't have read access? better get the heck out.
 513  492                   */
 514  493                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 515  494                  VN_RELE(vp);
 516  495                  return (NULL);
 517  496          }
 518  497  
 519  498          (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
 520  499          /*
 521  500           * get the file size to do some basic validation
 522  501           */
 523  502          va.va_mask = AT_SIZE;
 524  503          err = VOP_GETATTR(vp, &va, 0, CRED(), NULL);
 525  504  
 526  505          kill_file = (va.va_size == 0 || va.va_size <
 527  506              (NFS4_VERIFIER_SIZE + sizeof (uint_t)+1));
 528  507  
 529  508          if (err || kill_file) {
 530  509                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
 531  510                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 532  511                  VN_RELE(vp);
 533  512                  if (kill_file) {
 534  513                          (void) VOP_REMOVE(dvp, ss_pn->leaf, CRED(), NULL, 0);
 535  514                  }
 536  515                  return (NULL);
 537  516          }
 538  517  
 539  518          cl_ss = kmem_alloc(sizeof (rfs4_oldstate_t), KM_SLEEP);
 540  519  
 541  520          /*
 542  521           * build iovecs to read in the file_version, verifier and id_len
 543  522           */
 544  523          iov[0].iov_base = (caddr_t)&file_vers;
 545  524          iov[0].iov_len = sizeof (int);
 546  525          iov[1].iov_base = (caddr_t)&cl_ss->cl_id4.verifier;
 547  526          iov[1].iov_len = NFS4_VERIFIER_SIZE;
 548  527          iov[2].iov_base = (caddr_t)&id_len;
 549  528          iov[2].iov_len = sizeof (uint_t);
 550  529  
 551  530          uio.uio_iov = iov;
 552  531          uio.uio_iovcnt = 3;
 553  532          uio.uio_segflg = UIO_SYSSPACE;
 554  533          uio.uio_loffset = 0;
 555  534          uio.uio_resid = sizeof (int) + NFS4_VERIFIER_SIZE + sizeof (uint_t);
 556  535  
 557  536          if (err = VOP_READ(vp, &uio, FREAD, CRED(), NULL)) {
 558  537                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
 559  538                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 560  539                  VN_RELE(vp);
 561  540                  kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
 562  541                  return (NULL);
 563  542          }
 564  543  
 565  544          /*
 566  545           * if the file_version doesn't match or if the
 567  546           * id_len is zero or the combination of the verifier,
 568  547           * id_len and id_val is bigger than the file we have
 569  548           * a problem. If so ditch the file.
 570  549           */
 571  550          kill_file = (file_vers != NFS4_SS_VERSION || id_len == 0 ||
 572  551              (id_len + NFS4_VERIFIER_SIZE + sizeof (uint_t)) > va.va_size);
 573  552  
 574  553          if (err || kill_file) {
 575  554                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
 576  555                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 577  556                  VN_RELE(vp);
 578  557                  kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
 579  558                  if (kill_file) {
 580  559                          (void) VOP_REMOVE(dvp, ss_pn->leaf, CRED(), NULL, 0);
 581  560                  }
 582  561                  return (NULL);
 583  562          }
 584  563  
 585  564          /*
 586  565           * now get the client id value
 587  566           */
 588  567          cl_ss->cl_id4.id_val = kmem_alloc(id_len, KM_SLEEP);
 589  568          iov[0].iov_base = cl_ss->cl_id4.id_val;
 590  569          iov[0].iov_len = id_len;
 591  570  
 592  571          uio.uio_iov = iov;
 593  572          uio.uio_iovcnt = 1;
 594  573          uio.uio_segflg = UIO_SYSSPACE;
 595  574          uio.uio_resid = cl_ss->cl_id4.id_len = id_len;
 596  575  
 597  576          if (err = VOP_READ(vp, &uio, FREAD, CRED(), NULL)) {
 598  577                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
 599  578                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 600  579                  VN_RELE(vp);
 601  580                  kmem_free(cl_ss->cl_id4.id_val, id_len);
 602  581                  kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
 603  582                  return (NULL);
 604  583          }
 605  584  
 606  585          VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
 607  586          (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
 608  587          VN_RELE(vp);
 609  588          return (cl_ss);
 610  589  }
 611  590  
 612  591  #ifdef  nextdp
 613  592  #undef nextdp
 614  593  #endif
 615  594  #define nextdp(dp)      ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
 616  595  
 617  596  /*
 618  597   * Add entries from statedir to supplied oldstate list.
 619  598   * Optionally, move all entries from statedir -> destdir.
 620  599   */
 621  600  void
 622  601  rfs4_ss_oldstate(rfs4_oldstate_t *oldstate, char *statedir, char *destdir)
 623  602  {
 624  603          rfs4_ss_pn_t *ss_pn;
 625  604          rfs4_oldstate_t *cl_ss = NULL;
 626  605          char    *dirt = NULL;
 627  606          int     err, dir_eof = 0, size = 0;
 628  607          vnode_t *dvp;
 629  608          struct iovec iov;
 630  609          struct uio uio;
 631  610          struct dirent64 *dep;
 632  611          offset_t dirchunk_offset = 0;
 633  612  
 634  613          /*
 635  614           * open the state directory
 636  615           */
 637  616          if (vn_open(statedir, UIO_SYSSPACE, FREAD, 0, &dvp, 0, 0))
 638  617                  return;
 639  618  
 640  619          if (dvp->v_type != VDIR || VOP_ACCESS(dvp, VREAD, 0, CRED(), NULL))
 641  620                  goto out;
 642  621  
 643  622          dirt = kmem_alloc(RFS4_SS_DIRSIZE, KM_SLEEP);
 644  623  
 645  624          /*
 646  625           * Get and process the directory entries
 647  626           */
 648  627          while (!dir_eof) {
 649  628                  (void) VOP_RWLOCK(dvp, V_WRITELOCK_FALSE, NULL);
 650  629                  iov.iov_base = dirt;
 651  630                  iov.iov_len = RFS4_SS_DIRSIZE;
 652  631                  uio.uio_iov = &iov;
 653  632                  uio.uio_iovcnt = 1;
 654  633                  uio.uio_segflg = UIO_SYSSPACE;
 655  634                  uio.uio_loffset = dirchunk_offset;
 656  635                  uio.uio_resid = RFS4_SS_DIRSIZE;
 657  636  
 658  637                  err = VOP_READDIR(dvp, &uio, CRED(), &dir_eof, NULL, 0);
 659  638                  VOP_RWUNLOCK(dvp, V_WRITELOCK_FALSE, NULL);
 660  639                  if (err)
 661  640                          goto out;
 662  641  
 663  642                  size = RFS4_SS_DIRSIZE - uio.uio_resid;
 664  643  
 665  644                  /*
 666  645                   * Process all the directory entries in this
 667  646                   * readdir chunk
 668  647                   */
 669  648                  for (dep = (struct dirent64 *)dirt; size > 0;
 670  649                      dep = nextdp(dep)) {
 671  650  
 672  651                          size -= dep->d_reclen;
 673  652                          dirchunk_offset = dep->d_off;
 674  653  
 675  654                          /*
 676  655                           * Skip '.' and '..'
 677  656                           */
 678  657                          if (NFS_IS_DOTNAME(dep->d_name))
 679  658                                  continue;
 680  659  
 681  660                          ss_pn = rfs4_ss_pnalloc(statedir, dep->d_name);
 682  661                          if (ss_pn == NULL)
 683  662                                  continue;
 684  663  
 685  664                          if (cl_ss = rfs4_ss_getstate(dvp, ss_pn)) {
 686  665                                  if (destdir != NULL) {
 687  666                                          rfs4_ss_pnfree(ss_pn);
 688  667                                          cl_ss->ss_pn = rfs4_ss_movestate(
 689  668                                              statedir, destdir, dep->d_name);
 690  669                                  } else {
 691  670                                          cl_ss->ss_pn = ss_pn;
 692  671                                  }
 693  672                                  insque(cl_ss, oldstate);
 694  673                          } else {
 695  674                                  rfs4_ss_pnfree(ss_pn);
 696  675                          }
 697  676                  }
  
    | 
      ↓ open down ↓ | 
    260 lines elided | 
    
      ↑ open up ↑ | 
  
 698  677          }
 699  678  
 700  679  out:
 701  680          (void) VOP_CLOSE(dvp, FREAD, 1, (offset_t)0, CRED(), NULL);
 702  681          VN_RELE(dvp);
 703  682          if (dirt)
 704  683                  kmem_free((caddr_t)dirt, RFS4_SS_DIRSIZE);
 705  684  }
 706  685  
 707  686  static void
 708      -rfs4_ss_init(void)
      687 +rfs4_ss_init(nfs4_srv_t *nsrv4)
 709  688  {
 710  689          int npaths = 1;
 711  690          char *default_dss_path = NFS4_DSS_VAR_DIR;
 712  691  
 713  692          /* read the default stable storage state */
 714      -        rfs4_dss_readstate(npaths, &default_dss_path);
      693 +        rfs4_dss_readstate(nsrv4, npaths, &default_dss_path);
 715  694  
 716  695          rfs4_ss_enabled = 1;
 717  696  }
 718  697  
 719  698  static void
 720      -rfs4_ss_fini(void)
      699 +rfs4_ss_fini(nfs4_srv_t *nsrv4)
 721  700  {
 722  701          rfs4_servinst_t *sip;
 723  702  
 724      -        mutex_enter(&rfs4_servinst_lock);
 725      -        sip = rfs4_cur_servinst;
      703 +        mutex_enter(&nsrv4->servinst_lock);
      704 +        sip = nsrv4->nfs4_cur_servinst;
 726  705          while (sip != NULL) {
 727  706                  rfs4_dss_clear_oldstate(sip);
 728  707                  sip = sip->next;
 729  708          }
 730      -        mutex_exit(&rfs4_servinst_lock);
      709 +        mutex_exit(&nsrv4->servinst_lock);
 731  710  }
 732  711  
 733  712  /*
 734  713   * Remove all oldstate files referenced by this servinst.
 735  714   */
 736  715  static void
 737  716  rfs4_dss_clear_oldstate(rfs4_servinst_t *sip)
 738  717  {
 739  718          rfs4_oldstate_t *os_head, *osp;
 740  719  
 741  720          rw_enter(&sip->oldstate_lock, RW_WRITER);
 742  721          os_head = sip->oldstate;
 743  722  
 744  723          if (os_head == NULL) {
 745  724                  rw_exit(&sip->oldstate_lock);
 746  725                  return;
 747  726          }
 748  727  
 749  728          /* skip dummy entry */
 750  729          osp = os_head->next;
 751  730          while (osp != os_head) {
 752  731                  char *leaf = osp->ss_pn->leaf;
 753  732                  rfs4_oldstate_t *os_next;
 754  733  
 755  734                  rfs4_dss_remove_leaf(sip, NFS4_DSS_OLDSTATE_LEAF, leaf);
 756  735  
 757  736                  if (osp->cl_id4.id_val)
 758  737                          kmem_free(osp->cl_id4.id_val, osp->cl_id4.id_len);
 759  738                  rfs4_ss_pnfree(osp->ss_pn);
 760  739  
 761  740                  os_next = osp->next;
 762  741                  remque(osp);
 763  742                  kmem_free(osp, sizeof (rfs4_oldstate_t));
  
    | 
      ↓ open down ↓ | 
    23 lines elided | 
    
      ↑ open up ↑ | 
  
 764  743                  osp = os_next;
 765  744          }
 766  745  
 767  746          rw_exit(&sip->oldstate_lock);
 768  747  }
 769  748  
 770  749  /*
 771  750   * Form the state and oldstate paths, and read in the stable storage files.
 772  751   */
 773  752  void
 774      -rfs4_dss_readstate(int npaths, char **paths)
      753 +rfs4_dss_readstate(nfs4_srv_t *nsrv4, int npaths, char **paths)
 775  754  {
 776  755          int i;
 777  756          char *state, *oldstate;
 778  757  
 779  758          state = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 780  759          oldstate = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 781  760  
 782  761          for (i = 0; i < npaths; i++) {
 783  762                  char *path = paths[i];
 784  763  
 785  764                  (void) sprintf(state, "%s/%s", path, NFS4_DSS_STATE_LEAF);
 786  765                  (void) sprintf(oldstate, "%s/%s", path, NFS4_DSS_OLDSTATE_LEAF);
 787  766  
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 788  767                  /*
 789  768                   * Populate the current server instance's oldstate list.
 790  769                   *
 791  770                   * 1. Read stable storage data from old state directory,
 792  771                   *    leaving its contents alone.
 793  772                   *
 794  773                   * 2. Read stable storage data from state directory,
 795  774                   *    and move the latter's contents to old state
 796  775                   *    directory.
 797  776                   */
 798      -                rfs4_ss_oldstate(rfs4_cur_servinst->oldstate, oldstate, NULL);
 799      -                rfs4_ss_oldstate(rfs4_cur_servinst->oldstate, state, oldstate);
      777 +                /* CSTYLED */
      778 +                rfs4_ss_oldstate(nsrv4->nfs4_cur_servinst->oldstate, oldstate, NULL);
      779 +                /* CSTYLED */
      780 +                rfs4_ss_oldstate(nsrv4->nfs4_cur_servinst->oldstate, state, oldstate);
 800  781          }
 801  782  
 802  783          kmem_free(state, MAXPATHLEN);
 803  784          kmem_free(oldstate, MAXPATHLEN);
 804  785  }
 805  786  
 806  787  
 807  788  /*
 808  789   * Check if we are still in grace and if the client can be
 809  790   * granted permission to perform reclaims.
 810  791   */
 811  792  void
 812      -rfs4_ss_chkclid(rfs4_client_t *cp)
      793 +rfs4_ss_chkclid(nfs4_srv_t *nsrv4, rfs4_client_t *cp)
 813  794  {
 814  795          rfs4_servinst_t *sip;
 815  796  
 816  797          /*
 817  798           * It should be sufficient to check the oldstate data for just
 818  799           * this client's instance. However, since our per-instance
 819  800           * client grouping is solely temporal, HA-NFSv4 RG failover
 820  801           * might result in clients of the same RG being partitioned into
 821  802           * separate instances.
 822  803           *
 823  804           * Until the client grouping is improved, we must check the
 824  805           * oldstate data for all instances with an active grace period.
 825  806           *
 826  807           * This also serves as the mechanism to remove stale oldstate data.
 827  808           * The first time we check an instance after its grace period has
 828  809           * expired, the oldstate data should be cleared.
 829  810           *
 830  811           * Start at the current instance, and walk the list backwards
 831  812           * to the first.
 832  813           */
 833      -        mutex_enter(&rfs4_servinst_lock);
 834      -        for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
      814 +        mutex_enter(&nsrv4->servinst_lock);
      815 +        for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
 835  816                  rfs4_ss_chkclid_sip(cp, sip);
 836  817  
 837  818                  /* if the above check found this client, we're done */
 838  819                  if (cp->rc_can_reclaim)
 839  820                          break;
 840  821          }
 841      -        mutex_exit(&rfs4_servinst_lock);
      822 +        mutex_exit(&nsrv4->servinst_lock);
 842  823  }
 843  824  
 844  825  static void
 845  826  rfs4_ss_chkclid_sip(rfs4_client_t *cp, rfs4_servinst_t *sip)
 846  827  {
 847  828          rfs4_oldstate_t *osp, *os_head;
 848  829  
 849  830          /* short circuit everything if this server instance has no oldstate */
 850  831          rw_enter(&sip->oldstate_lock, RW_READER);
 851  832          os_head = sip->oldstate;
 852  833          rw_exit(&sip->oldstate_lock);
 853  834          if (os_head == NULL)
 854  835                  return;
 855  836  
 856  837          /*
 857  838           * If this server instance is no longer in a grace period then
 858  839           * the client won't be able to reclaim. No further need for this
 859  840           * instance's oldstate data, so it can be cleared.
 860  841           */
 861  842          if (!rfs4_servinst_in_grace(sip))
 862  843                  return;
 863  844  
 864  845          /* this instance is still in grace; search for the clientid */
 865  846  
 866  847          rw_enter(&sip->oldstate_lock, RW_READER);
 867  848  
 868  849          os_head = sip->oldstate;
 869  850          /* skip dummy entry */
 870  851          osp = os_head->next;
 871  852          while (osp != os_head) {
 872  853                  if (osp->cl_id4.id_len == cp->rc_nfs_client.id_len) {
 873  854                          if (bcmp(osp->cl_id4.id_val, cp->rc_nfs_client.id_val,
 874  855                              osp->cl_id4.id_len) == 0) {
 875  856                                  cp->rc_can_reclaim = 1;
 876  857                                  break;
 877  858                          }
 878  859                  }
 879  860                  osp = osp->next;
 880  861          }
  
    | 
      ↓ open down ↓ | 
    29 lines elided | 
    
      ↑ open up ↑ | 
  
 881  862  
 882  863          rw_exit(&sip->oldstate_lock);
 883  864  }
 884  865  
 885  866  /*
 886  867   * Place client information into stable storage: 1/3.
 887  868   * First, generate the leaf filename, from the client's IP address and
 888  869   * the server-generated short-hand clientid.
 889  870   */
 890  871  void
 891      -rfs4_ss_clid(rfs4_client_t *cp)
      872 +rfs4_ss_clid(nfs4_srv_t *nsrv4, rfs4_client_t *cp)
 892  873  {
 893  874          const char *kinet_ntop6(uchar_t *, char *, size_t);
 894  875          char leaf[MAXNAMELEN], buf[INET6_ADDRSTRLEN];
 895  876          struct sockaddr *ca;
 896  877          uchar_t *b;
 897  878  
 898  879          if (rfs4_ss_enabled == 0) {
 899  880                  return;
 900  881          }
 901  882  
 902  883          buf[0] = 0;
 903  884  
 904  885          ca = (struct sockaddr *)&cp->rc_addr;
 905  886  
 906  887          /*
 907  888           * Convert the caller's IP address to a dotted string
 908  889           */
 909  890          if (ca->sa_family == AF_INET) {
 910  891                  b = (uchar_t *)&((struct sockaddr_in *)ca)->sin_addr;
 911  892                  (void) sprintf(buf, "%03d.%03d.%03d.%03d", b[0] & 0xFF,
 912  893                      b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
  
    | 
      ↓ open down ↓ | 
    11 lines elided | 
    
      ↑ open up ↑ | 
  
 913  894          } else if (ca->sa_family == AF_INET6) {
 914  895                  struct sockaddr_in6 *sin6;
 915  896  
 916  897                  sin6 = (struct sockaddr_in6 *)ca;
 917  898                  (void) kinet_ntop6((uchar_t *)&sin6->sin6_addr,
 918  899                      buf, INET6_ADDRSTRLEN);
 919  900          }
 920  901  
 921  902          (void) snprintf(leaf, MAXNAMELEN, "%s-%llx", buf,
 922  903              (longlong_t)cp->rc_clientid);
 923      -        rfs4_ss_clid_write(cp, leaf);
      904 +        rfs4_ss_clid_write(nsrv4, cp, leaf);
 924  905  }
 925  906  
 926  907  /*
 927  908   * Place client information into stable storage: 2/3.
 928  909   * DSS: distributed stable storage: the file may need to be written to
 929  910   * multiple directories.
 930  911   */
 931  912  static void
 932      -rfs4_ss_clid_write(rfs4_client_t *cp, char *leaf)
      913 +rfs4_ss_clid_write(nfs4_srv_t *nsrv4, rfs4_client_t *cp, char *leaf)
 933  914  {
 934  915          rfs4_servinst_t *sip;
 935  916  
 936  917          /*
 937  918           * It should be sufficient to write the leaf file to (all) DSS paths
 938  919           * associated with just this client's instance. However, since our
 939  920           * per-instance client grouping is solely temporal, HA-NFSv4 RG
 940  921           * failover might result in us losing DSS data.
 941  922           *
 942  923           * Until the client grouping is improved, we must write the DSS data
 943  924           * to all instances' paths. Start at the current instance, and
 944  925           * walk the list backwards to the first.
 945  926           */
 946      -        mutex_enter(&rfs4_servinst_lock);
 947      -        for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
      927 +        mutex_enter(&nsrv4->servinst_lock);
      928 +        for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
 948  929                  int i, npaths = sip->dss_npaths;
 949  930  
 950  931                  /* write the leaf file to all DSS paths */
 951  932                  for (i = 0; i < npaths; i++) {
 952  933                          rfs4_dss_path_t *dss_path = sip->dss_paths[i];
 953  934  
 954  935                          /* HA-NFSv4 path might have been failed-away from us */
 955  936                          if (dss_path == NULL)
 956  937                                  continue;
 957  938  
 958  939                          rfs4_ss_clid_write_one(cp, dss_path->path, leaf);
 959  940                  }
 960  941          }
 961      -        mutex_exit(&rfs4_servinst_lock);
      942 +        mutex_exit(&nsrv4->servinst_lock);
 962  943  }
 963  944  
 964  945  /*
 965  946   * Place client information into stable storage: 3/3.
 966  947   * Write the stable storage data to the requested file.
 967  948   */
 968  949  static void
 969  950  rfs4_ss_clid_write_one(rfs4_client_t *cp, char *dss_path, char *leaf)
 970  951  {
 971  952          int ioflag;
 972  953          int file_vers = NFS4_SS_VERSION;
 973  954          size_t dirlen;
 974  955          struct uio uio;
 975  956          struct iovec iov[4];
 976  957          char *dir;
 977  958          rfs4_ss_pn_t *ss_pn;
 978  959          vnode_t *vp;
 979  960          nfs_client_id4 *cl_id4 = &(cp->rc_nfs_client);
 980  961  
 981  962          /* allow 2 extra bytes for '/' & NUL */
 982  963          dirlen = strlen(dss_path) + strlen(NFS4_DSS_STATE_LEAF) + 2;
 983  964          dir = kmem_alloc(dirlen, KM_SLEEP);
 984  965          (void) sprintf(dir, "%s/%s", dss_path, NFS4_DSS_STATE_LEAF);
 985  966  
 986  967          ss_pn = rfs4_ss_pnalloc(dir, leaf);
 987  968          /* rfs4_ss_pnalloc takes its own copy */
 988  969          kmem_free(dir, dirlen);
 989  970          if (ss_pn == NULL)
 990  971                  return;
 991  972  
 992  973          if (vn_open(ss_pn->pn, UIO_SYSSPACE, FCREAT|FWRITE, 0600, &vp,
 993  974              CRCREAT, 0)) {
 994  975                  rfs4_ss_pnfree(ss_pn);
 995  976                  return;
 996  977          }
 997  978  
 998  979          /*
 999  980           * We need to record leaf - i.e. the filename - so that we know
1000  981           * what to remove, in the future. However, the dir part of cp->ss_pn
1001  982           * should never be referenced directly, since it's potentially only
1002  983           * one of several paths with this leaf in it.
1003  984           */
1004  985          if (cp->rc_ss_pn != NULL) {
1005  986                  if (strcmp(cp->rc_ss_pn->leaf, leaf) == 0) {
1006  987                          /* we've already recorded *this* leaf */
1007  988                          rfs4_ss_pnfree(ss_pn);
1008  989                  } else {
1009  990                          /* replace with this leaf */
1010  991                          rfs4_ss_pnfree(cp->rc_ss_pn);
1011  992                          cp->rc_ss_pn = ss_pn;
1012  993                  }
1013  994          } else {
1014  995                  cp->rc_ss_pn = ss_pn;
1015  996          }
1016  997  
1017  998          /*
1018  999           * Build a scatter list that points to the nfs_client_id4
1019 1000           */
1020 1001          iov[0].iov_base = (caddr_t)&file_vers;
1021 1002          iov[0].iov_len = sizeof (int);
1022 1003          iov[1].iov_base = (caddr_t)&(cl_id4->verifier);
1023 1004          iov[1].iov_len = NFS4_VERIFIER_SIZE;
1024 1005          iov[2].iov_base = (caddr_t)&(cl_id4->id_len);
1025 1006          iov[2].iov_len = sizeof (uint_t);
1026 1007          iov[3].iov_base = (caddr_t)cl_id4->id_val;
1027 1008          iov[3].iov_len = cl_id4->id_len;
1028 1009  
1029 1010          uio.uio_iov = iov;
1030 1011          uio.uio_iovcnt = 4;
1031 1012          uio.uio_loffset = 0;
1032 1013          uio.uio_segflg = UIO_SYSSPACE;
1033 1014          uio.uio_llimit = (rlim64_t)MAXOFFSET_T;
1034 1015          uio.uio_resid = cl_id4->id_len + sizeof (int) +
1035 1016              NFS4_VERIFIER_SIZE + sizeof (uint_t);
1036 1017  
1037 1018          ioflag = uio.uio_fmode = (FWRITE|FSYNC);
1038 1019          uio.uio_extflg = UIO_COPY_DEFAULT;
1039 1020  
1040 1021          (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
1041 1022          /* write the full client id to the file. */
1042 1023          (void) VOP_WRITE(vp, &uio, ioflag, CRED(), NULL);
1043 1024          VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
1044 1025  
1045 1026          (void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
1046 1027          VN_RELE(vp);
1047 1028  }
1048 1029  
1049 1030  /*
1050 1031   * DSS: distributed stable storage.
1051 1032   * Unpack the list of paths passed by nfsd.
1052 1033   * Use nvlist_alloc(9F) to manage the data.
1053 1034   * The caller is responsible for allocating and freeing the buffer.
1054 1035   */
1055 1036  int
1056 1037  rfs4_dss_setpaths(char *buf, size_t buflen)
1057 1038  {
1058 1039          int error;
1059 1040  
1060 1041          /*
1061 1042           * If this is a "warm start", i.e. we previously had DSS paths,
1062 1043           * preserve the old paths.
1063 1044           */
1064 1045          if (rfs4_dss_paths != NULL) {
1065 1046                  /*
1066 1047                   * Before we lose the ptr, destroy the nvlist and pathnames
1067 1048                   * array from the warm start before this one.
1068 1049                   */
1069 1050                  nvlist_free(rfs4_dss_oldpaths);
1070 1051                  rfs4_dss_oldpaths = rfs4_dss_paths;
1071 1052          }
1072 1053  
1073 1054          /* unpack the buffer into a searchable nvlist */
1074 1055          error = nvlist_unpack(buf, buflen, &rfs4_dss_paths, KM_SLEEP);
1075 1056          if (error)
1076 1057                  return (error);
1077 1058  
1078 1059          /*
1079 1060           * Search the nvlist for the pathnames nvpair (which is the only nvpair
1080 1061           * in the list, and record its location.
1081 1062           */
1082 1063          error = nvlist_lookup_string_array(rfs4_dss_paths, NFS4_DSS_NVPAIR_NAME,
1083 1064              &rfs4_dss_newpaths, &rfs4_dss_numnewpaths);
1084 1065          return (error);
1085 1066  }
1086 1067  
1087 1068  /*
1088 1069   * Ultimately the nfssys() call NFS4_CLR_STATE endsup here
1089 1070   * to find and mark the client for forced expire.
1090 1071   */
1091 1072  static void
1092 1073  rfs4_client_scrub(rfs4_entry_t ent, void *arg)
1093 1074  {
1094 1075          rfs4_client_t *cp = (rfs4_client_t *)ent;
1095 1076          struct nfs4clrst_args *clr = arg;
1096 1077          struct sockaddr_in6 *ent_sin6;
1097 1078          struct in6_addr  clr_in6;
1098 1079          struct sockaddr_in  *ent_sin;
1099 1080          struct in_addr   clr_in;
1100 1081  
1101 1082          if (clr->addr_type != cp->rc_addr.ss_family) {
1102 1083                  return;
1103 1084          }
1104 1085  
1105 1086          switch (clr->addr_type) {
1106 1087  
1107 1088          case AF_INET6:
1108 1089                  /* copyin the address from user space */
1109 1090                  if (copyin(clr->ap, &clr_in6, sizeof (clr_in6))) {
1110 1091                          break;
1111 1092                  }
1112 1093  
1113 1094                  ent_sin6 = (struct sockaddr_in6 *)&cp->rc_addr;
1114 1095  
1115 1096                  /*
1116 1097                   * now compare, and if equivalent mark entry
1117 1098                   * for forced expiration
1118 1099                   */
1119 1100                  if (IN6_ARE_ADDR_EQUAL(&ent_sin6->sin6_addr, &clr_in6)) {
1120 1101                          cp->rc_forced_expire = 1;
1121 1102                  }
1122 1103                  break;
1123 1104  
1124 1105          case AF_INET:
1125 1106                  /* copyin the address from user space */
1126 1107                  if (copyin(clr->ap, &clr_in, sizeof (clr_in))) {
1127 1108                          break;
1128 1109                  }
1129 1110  
1130 1111                  ent_sin = (struct sockaddr_in *)&cp->rc_addr;
1131 1112  
1132 1113                  /*
1133 1114                   * now compare, and if equivalent mark entry
1134 1115                   * for forced expiration
1135 1116                   */
1136 1117                  if (ent_sin->sin_addr.s_addr == clr_in.s_addr) {
1137 1118                          cp->rc_forced_expire = 1;
1138 1119                  }
1139 1120                  break;
1140 1121  
1141 1122          default:
1142 1123                  /* force this assert to fail */
1143 1124                  ASSERT(clr->addr_type != clr->addr_type);
  
    | 
      ↓ open down ↓ | 
    172 lines elided | 
    
      ↑ open up ↑ | 
  
1144 1125          }
1145 1126  }
1146 1127  
1147 1128  /*
1148 1129   * This is called from nfssys() in order to clear server state
1149 1130   * for the specified client IP Address.
1150 1131   */
1151 1132  void
1152 1133  rfs4_clear_client_state(struct nfs4clrst_args *clr)
1153 1134  {
1154      -        (void) rfs4_dbe_walk(rfs4_client_tab, rfs4_client_scrub, clr);
     1135 +        nfs4_srv_t *nsrv4;
     1136 +        nsrv4 = nfs4_get_srv();
     1137 +        (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
1155 1138  }
1156 1139  
1157 1140  /*
1158 1141   * Used to initialize the NFSv4 server's state or database.  All of
1159      - * the tables are created and timers are set. Only called when NFSv4
1160      - * service is provided.
     1142 + * the tables are created and timers are set.
1161 1143   */
1162 1144  void
1163      -rfs4_state_init()
     1145 +rfs4_state_g_init()
1164 1146  {
1165      -        int start_grace;
1166 1147          extern boolean_t rfs4_cpr_callb(void *, int);
1167      -        char *dss_path = NFS4_DSS_VAR_DIR;
1168      -        time_t start_time;
     1148 +        /*
     1149 +         * Add a CPR callback so that we can update client
     1150 +         * access times to extend the lease after a suspend
     1151 +         * and resume (using the same class as rpcmod/connmgr)
     1152 +         */
     1153 +        cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
1169 1154  
1170      -        mutex_enter(&rfs4_state_lock);
     1155 +        /*
     1156 +         * NFSv4 server state databases
     1157 +         *
     1158 +         * Initialized when the module is loaded and used by NFSv4 state
     1159 +         * tables.  These kmem_cache free pools are used globally, the NFSv4
     1160 +         * state tables which make use of these kmem_cache free pools are per
     1161 +         * zone.
     1162 +         *
     1163 +         * initialize the global kmem_cache free pools which will be used by
     1164 +         * the NFSv4 state tables.
     1165 +         */
     1166 +        /* CSTYLED */
     1167 +        rfs4_client_mem_cache = nfs4_init_mem_cache("Client_entry_cache", 2, sizeof (rfs4_client_t), 0);
     1168 +        /* CSTYLED */
     1169 +        rfs4_clntIP_mem_cache = nfs4_init_mem_cache("ClntIP_entry_cache", 1, sizeof (rfs4_clntip_t), 1);
     1170 +        /* CSTYLED */
     1171 +        rfs4_openown_mem_cache = nfs4_init_mem_cache("OpenOwner_entry_cache", 1, sizeof (rfs4_openowner_t), 2);
     1172 +        /* CSTYLED */
     1173 +        rfs4_openstID_mem_cache = nfs4_init_mem_cache("OpenStateID_entry_cache", 3, sizeof (rfs4_state_t), 3);
     1174 +        /* CSTYLED */
     1175 +        rfs4_lockstID_mem_cache = nfs4_init_mem_cache("LockStateID_entry_cache", 3, sizeof (rfs4_lo_state_t), 4);
     1176 +        /* CSTYLED */
     1177 +        rfs4_lockown_mem_cache = nfs4_init_mem_cache("Lockowner_entry_cache", 2, sizeof (rfs4_lockowner_t), 5);
     1178 +        /* CSTYLED */
     1179 +        rfs4_file_mem_cache = nfs4_init_mem_cache("File_entry_cache", 1, sizeof (rfs4_file_t), 6);
     1180 +        /* CSTYLED */
     1181 +        rfs4_delegstID_mem_cache = nfs4_init_mem_cache("DelegStateID_entry_cache", 2, sizeof (rfs4_deleg_state_t), 7);
1171 1182  
     1183 +        rfs4_client_clrst = rfs4_clear_client_state;
     1184 +}
     1185 +
     1186 +
     1187 +/*
     1188 + * Used at server shutdown to cleanup all of the NFSv4 server's structures
     1189 + * and other state.
     1190 + */
     1191 +void
     1192 +rfs4_state_g_fini()
     1193 +{
     1194 +        int i;
1172 1195          /*
1173      -         * If the server state database has already been initialized,
1174      -         * skip it
     1196 +         * Cleanup the CPR callback.
1175 1197           */
1176      -        if (rfs4_server_state != NULL) {
1177      -                mutex_exit(&rfs4_state_lock);
1178      -                return;
     1198 +        if (cpr_id)
     1199 +                (void) callb_delete(cpr_id);
     1200 +
     1201 +        rfs4_client_clrst = NULL;
     1202 +
     1203 +        /* free the NFSv4 state databases */
     1204 +        for (i = 0; i < RFS4_DB_MEM_CACHE_NUM; i++) {
     1205 +                kmem_cache_destroy(rfs4_db_mem_cache_table[i].r_db_mem_cache);
     1206 +                rfs4_db_mem_cache_table[i].r_db_mem_cache = NULL;
1179 1207          }
1180 1208  
1181      -        rw_init(&rfs4_findclient_lock, NULL, RW_DEFAULT, NULL);
     1209 +        rfs4_client_mem_cache = NULL;
     1210 +        rfs4_clntIP_mem_cache = NULL;
     1211 +        rfs4_openown_mem_cache = NULL;
     1212 +        rfs4_openstID_mem_cache = NULL;
     1213 +        rfs4_lockstID_mem_cache = NULL;
     1214 +        rfs4_lockown_mem_cache = NULL;
     1215 +        rfs4_file_mem_cache = NULL;
     1216 +        rfs4_delegstID_mem_cache = NULL;
1182 1217  
     1218 +        /* DSS: distributed stable storage */
     1219 +        nvlist_free(rfs4_dss_oldpaths);
     1220 +        nvlist_free(rfs4_dss_paths);
     1221 +        rfs4_dss_paths = rfs4_dss_oldpaths = NULL;
     1222 +}
     1223 +
     1224 +/*
     1225 + * Used to initialize the per zone NFSv4 server's state
     1226 + */
     1227 +void
     1228 +rfs4_state_zone_init(nfs4_srv_t *nsrv4)
     1229 +{
     1230 +        time_t start_time;
     1231 +        int start_grace;
     1232 +        char *dss_path = NFS4_DSS_VAR_DIR;
     1233 +
     1234 +        /* DSS: distributed stable storage: initialise served paths list */
     1235 +        nsrv4->dss_pathlist = NULL;
     1236 +
1183 1237          /*
1184 1238           * Set the boot time.  If the server
1185 1239           * has been restarted quickly and has had the opportunity to
1186 1240           * service clients, then the start_time needs to be bumped
1187 1241           * regardless.  A small window but it exists...
1188 1242           */
1189 1243          start_time = gethrestime_sec();
1190      -        if (rfs4_start_time < start_time)
1191      -                rfs4_start_time = start_time;
     1244 +        if (nsrv4->rfs4_start_time < start_time)
     1245 +                nsrv4->rfs4_start_time = start_time;
1192 1246          else
1193      -                rfs4_start_time++;
     1247 +                nsrv4->rfs4_start_time++;
1194 1248  
1195      -        /* DSS: distributed stable storage: initialise served paths list */
1196      -        rfs4_dss_pathlist = NULL;
1197      -
1198 1249          /*
1199 1250           * Create the first server instance, or a new one if the server has
1200 1251           * been restarted; see above comments on rfs4_start_time. Don't
1201 1252           * start its grace period; that will be done later, to maximise the
1202 1253           * clients' recovery window.
1203 1254           */
1204 1255          start_grace = 0;
1205      -        rfs4_servinst_create(start_grace, 1, &dss_path);
     1256 +        if (curzone == global_zone && rfs4_dss_numnewpaths > 0) {
     1257 +                int i;
     1258 +                char **dss_allpaths = NULL;
     1259 +                dss_allpaths = kmem_alloc(sizeof (char *) *
     1260 +                    (rfs4_dss_numnewpaths + 1), KM_SLEEP);
     1261 +                /*
     1262 +                 * Add the default path into the list of paths for saving
     1263 +                 * state informantion.
     1264 +                 */
     1265 +                dss_allpaths[0] = dss_path;
     1266 +                for (i = 0; i < rfs4_dss_numnewpaths; i++) {
     1267 +                        dss_allpaths[i + 1] = rfs4_dss_newpaths[i];
     1268 +                }
     1269 +                rfs4_servinst_create(nsrv4, start_grace,
     1270 +                    (rfs4_dss_numnewpaths + 1), dss_allpaths);
     1271 +                kmem_free(dss_allpaths,
     1272 +                    (sizeof (char *) * (rfs4_dss_numnewpaths + 1)));
     1273 +        } else {
     1274 +                rfs4_servinst_create(nsrv4, start_grace, 1, &dss_path);
     1275 +        }
1206 1276  
1207 1277          /* reset the "first NFSv4 request" status */
1208      -        rfs4_seen_first_compound = 0;
     1278 +        nsrv4->seen_first_compound = 0;
1209 1279  
     1280 +        mutex_enter(&nsrv4->state_lock);
     1281 +
1210 1282          /*
1211      -         * Add a CPR callback so that we can update client
1212      -         * access times to extend the lease after a suspend
1213      -         * and resume (using the same class as rpcmod/connmgr)
     1283 +         * If the server state database has already been initialized,
     1284 +         * skip it
1214 1285           */
1215      -        cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
     1286 +        if (nsrv4->nfs4_server_state != NULL) {
     1287 +                mutex_exit(&nsrv4->state_lock);
     1288 +                return;
     1289 +        }
1216 1290  
     1291 +        rw_init(&nsrv4->rfs4_findclient_lock, NULL, RW_DEFAULT, NULL);
     1292 +
1217 1293          /* set the various cache timers for table creation */
1218      -        if (rfs4_client_cache_time == 0)
1219      -                rfs4_client_cache_time = CLIENT_CACHE_TIME;
1220      -        if (rfs4_openowner_cache_time == 0)
1221      -                rfs4_openowner_cache_time = OPENOWNER_CACHE_TIME;
1222      -        if (rfs4_state_cache_time == 0)
1223      -                rfs4_state_cache_time = STATE_CACHE_TIME;
1224      -        if (rfs4_lo_state_cache_time == 0)
1225      -                rfs4_lo_state_cache_time = LO_STATE_CACHE_TIME;
1226      -        if (rfs4_lockowner_cache_time == 0)
1227      -                rfs4_lockowner_cache_time = LOCKOWNER_CACHE_TIME;
1228      -        if (rfs4_file_cache_time == 0)
1229      -                rfs4_file_cache_time = FILE_CACHE_TIME;
1230      -        if (rfs4_deleg_state_cache_time == 0)
1231      -                rfs4_deleg_state_cache_time = DELEG_STATE_CACHE_TIME;
     1294 +        if (nsrv4->rfs4_client_cache_time == 0)
     1295 +                nsrv4->rfs4_client_cache_time = CLIENT_CACHE_TIME;
     1296 +        if (nsrv4->rfs4_openowner_cache_time == 0)
     1297 +                nsrv4->rfs4_openowner_cache_time = OPENOWNER_CACHE_TIME;
     1298 +        if (nsrv4->rfs4_state_cache_time == 0)
     1299 +                nsrv4->rfs4_state_cache_time = STATE_CACHE_TIME;
     1300 +        if (nsrv4->rfs4_lo_state_cache_time == 0)
     1301 +                nsrv4->rfs4_lo_state_cache_time = LO_STATE_CACHE_TIME;
     1302 +        if (nsrv4->rfs4_lockowner_cache_time == 0)
     1303 +                nsrv4->rfs4_lockowner_cache_time = LOCKOWNER_CACHE_TIME;
     1304 +        if (nsrv4->rfs4_file_cache_time == 0)
     1305 +                nsrv4->rfs4_file_cache_time = FILE_CACHE_TIME;
     1306 +        if (nsrv4->rfs4_deleg_state_cache_time == 0)
     1307 +                nsrv4->rfs4_deleg_state_cache_time = DELEG_STATE_CACHE_TIME;
1232 1308  
1233 1309          /* Create the overall database to hold all server state */
1234      -        rfs4_server_state = rfs4_database_create(rfs4_database_debug);
     1310 +        nsrv4->nfs4_server_state = rfs4_database_create(rfs4_database_debug);
1235 1311  
1236 1312          /* Now create the individual tables */
1237      -        rfs4_client_cache_time *= rfs4_lease_time;
1238      -        rfs4_client_tab = rfs4_table_create(rfs4_server_state,
     1313 +        nsrv4->rfs4_client_cache_time *= rfs4_lease_time;
     1314 +        nsrv4->rfs4_client_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1239 1315              "Client",
1240      -            rfs4_client_cache_time,
     1316 +            nsrv4->rfs4_client_cache_time,
1241 1317              2,
1242 1318              rfs4_client_create,
1243 1319              rfs4_client_destroy,
1244 1320              rfs4_client_expiry,
1245 1321              sizeof (rfs4_client_t),
1246 1322              TABSIZE,
1247 1323              MAXTABSZ/8, 100);
1248      -        rfs4_nfsclnt_idx = rfs4_index_create(rfs4_client_tab,
     1324 +        nsrv4->rfs4_nfsclnt_idx = rfs4_index_create(nsrv4->rfs4_client_tab,
1249 1325              "nfs_client_id4", nfsclnt_hash,
1250 1326              nfsclnt_compare, nfsclnt_mkkey,
1251 1327              TRUE);
1252      -        rfs4_clientid_idx = rfs4_index_create(rfs4_client_tab,
     1328 +        nsrv4->rfs4_clientid_idx = rfs4_index_create(nsrv4->rfs4_client_tab,
1253 1329              "client_id", clientid_hash,
1254 1330              clientid_compare, clientid_mkkey,
1255 1331              FALSE);
1256 1332  
1257      -        rfs4_clntip_cache_time = 86400 * 365;   /* about a year */
1258      -        rfs4_clntip_tab = rfs4_table_create(rfs4_server_state,
     1333 +        nsrv4->rfs4_clntip_cache_time = 86400 * 365;    /* about a year */
     1334 +        nsrv4->rfs4_clntip_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1259 1335              "ClntIP",
1260      -            rfs4_clntip_cache_time,
     1336 +            nsrv4->rfs4_clntip_cache_time,
1261 1337              1,
1262 1338              rfs4_clntip_create,
1263 1339              rfs4_clntip_destroy,
1264 1340              rfs4_clntip_expiry,
1265 1341              sizeof (rfs4_clntip_t),
1266 1342              TABSIZE,
1267 1343              MAXTABSZ, 100);
1268      -        rfs4_clntip_idx = rfs4_index_create(rfs4_clntip_tab,
     1344 +        nsrv4->rfs4_clntip_idx = rfs4_index_create(nsrv4->rfs4_clntip_tab,
1269 1345              "client_ip", clntip_hash,
1270 1346              clntip_compare, clntip_mkkey,
1271 1347              TRUE);
1272 1348  
1273      -        rfs4_openowner_cache_time *= rfs4_lease_time;
1274      -        rfs4_openowner_tab = rfs4_table_create(rfs4_server_state,
     1349 +        nsrv4->rfs4_openowner_cache_time *= rfs4_lease_time;
     1350 +        nsrv4->rfs4_openowner_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1275 1351              "OpenOwner",
1276      -            rfs4_openowner_cache_time,
     1352 +            nsrv4->rfs4_openowner_cache_time,
1277 1353              1,
1278 1354              rfs4_openowner_create,
1279 1355              rfs4_openowner_destroy,
1280 1356              rfs4_openowner_expiry,
1281 1357              sizeof (rfs4_openowner_t),
1282 1358              TABSIZE,
1283 1359              MAXTABSZ, 100);
1284      -        rfs4_openowner_idx = rfs4_index_create(rfs4_openowner_tab,
     1360 +        nsrv4->rfs4_openowner_idx = rfs4_index_create(nsrv4->rfs4_openowner_tab,
1285 1361              "open_owner4", openowner_hash,
1286 1362              openowner_compare,
1287 1363              openowner_mkkey, TRUE);
1288 1364  
1289      -        rfs4_state_cache_time *= rfs4_lease_time;
1290      -        rfs4_state_tab = rfs4_table_create(rfs4_server_state,
     1365 +        nsrv4->rfs4_state_cache_time *= rfs4_lease_time;
     1366 +        nsrv4->rfs4_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1291 1367              "OpenStateID",
1292      -            rfs4_state_cache_time,
     1368 +            nsrv4->rfs4_state_cache_time,
1293 1369              3,
1294 1370              rfs4_state_create,
1295 1371              rfs4_state_destroy,
1296 1372              rfs4_state_expiry,
1297 1373              sizeof (rfs4_state_t),
1298 1374              TABSIZE,
1299 1375              MAXTABSZ, 100);
1300 1376  
1301      -        rfs4_state_owner_file_idx = rfs4_index_create(rfs4_state_tab,
     1377 +        /* CSTYLED */
     1378 +        nsrv4->rfs4_state_owner_file_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1302 1379              "Openowner-File",
1303 1380              state_owner_file_hash,
1304 1381              state_owner_file_compare,
1305 1382              state_owner_file_mkkey, TRUE);
1306 1383  
1307      -        rfs4_state_idx = rfs4_index_create(rfs4_state_tab,
     1384 +        nsrv4->rfs4_state_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1308 1385              "State-id", state_hash,
1309 1386              state_compare, state_mkkey, FALSE);
1310 1387  
1311      -        rfs4_state_file_idx = rfs4_index_create(rfs4_state_tab,
     1388 +        nsrv4->rfs4_state_file_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1312 1389              "File", state_file_hash,
1313 1390              state_file_compare, state_file_mkkey,
1314 1391              FALSE);
1315 1392  
1316      -        rfs4_lo_state_cache_time *= rfs4_lease_time;
1317      -        rfs4_lo_state_tab = rfs4_table_create(rfs4_server_state,
     1393 +        nsrv4->rfs4_lo_state_cache_time *= rfs4_lease_time;
     1394 +        nsrv4->rfs4_lo_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1318 1395              "LockStateID",
1319      -            rfs4_lo_state_cache_time,
     1396 +            nsrv4->rfs4_lo_state_cache_time,
1320 1397              2,
1321 1398              rfs4_lo_state_create,
1322 1399              rfs4_lo_state_destroy,
1323 1400              rfs4_lo_state_expiry,
1324 1401              sizeof (rfs4_lo_state_t),
1325 1402              TABSIZE,
1326 1403              MAXTABSZ, 100);
1327 1404  
1328      -        rfs4_lo_state_owner_idx = rfs4_index_create(rfs4_lo_state_tab,
     1405 +        /* CSTYLED */
     1406 +        nsrv4->rfs4_lo_state_owner_idx = rfs4_index_create(nsrv4->rfs4_lo_state_tab,
1329 1407              "lockownerxstate",
1330 1408              lo_state_lo_hash,
1331 1409              lo_state_lo_compare,
1332 1410              lo_state_lo_mkkey, TRUE);
1333 1411  
1334      -        rfs4_lo_state_idx = rfs4_index_create(rfs4_lo_state_tab,
     1412 +        nsrv4->rfs4_lo_state_idx = rfs4_index_create(nsrv4->rfs4_lo_state_tab,
1335 1413              "State-id",
1336 1414              lo_state_hash, lo_state_compare,
1337 1415              lo_state_mkkey, FALSE);
1338 1416  
1339      -        rfs4_lockowner_cache_time *= rfs4_lease_time;
     1417 +        nsrv4->rfs4_lockowner_cache_time *= rfs4_lease_time;
1340 1418  
1341      -        rfs4_lockowner_tab = rfs4_table_create(rfs4_server_state,
     1419 +        nsrv4->rfs4_lockowner_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1342 1420              "Lockowner",
1343      -            rfs4_lockowner_cache_time,
     1421 +            nsrv4->rfs4_lockowner_cache_time,
1344 1422              2,
1345 1423              rfs4_lockowner_create,
1346 1424              rfs4_lockowner_destroy,
1347 1425              rfs4_lockowner_expiry,
1348 1426              sizeof (rfs4_lockowner_t),
1349 1427              TABSIZE,
1350 1428              MAXTABSZ, 100);
1351 1429  
1352      -        rfs4_lockowner_idx = rfs4_index_create(rfs4_lockowner_tab,
     1430 +        nsrv4->rfs4_lockowner_idx = rfs4_index_create(nsrv4->rfs4_lockowner_tab,
1353 1431              "lock_owner4", lockowner_hash,
1354 1432              lockowner_compare,
1355 1433              lockowner_mkkey, TRUE);
1356 1434  
1357      -        rfs4_lockowner_pid_idx = rfs4_index_create(rfs4_lockowner_tab,
     1435 +        /* CSTYLED */
     1436 +        nsrv4->rfs4_lockowner_pid_idx = rfs4_index_create(nsrv4->rfs4_lockowner_tab,
1358 1437              "pid", pid_hash,
1359 1438              pid_compare, pid_mkkey,
1360 1439              FALSE);
1361 1440  
1362      -        rfs4_file_cache_time *= rfs4_lease_time;
1363      -        rfs4_file_tab = rfs4_table_create(rfs4_server_state,
     1441 +        nsrv4->rfs4_file_cache_time *= rfs4_lease_time;
     1442 +        nsrv4->rfs4_file_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1364 1443              "File",
1365      -            rfs4_file_cache_time,
     1444 +            nsrv4->rfs4_file_cache_time,
1366 1445              1,
1367 1446              rfs4_file_create,
1368 1447              rfs4_file_destroy,
1369 1448              NULL,
1370 1449              sizeof (rfs4_file_t),
1371 1450              TABSIZE,
1372 1451              MAXTABSZ, -1);
1373 1452  
1374      -        rfs4_file_idx = rfs4_index_create(rfs4_file_tab,
     1453 +        nsrv4->rfs4_file_idx = rfs4_index_create(nsrv4->rfs4_file_tab,
1375 1454              "Filehandle", file_hash,
1376 1455              file_compare, file_mkkey, TRUE);
1377 1456  
1378      -        rfs4_deleg_state_cache_time *= rfs4_lease_time;
1379      -        rfs4_deleg_state_tab = rfs4_table_create(rfs4_server_state,
     1457 +        nsrv4->rfs4_deleg_state_cache_time *= rfs4_lease_time;
     1458 +        /* CSTYLED */
     1459 +        nsrv4->rfs4_deleg_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1380 1460              "DelegStateID",
1381      -            rfs4_deleg_state_cache_time,
     1461 +            nsrv4->rfs4_deleg_state_cache_time,
1382 1462              2,
1383 1463              rfs4_deleg_state_create,
1384 1464              rfs4_deleg_state_destroy,
1385 1465              rfs4_deleg_state_expiry,
1386 1466              sizeof (rfs4_deleg_state_t),
1387 1467              TABSIZE,
1388 1468              MAXTABSZ, 100);
1389      -        rfs4_deleg_idx = rfs4_index_create(rfs4_deleg_state_tab,
     1469 +        nsrv4->rfs4_deleg_idx = rfs4_index_create(nsrv4->rfs4_deleg_state_tab,
1390 1470              "DelegByFileClient",
1391 1471              deleg_hash,
1392 1472              deleg_compare,
1393 1473              deleg_mkkey, TRUE);
1394 1474  
1395      -        rfs4_deleg_state_idx = rfs4_index_create(rfs4_deleg_state_tab,
     1475 +        /* CSTYLED */
     1476 +        nsrv4->rfs4_deleg_state_idx = rfs4_index_create(nsrv4->rfs4_deleg_state_tab,
1396 1477              "DelegState",
1397 1478              deleg_state_hash,
1398 1479              deleg_state_compare,
1399 1480              deleg_state_mkkey, FALSE);
1400 1481  
     1482 +        mutex_exit(&nsrv4->state_lock);
     1483 +
1401 1484          /*
1402 1485           * Init the stable storage.
1403 1486           */
1404      -        rfs4_ss_init();
1405      -
1406      -        rfs4_client_clrst = rfs4_clear_client_state;
1407      -
1408      -        mutex_exit(&rfs4_state_lock);
     1487 +        rfs4_ss_init(nsrv4);
1409 1488  }
1410 1489  
1411      -
1412 1490  /*
1413      - * Used at server shutdown to cleanup all of the NFSv4 server's structures
1414      - * and other state.
     1491 + * Used at server shutdown to cleanup all of NFSv4 server's zone structures
     1492 + * and state.
1415 1493   */
1416 1494  void
1417      -rfs4_state_fini()
     1495 +rfs4_state_zone_fini()
1418 1496  {
1419 1497          rfs4_database_t *dbp;
     1498 +        nfs4_srv_t *nsrv4;
     1499 +        nsrv4 = nfs4_get_srv();
1420 1500  
1421      -        mutex_enter(&rfs4_state_lock);
     1501 +        rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
1422 1502  
1423      -        if (rfs4_server_state == NULL) {
1424      -                mutex_exit(&rfs4_state_lock);
     1503 +        /*
     1504 +         * Clean up any dangling stable storage structures BEFORE calling
     1505 +         * rfs4_servinst_destroy_all() so there are no dangling structures
     1506 +         * (i.e. the srvinsts are all cleared of danglers BEFORE they get
     1507 +         * freed).
     1508 +         */
     1509 +        rfs4_ss_fini(nsrv4);
     1510 +
     1511 +        mutex_enter(&nsrv4->state_lock);
     1512 +
     1513 +        if (nsrv4->nfs4_server_state == NULL) {
     1514 +                mutex_exit(&nsrv4->state_lock);
1425 1515                  return;
1426 1516          }
1427 1517  
1428      -        rfs4_client_clrst = NULL;
     1518 +        /* destroy server instances and current instance ptr */
     1519 +        rfs4_servinst_destroy_all(nsrv4);
1429 1520  
1430      -        rfs4_set_deleg_policy(SRV_NEVER_DELEGATE);
1431      -        dbp = rfs4_server_state;
1432      -        rfs4_server_state = NULL;
     1521 +        /* reset the "first NFSv4 request" status */
     1522 +        nsrv4->seen_first_compound = 0;
1433 1523  
1434      -        /*
1435      -         * Cleanup the CPR callback.
1436      -         */
1437      -        if (cpr_id)
1438      -                (void) callb_delete(cpr_id);
     1524 +        dbp = nsrv4->nfs4_server_state;
     1525 +        nsrv4->nfs4_server_state = NULL;
1439 1526  
1440      -        rw_destroy(&rfs4_findclient_lock);
     1527 +        rw_destroy(&nsrv4->rfs4_findclient_lock);
1441 1528  
1442 1529          /* First stop all of the reaper threads in the database */
1443 1530          rfs4_database_shutdown(dbp);
1444      -        /* clean up any dangling stable storage structures */
1445      -        rfs4_ss_fini();
1446      -        /* Now actually destroy/release the database and its tables */
     1531 +
     1532 +        /*
     1533 +         * WARNING: There may be consumers of the rfs4 database still
     1534 +         * active as we destroy these.  IF that's the case, consider putting
     1535 +         * some of their _zone_fini()-like functions into the zsd key as
     1536 +         * ~~SHUTDOWN~~ functions instead of ~~DESTROY~~ functions.  We can
     1537 +         * maintain some ordering guarantees better that way.
     1538 +         */
     1539 +        /* Now destroy/release the database tables */
1447 1540          rfs4_database_destroy(dbp);
1448 1541  
1449 1542          /* Reset the cache timers for next time */
1450      -        rfs4_client_cache_time = 0;
1451      -        rfs4_openowner_cache_time = 0;
1452      -        rfs4_state_cache_time = 0;
1453      -        rfs4_lo_state_cache_time = 0;
1454      -        rfs4_lockowner_cache_time = 0;
1455      -        rfs4_file_cache_time = 0;
1456      -        rfs4_deleg_state_cache_time = 0;
     1543 +        nsrv4->rfs4_client_cache_time = 0;
     1544 +        nsrv4->rfs4_openowner_cache_time = 0;
     1545 +        nsrv4->rfs4_state_cache_time = 0;
     1546 +        nsrv4->rfs4_lo_state_cache_time = 0;
     1547 +        nsrv4->rfs4_lockowner_cache_time = 0;
     1548 +        nsrv4->rfs4_file_cache_time = 0;
     1549 +        nsrv4->rfs4_deleg_state_cache_time = 0;
1457 1550  
1458      -        mutex_exit(&rfs4_state_lock);
1459      -
1460      -        /* destroy server instances and current instance ptr */
1461      -        rfs4_servinst_destroy_all();
1462      -
1463      -        /* reset the "first NFSv4 request" status */
1464      -        rfs4_seen_first_compound = 0;
1465      -
1466      -        /* DSS: distributed stable storage */
1467      -        nvlist_free(rfs4_dss_oldpaths);
1468      -        nvlist_free(rfs4_dss_paths);
1469      -        rfs4_dss_paths = rfs4_dss_oldpaths = NULL;
     1551 +        mutex_exit(&nsrv4->state_lock);
1470 1552  }
1471 1553  
1472 1554  typedef union {
1473 1555          struct {
1474 1556                  uint32_t start_time;
1475 1557                  uint32_t c_id;
1476 1558          } impl_id;
1477 1559          clientid4 id4;
1478 1560  } cid;
1479 1561  
1480 1562  static int foreign_stateid(stateid_t *id);
1481 1563  static int foreign_clientid(cid *cidp);
1482 1564  static void embed_nodeid(cid *cidp);
1483 1565  
1484 1566  typedef union {
1485 1567          struct {
1486 1568                  uint32_t c_id;
1487 1569                  uint32_t gen_num;
1488 1570          } cv_impl;
1489 1571          verifier4       confirm_verf;
1490 1572  } scid_confirm_verf;
1491 1573  
1492 1574  static uint32_t
1493 1575  clientid_hash(void *key)
1494 1576  {
1495 1577          cid *idp = key;
1496 1578  
1497 1579          return (idp->impl_id.c_id);
1498 1580  }
1499 1581  
1500 1582  static bool_t
1501 1583  clientid_compare(rfs4_entry_t entry, void *key)
1502 1584  {
1503 1585          rfs4_client_t *cp = (rfs4_client_t *)entry;
1504 1586          clientid4 *idp = key;
1505 1587  
1506 1588          return (*idp == cp->rc_clientid);
1507 1589  }
1508 1590  
1509 1591  static void *
1510 1592  clientid_mkkey(rfs4_entry_t entry)
1511 1593  {
1512 1594          rfs4_client_t *cp = (rfs4_client_t *)entry;
1513 1595  
1514 1596          return (&cp->rc_clientid);
1515 1597  }
1516 1598  
1517 1599  static uint32_t
1518 1600  nfsclnt_hash(void *key)
1519 1601  {
1520 1602          nfs_client_id4 *client = key;
1521 1603          int i;
1522 1604          uint32_t hash = 0;
1523 1605  
1524 1606          for (i = 0; i < client->id_len; i++) {
1525 1607                  hash <<= 1;
1526 1608                  hash += (uint_t)client->id_val[i];
1527 1609          }
1528 1610          return (hash);
1529 1611  }
1530 1612  
1531 1613  
1532 1614  static bool_t
1533 1615  nfsclnt_compare(rfs4_entry_t entry, void *key)
1534 1616  {
1535 1617          rfs4_client_t *cp = (rfs4_client_t *)entry;
1536 1618          nfs_client_id4 *nfs_client = key;
1537 1619  
1538 1620          if (cp->rc_nfs_client.id_len != nfs_client->id_len)
1539 1621                  return (FALSE);
1540 1622  
1541 1623          return (bcmp(cp->rc_nfs_client.id_val, nfs_client->id_val,
1542 1624              nfs_client->id_len) == 0);
1543 1625  }
1544 1626  
1545 1627  static void *
1546 1628  nfsclnt_mkkey(rfs4_entry_t entry)
1547 1629  {
1548 1630          rfs4_client_t *cp = (rfs4_client_t *)entry;
1549 1631  
1550 1632          return (&cp->rc_nfs_client);
1551 1633  }
1552 1634  
1553 1635  static bool_t
1554 1636  rfs4_client_expiry(rfs4_entry_t u_entry)
1555 1637  {
1556 1638          rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1557 1639          bool_t cp_expired;
1558 1640  
1559 1641          if (rfs4_dbe_is_invalid(cp->rc_dbe)) {
1560 1642                  cp->rc_ss_remove = 1;
1561 1643                  return (TRUE);
1562 1644          }
1563 1645          /*
1564 1646           * If the sysadmin has used clear_locks for this
1565 1647           * entry then forced_expire will be set and we
1566 1648           * want this entry to be reaped. Or the entry
1567 1649           * has exceeded its lease period.
1568 1650           */
1569 1651          cp_expired = (cp->rc_forced_expire ||
1570 1652              (gethrestime_sec() - cp->rc_last_access
1571 1653              > rfs4_lease_time));
1572 1654  
1573 1655          if (!cp->rc_ss_remove && cp_expired)
  
    | 
      ↓ open down ↓ | 
    94 lines elided | 
    
      ↑ open up ↑ | 
  
1574 1656                  cp->rc_ss_remove = 1;
1575 1657          return (cp_expired);
1576 1658  }
1577 1659  
1578 1660  /*
1579 1661   * Remove the leaf file from all distributed stable storage paths.
1580 1662   */
1581 1663  static void
1582 1664  rfs4_dss_remove_cpleaf(rfs4_client_t *cp)
1583 1665  {
     1666 +        nfs4_srv_t *nsrv4;
1584 1667          rfs4_servinst_t *sip;
1585 1668          char *leaf = cp->rc_ss_pn->leaf;
1586 1669  
1587 1670          /*
1588 1671           * since the state files are written to all DSS
1589 1672           * paths we must remove this leaf file instance
1590 1673           * from all server instances.
1591 1674           */
1592 1675  
1593      -        mutex_enter(&rfs4_servinst_lock);
1594      -        for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
     1676 +        nsrv4 = nfs4_get_srv();
     1677 +        mutex_enter(&nsrv4->servinst_lock);
     1678 +        for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
1595 1679                  /* remove the leaf file associated with this server instance */
1596 1680                  rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
1597 1681          }
1598      -        mutex_exit(&rfs4_servinst_lock);
     1682 +        mutex_exit(&nsrv4->servinst_lock);
1599 1683  }
1600 1684  
1601 1685  static void
1602 1686  rfs4_dss_remove_leaf(rfs4_servinst_t *sip, char *dir_leaf, char *leaf)
1603 1687  {
1604 1688          int i, npaths = sip->dss_npaths;
1605 1689  
1606 1690          for (i = 0; i < npaths; i++) {
1607 1691                  rfs4_dss_path_t *dss_path = sip->dss_paths[i];
1608 1692                  char *path, *dir;
1609 1693                  size_t pathlen;
1610 1694  
1611 1695                  /* the HA-NFSv4 path might have been failed-over away from us */
1612 1696                  if (dss_path == NULL)
1613 1697                          continue;
1614 1698  
1615 1699                  dir = dss_path->path;
1616 1700  
1617 1701                  /* allow 3 extra bytes for two '/' & a NUL */
1618 1702                  pathlen = strlen(dir) + strlen(dir_leaf) + strlen(leaf) + 3;
1619 1703                  path = kmem_alloc(pathlen, KM_SLEEP);
1620 1704                  (void) sprintf(path, "%s/%s/%s", dir, dir_leaf, leaf);
1621 1705  
1622 1706                  (void) vn_remove(path, UIO_SYSSPACE, RMFILE);
1623 1707  
1624 1708                  kmem_free(path, pathlen);
1625 1709          }
1626 1710  }
1627 1711  
1628 1712  static void
1629 1713  rfs4_client_destroy(rfs4_entry_t u_entry)
1630 1714  {
1631 1715          rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1632 1716  
1633 1717          mutex_destroy(cp->rc_cbinfo.cb_lock);
1634 1718          cv_destroy(cp->rc_cbinfo.cb_cv);
1635 1719          cv_destroy(cp->rc_cbinfo.cb_cv_nullcaller);
1636 1720          list_destroy(&cp->rc_openownerlist);
1637 1721  
1638 1722          /* free callback info */
1639 1723          rfs4_cbinfo_free(&cp->rc_cbinfo);
1640 1724  
1641 1725          if (cp->rc_cp_confirmed)
1642 1726                  rfs4_client_rele(cp->rc_cp_confirmed);
1643 1727  
1644 1728          if (cp->rc_ss_pn) {
1645 1729                  /* check if the stable storage files need to be removed */
1646 1730                  if (cp->rc_ss_remove)
1647 1731                          rfs4_dss_remove_cpleaf(cp);
1648 1732                  rfs4_ss_pnfree(cp->rc_ss_pn);
1649 1733          }
1650 1734  
1651 1735          /* Free the client supplied client id */
1652 1736          kmem_free(cp->rc_nfs_client.id_val, cp->rc_nfs_client.id_len);
1653 1737  
1654 1738          if (cp->rc_sysidt != LM_NOSYSID)
1655 1739                  lm_free_sysidt(cp->rc_sysidt);
  
    | 
      ↓ open down ↓ | 
    47 lines elided | 
    
      ↑ open up ↑ | 
  
1656 1740  }
1657 1741  
1658 1742  static bool_t
1659 1743  rfs4_client_create(rfs4_entry_t u_entry, void *arg)
1660 1744  {
1661 1745          rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1662 1746          nfs_client_id4 *client = (nfs_client_id4 *)arg;
1663 1747          struct sockaddr *ca;
1664 1748          cid *cidp;
1665 1749          scid_confirm_verf *scvp;
     1750 +        nfs4_srv_t *nsrv4;
1666 1751  
     1752 +        nsrv4 = nfs4_get_srv();
     1753 +
1667 1754          /* Get a clientid to give to the client */
1668 1755          cidp = (cid *)&cp->rc_clientid;
1669      -        cidp->impl_id.start_time = rfs4_start_time;
     1756 +        cidp->impl_id.start_time = nsrv4->rfs4_start_time;
1670 1757          cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
1671 1758  
1672 1759          /* If we are booted as a cluster node, embed our nodeid */
1673 1760          if (cluster_bootflags & CLUSTER_BOOTED)
1674 1761                  embed_nodeid(cidp);
1675 1762  
1676 1763          /* Allocate and copy client's client id value */
1677 1764          cp->rc_nfs_client.id_val = kmem_alloc(client->id_len, KM_SLEEP);
1678 1765          cp->rc_nfs_client.id_len = client->id_len;
1679 1766          bcopy(client->id_val, cp->rc_nfs_client.id_val, client->id_len);
1680 1767          cp->rc_nfs_client.verifier = client->verifier;
1681 1768  
1682 1769          /* Copy client's IP address */
1683 1770          ca = client->cl_addr;
1684 1771          if (ca->sa_family == AF_INET)
1685 1772                  bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in));
1686 1773          else if (ca->sa_family == AF_INET6)
1687 1774                  bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in6));
1688 1775          cp->rc_nfs_client.cl_addr = (struct sockaddr *)&cp->rc_addr;
1689 1776  
1690 1777          /* Init the value for the SETCLIENTID_CONFIRM verifier */
1691 1778          scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1692 1779          scvp->cv_impl.c_id = cidp->impl_id.c_id;
1693 1780          scvp->cv_impl.gen_num = 0;
1694 1781  
1695 1782          /* An F_UNLKSYS has been done for this client */
1696 1783          cp->rc_unlksys_completed = FALSE;
1697 1784  
1698 1785          /* We need the client to ack us */
1699 1786          cp->rc_need_confirm = TRUE;
1700 1787          cp->rc_cp_confirmed = NULL;
1701 1788  
1702 1789          /* TRUE all the time until the callback path actually fails */
1703 1790          cp->rc_cbinfo.cb_notified_of_cb_path_down = TRUE;
1704 1791  
1705 1792          /* Initialize the access time to now */
1706 1793          cp->rc_last_access = gethrestime_sec();
1707 1794  
1708 1795          cp->rc_cr_set = NULL;
1709 1796  
1710 1797          cp->rc_sysidt = LM_NOSYSID;
1711 1798  
1712 1799          list_create(&cp->rc_openownerlist, sizeof (rfs4_openowner_t),
1713 1800              offsetof(rfs4_openowner_t, ro_node));
1714 1801  
1715 1802          /* set up the callback control structure */
1716 1803          cp->rc_cbinfo.cb_state = CB_UNINIT;
  
    | 
      ↓ open down ↓ | 
    37 lines elided | 
    
      ↑ open up ↑ | 
  
1717 1804          mutex_init(cp->rc_cbinfo.cb_lock, NULL, MUTEX_DEFAULT, NULL);
1718 1805          cv_init(cp->rc_cbinfo.cb_cv, NULL, CV_DEFAULT, NULL);
1719 1806          cv_init(cp->rc_cbinfo.cb_cv_nullcaller, NULL, CV_DEFAULT, NULL);
1720 1807  
1721 1808          /*
1722 1809           * Associate the client_t with the current server instance.
1723 1810           * The hold is solely to satisfy the calling requirement of
1724 1811           * rfs4_servinst_assign(). In this case it's not strictly necessary.
1725 1812           */
1726 1813          rfs4_dbe_hold(cp->rc_dbe);
1727      -        rfs4_servinst_assign(cp, rfs4_cur_servinst);
     1814 +        rfs4_servinst_assign(nsrv4, cp, nsrv4->nfs4_cur_servinst);
1728 1815          rfs4_dbe_rele(cp->rc_dbe);
1729 1816  
1730 1817          return (TRUE);
1731 1818  }
1732 1819  
1733 1820  /*
1734 1821   * Caller wants to generate/update the setclientid_confirm verifier
1735 1822   * associated with a client.  This is done during the SETCLIENTID
1736 1823   * processing.
1737 1824   */
1738 1825  void
1739 1826  rfs4_client_scv_next(rfs4_client_t *cp)
1740 1827  {
1741 1828          scid_confirm_verf *scvp;
1742 1829  
1743 1830          /* Init the value for the SETCLIENTID_CONFIRM verifier */
1744 1831          scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1745 1832          scvp->cv_impl.gen_num++;
1746 1833  }
1747 1834  
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
1748 1835  void
1749 1836  rfs4_client_rele(rfs4_client_t *cp)
1750 1837  {
1751 1838          rfs4_dbe_rele(cp->rc_dbe);
1752 1839  }
1753 1840  
1754 1841  rfs4_client_t *
1755 1842  rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
1756 1843  {
1757 1844          rfs4_client_t *cp;
     1845 +        nfs4_srv_t *nsrv4;
     1846 +        nsrv4 = nfs4_get_srv();
1758 1847  
1759 1848  
1760 1849          if (oldcp) {
1761      -                rw_enter(&rfs4_findclient_lock, RW_WRITER);
     1850 +                rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
1762 1851                  rfs4_dbe_hide(oldcp->rc_dbe);
1763 1852          } else {
1764      -                rw_enter(&rfs4_findclient_lock, RW_READER);
     1853 +                rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1765 1854          }
1766 1855  
1767      -        cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_nfsclnt_idx, client,
     1856 +        cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_nfsclnt_idx, client,
1768 1857              create, (void *)client, RFS4_DBS_VALID);
1769 1858  
1770 1859          if (oldcp)
1771 1860                  rfs4_dbe_unhide(oldcp->rc_dbe);
1772 1861  
1773      -        rw_exit(&rfs4_findclient_lock);
     1862 +        rw_exit(&nsrv4->rfs4_findclient_lock);
1774 1863  
1775 1864          return (cp);
1776 1865  }
1777 1866  
1778 1867  rfs4_client_t *
1779 1868  rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
1780 1869  {
1781 1870          rfs4_client_t *cp;
1782 1871          bool_t create = FALSE;
1783 1872          cid *cidp = (cid *)&clientid;
     1873 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
1784 1874  
1785 1875          /* If we're a cluster and the nodeid isn't right, short-circuit */
1786 1876          if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
1787 1877                  return (NULL);
1788 1878  
1789      -        rw_enter(&rfs4_findclient_lock, RW_READER);
     1879 +        rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1790 1880  
1791      -        cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx, &clientid,
     1881 +        cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx, &clientid,
1792 1882              &create, NULL, RFS4_DBS_VALID);
1793 1883  
1794      -        rw_exit(&rfs4_findclient_lock);
     1884 +        rw_exit(&nsrv4->rfs4_findclient_lock);
1795 1885  
1796 1886          if (cp && cp->rc_need_confirm && find_unconfirmed == FALSE) {
1797 1887                  rfs4_client_rele(cp);
1798 1888                  return (NULL);
1799 1889          } else {
1800 1890                  return (cp);
1801 1891          }
1802 1892  }
1803 1893  
1804 1894  static uint32_t
1805 1895  clntip_hash(void *key)
1806 1896  {
1807 1897          struct sockaddr *addr = key;
1808 1898          int i, len = 0;
1809 1899          uint32_t hash = 0;
1810 1900          char *ptr;
1811 1901  
1812 1902          if (addr->sa_family == AF_INET) {
1813 1903                  struct sockaddr_in *a = (struct sockaddr_in *)addr;
1814 1904                  len = sizeof (struct in_addr);
1815 1905                  ptr = (char *)&a->sin_addr;
1816 1906          } else if (addr->sa_family == AF_INET6) {
1817 1907                  struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr;
1818 1908                  len = sizeof (struct in6_addr);
1819 1909                  ptr = (char *)&a->sin6_addr;
1820 1910          } else
1821 1911                  return (0);
1822 1912  
1823 1913          for (i = 0; i < len; i++) {
1824 1914                  hash <<= 1;
1825 1915                  hash += (uint_t)ptr[i];
1826 1916          }
1827 1917          return (hash);
1828 1918  }
1829 1919  
1830 1920  static bool_t
1831 1921  clntip_compare(rfs4_entry_t entry, void *key)
1832 1922  {
1833 1923          rfs4_clntip_t *cp = (rfs4_clntip_t *)entry;
1834 1924          struct sockaddr *addr = key;
1835 1925          int len = 0;
1836 1926          char *p1, *p2;
1837 1927  
1838 1928          if (addr->sa_family == AF_INET) {
1839 1929                  struct sockaddr_in *a1 = (struct sockaddr_in *)&cp->ri_addr;
1840 1930                  struct sockaddr_in *a2 = (struct sockaddr_in *)addr;
1841 1931                  len = sizeof (struct in_addr);
1842 1932                  p1 = (char *)&a1->sin_addr;
1843 1933                  p2 = (char *)&a2->sin_addr;
1844 1934          } else if (addr->sa_family == AF_INET6) {
1845 1935                  struct sockaddr_in6 *a1 = (struct sockaddr_in6 *)&cp->ri_addr;
1846 1936                  struct sockaddr_in6 *a2 = (struct sockaddr_in6 *)addr;
1847 1937                  len = sizeof (struct in6_addr);
1848 1938                  p1 = (char *)&a1->sin6_addr;
1849 1939                  p2 = (char *)&a2->sin6_addr;
1850 1940          } else
1851 1941                  return (0);
1852 1942  
1853 1943          return (bcmp(p1, p2, len) == 0);
1854 1944  }
1855 1945  
1856 1946  static void *
1857 1947  clntip_mkkey(rfs4_entry_t entry)
1858 1948  {
1859 1949          rfs4_clntip_t *cp = (rfs4_clntip_t *)entry;
1860 1950  
1861 1951          return (&cp->ri_addr);
1862 1952  }
1863 1953  
1864 1954  static bool_t
1865 1955  rfs4_clntip_expiry(rfs4_entry_t u_entry)
1866 1956  {
1867 1957          rfs4_clntip_t *cp = (rfs4_clntip_t *)u_entry;
1868 1958  
1869 1959          if (rfs4_dbe_is_invalid(cp->ri_dbe))
1870 1960                  return (TRUE);
1871 1961          return (FALSE);
1872 1962  }
1873 1963  
1874 1964  /* ARGSUSED */
1875 1965  static void
1876 1966  rfs4_clntip_destroy(rfs4_entry_t u_entry)
1877 1967  {
1878 1968  }
1879 1969  
1880 1970  static bool_t
1881 1971  rfs4_clntip_create(rfs4_entry_t u_entry, void *arg)
1882 1972  {
1883 1973          rfs4_clntip_t *cp = (rfs4_clntip_t *)u_entry;
1884 1974          struct sockaddr *ca = (struct sockaddr *)arg;
1885 1975  
1886 1976          /* Copy client's IP address */
1887 1977          if (ca->sa_family == AF_INET)
1888 1978                  bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in));
1889 1979          else if (ca->sa_family == AF_INET6)
1890 1980                  bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in6));
1891 1981          else
  
    | 
      ↓ open down ↓ | 
    87 lines elided | 
    
      ↑ open up ↑ | 
  
1892 1982                  return (FALSE);
1893 1983          cp->ri_no_referrals = 1;
1894 1984  
1895 1985          return (TRUE);
1896 1986  }
1897 1987  
1898 1988  rfs4_clntip_t *
1899 1989  rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
1900 1990  {
1901 1991          rfs4_clntip_t *cp;
     1992 +        nfs4_srv_t *nsrv4;
1902 1993  
1903      -        rw_enter(&rfs4_findclient_lock, RW_READER);
     1994 +        nsrv4 = nfs4_get_srv();
1904 1995  
1905      -        cp = (rfs4_clntip_t *)rfs4_dbsearch(rfs4_clntip_idx, addr,
     1996 +        rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
     1997 +
     1998 +        cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1906 1999              create, addr, RFS4_DBS_VALID);
1907 2000  
1908      -        rw_exit(&rfs4_findclient_lock);
     2001 +        rw_exit(&nsrv4->rfs4_findclient_lock);
1909 2002  
1910 2003          return (cp);
1911 2004  }
1912 2005  
1913 2006  void
1914 2007  rfs4_invalidate_clntip(struct sockaddr *addr)
1915 2008  {
1916 2009          rfs4_clntip_t *cp;
1917 2010          bool_t create = FALSE;
     2011 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
1918 2012  
1919      -        rw_enter(&rfs4_findclient_lock, RW_READER);
     2013 +        rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1920 2014  
1921      -        cp = (rfs4_clntip_t *)rfs4_dbsearch(rfs4_clntip_idx, addr,
     2015 +        cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1922 2016              &create, NULL, RFS4_DBS_VALID);
1923 2017          if (cp == NULL) {
1924      -                rw_exit(&rfs4_findclient_lock);
     2018 +                rw_exit(&nsrv4->rfs4_findclient_lock);
1925 2019                  return;
1926 2020          }
1927 2021          rfs4_dbe_invalidate(cp->ri_dbe);
1928 2022          rfs4_dbe_rele(cp->ri_dbe);
1929 2023  
1930      -        rw_exit(&rfs4_findclient_lock);
     2024 +        rw_exit(&nsrv4->rfs4_findclient_lock);
1931 2025  }
1932 2026  
1933 2027  bool_t
1934 2028  rfs4_lease_expired(rfs4_client_t *cp)
1935 2029  {
1936 2030          bool_t rc;
1937 2031  
1938 2032          rfs4_dbe_lock(cp->rc_dbe);
1939 2033  
1940 2034          /*
1941 2035           * If the admin has executed clear_locks for this
1942 2036           * client id, force expire will be set, so no need
1943 2037           * to calculate anything because it's "outa here".
1944 2038           */
1945 2039          if (cp->rc_forced_expire) {
1946 2040                  rc = TRUE;
1947 2041          } else {
1948 2042                  rc = (gethrestime_sec() - cp->rc_last_access > rfs4_lease_time);
1949 2043          }
1950 2044  
1951 2045          /*
1952 2046           * If the lease has expired we will also want
1953 2047           * to remove any stable storage state data. So
1954 2048           * mark the client id accordingly.
1955 2049           */
1956 2050          if (!cp->rc_ss_remove)
1957 2051                  cp->rc_ss_remove = (rc == TRUE);
1958 2052  
1959 2053          rfs4_dbe_unlock(cp->rc_dbe);
1960 2054  
1961 2055          return (rc);
1962 2056  }
1963 2057  
1964 2058  void
1965 2059  rfs4_update_lease(rfs4_client_t *cp)
1966 2060  {
1967 2061          rfs4_dbe_lock(cp->rc_dbe);
1968 2062          if (!cp->rc_forced_expire)
1969 2063                  cp->rc_last_access = gethrestime_sec();
1970 2064          rfs4_dbe_unlock(cp->rc_dbe);
1971 2065  }
1972 2066  
1973 2067  
1974 2068  static bool_t
1975 2069  EQOPENOWNER(open_owner4 *a, open_owner4 *b)
1976 2070  {
1977 2071          bool_t rc;
1978 2072  
1979 2073          if (a->clientid != b->clientid)
1980 2074                  return (FALSE);
1981 2075  
1982 2076          if (a->owner_len != b->owner_len)
1983 2077                  return (FALSE);
1984 2078  
1985 2079          rc = (bcmp(a->owner_val, b->owner_val, a->owner_len) == 0);
1986 2080  
1987 2081          return (rc);
1988 2082  }
1989 2083  
1990 2084  static uint_t
1991 2085  openowner_hash(void *key)
1992 2086  {
1993 2087          int i;
1994 2088          open_owner4 *openowner = key;
1995 2089          uint_t hash = 0;
1996 2090  
1997 2091          for (i = 0; i < openowner->owner_len; i++) {
1998 2092                  hash <<= 4;
1999 2093                  hash += (uint_t)openowner->owner_val[i];
2000 2094          }
2001 2095          hash += (uint_t)openowner->clientid;
2002 2096          hash |= (openowner->clientid >> 32);
2003 2097  
2004 2098          return (hash);
2005 2099  }
2006 2100  
2007 2101  static bool_t
2008 2102  openowner_compare(rfs4_entry_t u_entry, void *key)
2009 2103  {
2010 2104          rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2011 2105          open_owner4 *arg = key;
2012 2106  
2013 2107          return (EQOPENOWNER(&oo->ro_owner, arg));
2014 2108  }
2015 2109  
2016 2110  void *
2017 2111  openowner_mkkey(rfs4_entry_t u_entry)
2018 2112  {
2019 2113          rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2020 2114  
2021 2115          return (&oo->ro_owner);
2022 2116  }
2023 2117  
2024 2118  /* ARGSUSED */
2025 2119  static bool_t
2026 2120  rfs4_openowner_expiry(rfs4_entry_t u_entry)
2027 2121  {
2028 2122          /* openstateid held us and did all needed delay */
2029 2123          return (TRUE);
2030 2124  }
2031 2125  
2032 2126  static void
2033 2127  rfs4_openowner_destroy(rfs4_entry_t u_entry)
2034 2128  {
2035 2129          rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2036 2130  
2037 2131          /* Remove open owner from client's lists of open owners */
2038 2132          rfs4_dbe_lock(oo->ro_client->rc_dbe);
2039 2133          list_remove(&oo->ro_client->rc_openownerlist, oo);
2040 2134          rfs4_dbe_unlock(oo->ro_client->rc_dbe);
2041 2135  
2042 2136          /* One less reference to the client */
2043 2137          rfs4_client_rele(oo->ro_client);
2044 2138          oo->ro_client = NULL;
2045 2139  
2046 2140          /* Free the last reply for this lock owner */
2047 2141          rfs4_free_reply(&oo->ro_reply);
2048 2142  
2049 2143          if (oo->ro_reply_fh.nfs_fh4_val) {
2050 2144                  kmem_free(oo->ro_reply_fh.nfs_fh4_val,
2051 2145                      oo->ro_reply_fh.nfs_fh4_len);
2052 2146                  oo->ro_reply_fh.nfs_fh4_val = NULL;
2053 2147                  oo->ro_reply_fh.nfs_fh4_len = 0;
2054 2148          }
2055 2149  
2056 2150          rfs4_sw_destroy(&oo->ro_sw);
2057 2151          list_destroy(&oo->ro_statelist);
2058 2152  
2059 2153          /* Free the lock owner id */
2060 2154          kmem_free(oo->ro_owner.owner_val, oo->ro_owner.owner_len);
2061 2155  }
2062 2156  
2063 2157  void
2064 2158  rfs4_openowner_rele(rfs4_openowner_t *oo)
2065 2159  {
2066 2160          rfs4_dbe_rele(oo->ro_dbe);
2067 2161  }
  
    | 
      ↓ open down ↓ | 
    127 lines elided | 
    
      ↑ open up ↑ | 
  
2068 2162  
2069 2163  static bool_t
2070 2164  rfs4_openowner_create(rfs4_entry_t u_entry, void *arg)
2071 2165  {
2072 2166          rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2073 2167          rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
2074 2168          open_owner4 *openowner = &argp->ro_owner;
2075 2169          seqid4 seqid = argp->ro_open_seqid;
2076 2170          rfs4_client_t *cp;
2077 2171          bool_t create = FALSE;
     2172 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2078 2173  
2079      -        rw_enter(&rfs4_findclient_lock, RW_READER);
     2174 +        rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2080 2175  
2081      -        cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx,
     2176 +        cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2082 2177              &openowner->clientid,
2083 2178              &create, NULL, RFS4_DBS_VALID);
2084 2179  
2085      -        rw_exit(&rfs4_findclient_lock);
     2180 +        rw_exit(&nsrv4->rfs4_findclient_lock);
2086 2181  
2087 2182          if (cp == NULL)
2088 2183                  return (FALSE);
2089 2184  
2090 2185          oo->ro_reply_fh.nfs_fh4_len = 0;
2091 2186          oo->ro_reply_fh.nfs_fh4_val = NULL;
2092 2187  
2093 2188          oo->ro_owner.clientid = openowner->clientid;
2094 2189          oo->ro_owner.owner_val =
2095 2190              kmem_alloc(openowner->owner_len, KM_SLEEP);
2096 2191  
2097 2192          bcopy(openowner->owner_val,
2098 2193              oo->ro_owner.owner_val, openowner->owner_len);
2099 2194  
2100 2195          oo->ro_owner.owner_len = openowner->owner_len;
2101 2196  
2102 2197          oo->ro_need_confirm = TRUE;
2103 2198  
2104 2199          rfs4_sw_init(&oo->ro_sw);
2105 2200  
2106 2201          oo->ro_open_seqid = seqid;
2107 2202          bzero(&oo->ro_reply, sizeof (nfs_resop4));
2108 2203          oo->ro_client = cp;
2109 2204          oo->ro_cr_set = NULL;
2110 2205  
2111 2206          list_create(&oo->ro_statelist, sizeof (rfs4_state_t),
2112 2207              offsetof(rfs4_state_t, rs_node));
2113 2208  
2114 2209          /* Insert openowner into client's open owner list */
2115 2210          rfs4_dbe_lock(cp->rc_dbe);
2116 2211          list_insert_tail(&cp->rc_openownerlist, oo);
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
2117 2212          rfs4_dbe_unlock(cp->rc_dbe);
2118 2213  
2119 2214          return (TRUE);
2120 2215  }
2121 2216  
2122 2217  rfs4_openowner_t *
2123 2218  rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
2124 2219  {
2125 2220          rfs4_openowner_t *oo;
2126 2221          rfs4_openowner_t arg;
     2222 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2127 2223  
2128 2224          arg.ro_owner = *openowner;
2129 2225          arg.ro_open_seqid = seqid;
2130      -        oo = (rfs4_openowner_t *)rfs4_dbsearch(rfs4_openowner_idx, openowner,
     2226 +        /* CSTYLED */
     2227 +        oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
2131 2228              create, &arg, RFS4_DBS_VALID);
2132 2229  
2133 2230          return (oo);
2134 2231  }
2135 2232  
2136 2233  void
2137 2234  rfs4_update_open_sequence(rfs4_openowner_t *oo)
2138 2235  {
2139 2236  
2140 2237          rfs4_dbe_lock(oo->ro_dbe);
2141 2238  
2142 2239          oo->ro_open_seqid++;
2143 2240  
2144 2241          rfs4_dbe_unlock(oo->ro_dbe);
2145 2242  }
2146 2243  
2147 2244  void
2148 2245  rfs4_update_open_resp(rfs4_openowner_t *oo, nfs_resop4 *resp, nfs_fh4 *fh)
2149 2246  {
2150 2247  
2151 2248          rfs4_dbe_lock(oo->ro_dbe);
2152 2249  
2153 2250          rfs4_free_reply(&oo->ro_reply);
2154 2251  
2155 2252          rfs4_copy_reply(&oo->ro_reply, resp);
2156 2253  
2157 2254          /* Save the filehandle if provided and free if not used */
2158 2255          if (resp->nfs_resop4_u.opopen.status == NFS4_OK &&
2159 2256              fh && fh->nfs_fh4_len) {
2160 2257                  if (oo->ro_reply_fh.nfs_fh4_val == NULL)
2161 2258                          oo->ro_reply_fh.nfs_fh4_val =
2162 2259                              kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
2163 2260                  nfs_fh4_copy(fh, &oo->ro_reply_fh);
2164 2261          } else {
2165 2262                  if (oo->ro_reply_fh.nfs_fh4_val) {
2166 2263                          kmem_free(oo->ro_reply_fh.nfs_fh4_val,
2167 2264                              oo->ro_reply_fh.nfs_fh4_len);
2168 2265                          oo->ro_reply_fh.nfs_fh4_val = NULL;
2169 2266                          oo->ro_reply_fh.nfs_fh4_len = 0;
2170 2267                  }
2171 2268          }
2172 2269  
2173 2270          rfs4_dbe_unlock(oo->ro_dbe);
2174 2271  }
2175 2272  
2176 2273  static bool_t
2177 2274  lockowner_compare(rfs4_entry_t u_entry, void *key)
2178 2275  {
2179 2276          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2180 2277          lock_owner4 *b = (lock_owner4 *)key;
2181 2278  
2182 2279          if (lo->rl_owner.clientid != b->clientid)
2183 2280                  return (FALSE);
2184 2281  
2185 2282          if (lo->rl_owner.owner_len != b->owner_len)
2186 2283                  return (FALSE);
2187 2284  
2188 2285          return (bcmp(lo->rl_owner.owner_val, b->owner_val,
2189 2286              lo->rl_owner.owner_len) == 0);
2190 2287  }
2191 2288  
2192 2289  void *
2193 2290  lockowner_mkkey(rfs4_entry_t u_entry)
2194 2291  {
2195 2292          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2196 2293  
2197 2294          return (&lo->rl_owner);
2198 2295  }
2199 2296  
2200 2297  static uint32_t
2201 2298  lockowner_hash(void *key)
2202 2299  {
2203 2300          int i;
2204 2301          lock_owner4 *lockowner = key;
2205 2302          uint_t hash = 0;
2206 2303  
2207 2304          for (i = 0; i < lockowner->owner_len; i++) {
2208 2305                  hash <<= 4;
2209 2306                  hash += (uint_t)lockowner->owner_val[i];
2210 2307          }
2211 2308          hash += (uint_t)lockowner->clientid;
2212 2309          hash |= (lockowner->clientid >> 32);
2213 2310  
2214 2311          return (hash);
2215 2312  }
2216 2313  
2217 2314  static uint32_t
2218 2315  pid_hash(void *key)
2219 2316  {
2220 2317          return ((uint32_t)(uintptr_t)key);
2221 2318  }
2222 2319  
2223 2320  static void *
2224 2321  pid_mkkey(rfs4_entry_t u_entry)
2225 2322  {
2226 2323          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2227 2324  
2228 2325          return ((void *)(uintptr_t)lo->rl_pid);
2229 2326  }
2230 2327  
2231 2328  static bool_t
2232 2329  pid_compare(rfs4_entry_t u_entry, void *key)
2233 2330  {
2234 2331          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2235 2332  
2236 2333          return (lo->rl_pid == (pid_t)(uintptr_t)key);
2237 2334  }
2238 2335  
2239 2336  static void
2240 2337  rfs4_lockowner_destroy(rfs4_entry_t u_entry)
2241 2338  {
2242 2339          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2243 2340  
2244 2341          /* Free the lock owner id */
2245 2342          kmem_free(lo->rl_owner.owner_val, lo->rl_owner.owner_len);
2246 2343          rfs4_client_rele(lo->rl_client);
2247 2344  }
2248 2345  
2249 2346  void
2250 2347  rfs4_lockowner_rele(rfs4_lockowner_t *lo)
2251 2348  {
2252 2349          rfs4_dbe_rele(lo->rl_dbe);
2253 2350  }
2254 2351  
2255 2352  /* ARGSUSED */
2256 2353  static bool_t
2257 2354  rfs4_lockowner_expiry(rfs4_entry_t u_entry)
2258 2355  {
2259 2356          /*
2260 2357           * Since expiry is called with no other references on
2261 2358           * this struct, go ahead and have it removed.
2262 2359           */
  
    | 
      ↓ open down ↓ | 
    122 lines elided | 
    
      ↑ open up ↑ | 
  
2263 2360          return (TRUE);
2264 2361  }
2265 2362  
2266 2363  static bool_t
2267 2364  rfs4_lockowner_create(rfs4_entry_t u_entry, void *arg)
2268 2365  {
2269 2366          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2270 2367          lock_owner4 *lockowner = (lock_owner4 *)arg;
2271 2368          rfs4_client_t *cp;
2272 2369          bool_t create = FALSE;
     2370 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2273 2371  
2274      -        rw_enter(&rfs4_findclient_lock, RW_READER);
     2372 +        rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2275 2373  
2276      -        cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx,
     2374 +        cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2277 2375              &lockowner->clientid,
2278 2376              &create, NULL, RFS4_DBS_VALID);
2279 2377  
2280      -        rw_exit(&rfs4_findclient_lock);
     2378 +        rw_exit(&nsrv4->rfs4_findclient_lock);
2281 2379  
2282 2380          if (cp == NULL)
2283 2381                  return (FALSE);
2284 2382  
2285 2383          /* Reference client */
2286 2384          lo->rl_client = cp;
2287 2385          lo->rl_owner.clientid = lockowner->clientid;
2288 2386          lo->rl_owner.owner_val = kmem_alloc(lockowner->owner_len, KM_SLEEP);
2289 2387          bcopy(lockowner->owner_val, lo->rl_owner.owner_val,
2290 2388              lockowner->owner_len);
2291 2389          lo->rl_owner.owner_len = lockowner->owner_len;
2292 2390          lo->rl_pid = rfs4_dbe_getid(lo->rl_dbe);
2293 2391  
2294 2392          return (TRUE);
2295 2393  }
2296 2394  
2297 2395  rfs4_lockowner_t *
2298 2396  rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
2299 2397  {
2300 2398          rfs4_lockowner_t *lo;
     2399 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2301 2400  
2302      -        lo = (rfs4_lockowner_t *)rfs4_dbsearch(rfs4_lockowner_idx, lockowner,
     2401 +        /* CSTYLED */
     2402 +        lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
2303 2403              create, lockowner, RFS4_DBS_VALID);
2304 2404  
2305 2405          return (lo);
2306 2406  }
2307 2407  
2308 2408  rfs4_lockowner_t *
2309 2409  rfs4_findlockowner_by_pid(pid_t pid)
2310 2410  {
2311 2411          rfs4_lockowner_t *lo;
2312 2412          bool_t create = FALSE;
     2413 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2313 2414  
2314      -        lo = (rfs4_lockowner_t *)rfs4_dbsearch(rfs4_lockowner_pid_idx,
     2415 +        lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
2315 2416              (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
2316 2417  
2317 2418          return (lo);
2318 2419  }
2319 2420  
2320 2421  
2321 2422  static uint32_t
2322 2423  file_hash(void *key)
2323 2424  {
2324 2425          return (ADDRHASH(key));
2325 2426  }
2326 2427  
2327 2428  static void *
2328 2429  file_mkkey(rfs4_entry_t u_entry)
2329 2430  {
2330 2431          rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2331 2432  
2332 2433          return (fp->rf_vp);
2333 2434  }
2334 2435  
2335 2436  static bool_t
2336 2437  file_compare(rfs4_entry_t u_entry, void *key)
2337 2438  {
2338 2439          rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2339 2440  
2340 2441          return (fp->rf_vp == (vnode_t *)key);
2341 2442  }
2342 2443  
2343 2444  static void
2344 2445  rfs4_file_destroy(rfs4_entry_t u_entry)
2345 2446  {
2346 2447          rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2347 2448  
2348 2449          list_destroy(&fp->rf_delegstatelist);
2349 2450  
2350 2451          if (fp->rf_filehandle.nfs_fh4_val)
2351 2452                  kmem_free(fp->rf_filehandle.nfs_fh4_val,
2352 2453                      fp->rf_filehandle.nfs_fh4_len);
2353 2454          cv_destroy(fp->rf_dinfo.rd_recall_cv);
2354 2455          if (fp->rf_vp) {
2355 2456                  vnode_t *vp = fp->rf_vp;
2356 2457  
2357 2458                  mutex_enter(&vp->v_vsd_lock);
2358 2459                  (void) vsd_set(vp, nfs4_srv_vkey, NULL);
2359 2460                  mutex_exit(&vp->v_vsd_lock);
2360 2461                  VN_RELE(vp);
2361 2462                  fp->rf_vp = NULL;
2362 2463          }
2363 2464          rw_destroy(&fp->rf_file_rwlock);
2364 2465  }
2365 2466  
2366 2467  /*
2367 2468   * Used to unlock the underlying dbe struct only
2368 2469   */
2369 2470  void
2370 2471  rfs4_file_rele(rfs4_file_t *fp)
2371 2472  {
2372 2473          rfs4_dbe_rele(fp->rf_dbe);
2373 2474  }
2374 2475  
2375 2476  typedef struct {
2376 2477      vnode_t *vp;
2377 2478      nfs_fh4 *fh;
2378 2479  } rfs4_fcreate_arg;
2379 2480  
2380 2481  static bool_t
2381 2482  rfs4_file_create(rfs4_entry_t u_entry, void *arg)
2382 2483  {
2383 2484          rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2384 2485          rfs4_fcreate_arg *ap = (rfs4_fcreate_arg *)arg;
2385 2486          vnode_t *vp = ap->vp;
2386 2487          nfs_fh4 *fh = ap->fh;
2387 2488  
2388 2489          VN_HOLD(vp);
2389 2490  
2390 2491          fp->rf_filehandle.nfs_fh4_len = 0;
2391 2492          fp->rf_filehandle.nfs_fh4_val = NULL;
2392 2493          ASSERT(fh && fh->nfs_fh4_len);
2393 2494          if (fh && fh->nfs_fh4_len) {
2394 2495                  fp->rf_filehandle.nfs_fh4_val =
2395 2496                      kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
2396 2497                  nfs_fh4_copy(fh, &fp->rf_filehandle);
2397 2498          }
2398 2499          fp->rf_vp = vp;
2399 2500  
2400 2501          list_create(&fp->rf_delegstatelist, sizeof (rfs4_deleg_state_t),
2401 2502              offsetof(rfs4_deleg_state_t, rds_node));
2402 2503  
2403 2504          fp->rf_share_deny = fp->rf_share_access = fp->rf_access_read = 0;
2404 2505          fp->rf_access_write = fp->rf_deny_read = fp->rf_deny_write = 0;
2405 2506  
2406 2507          mutex_init(fp->rf_dinfo.rd_recall_lock, NULL, MUTEX_DEFAULT, NULL);
2407 2508          cv_init(fp->rf_dinfo.rd_recall_cv, NULL, CV_DEFAULT, NULL);
2408 2509  
2409 2510          fp->rf_dinfo.rd_dtype = OPEN_DELEGATE_NONE;
2410 2511  
2411 2512          rw_init(&fp->rf_file_rwlock, NULL, RW_DEFAULT, NULL);
2412 2513  
2413 2514          mutex_enter(&vp->v_vsd_lock);
2414 2515          VERIFY(vsd_set(vp, nfs4_srv_vkey, (void *)fp) == 0);
  
    | 
      ↓ open down ↓ | 
    90 lines elided | 
    
      ↑ open up ↑ | 
  
2415 2516          mutex_exit(&vp->v_vsd_lock);
2416 2517  
2417 2518          return (TRUE);
2418 2519  }
2419 2520  
2420 2521  rfs4_file_t *
2421 2522  rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2422 2523  {
2423 2524          rfs4_file_t *fp;
2424 2525          rfs4_fcreate_arg arg;
     2526 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2425 2527  
2426 2528          arg.vp = vp;
2427 2529          arg.fh = fh;
2428 2530  
2429 2531          if (*create == TRUE)
2430      -                fp = (rfs4_file_t *)rfs4_dbsearch(rfs4_file_idx, vp, create,
     2532 +                /* CSTYLED */
     2533 +                fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp, create,
2431 2534                      &arg, RFS4_DBS_VALID);
2432 2535          else {
2433 2536                  mutex_enter(&vp->v_vsd_lock);
2434 2537                  fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2435 2538                  if (fp) {
2436 2539                          rfs4_dbe_lock(fp->rf_dbe);
2437 2540                          if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2438 2541                              (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2439 2542                                  rfs4_dbe_unlock(fp->rf_dbe);
2440 2543                                  fp = NULL;
2441 2544                          } else {
2442 2545                                  rfs4_dbe_hold(fp->rf_dbe);
2443 2546                                  rfs4_dbe_unlock(fp->rf_dbe);
2444 2547                          }
2445 2548                  }
2446 2549                  mutex_exit(&vp->v_vsd_lock);
2447 2550          }
2448 2551          return (fp);
2449 2552  }
2450 2553  
2451 2554  /*
2452 2555   * Find a file in the db and once it is located, take the rw lock.
2453 2556   * Need to check the vnode pointer and if it does not exist (it was
2454 2557   * removed between the db location and check) redo the find.  This
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
2455 2558   * assumes that a file struct that has a NULL vnode pointer is marked
2456 2559   * at 'invalid' and will not be found in the db the second time
2457 2560   * around.
2458 2561   */
2459 2562  rfs4_file_t *
2460 2563  rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2461 2564  {
2462 2565          rfs4_file_t *fp;
2463 2566          rfs4_fcreate_arg arg;
2464 2567          bool_t screate = *create;
     2568 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2465 2569  
2466 2570          if (screate == FALSE) {
2467 2571                  mutex_enter(&vp->v_vsd_lock);
2468 2572                  fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2469 2573                  if (fp) {
2470 2574                          rfs4_dbe_lock(fp->rf_dbe);
2471 2575                          if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2472 2576                              (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2473 2577                                  rfs4_dbe_unlock(fp->rf_dbe);
2474 2578                                  mutex_exit(&vp->v_vsd_lock);
2475 2579                                  fp = NULL;
2476 2580                          } else {
2477 2581                                  rfs4_dbe_hold(fp->rf_dbe);
2478 2582                                  rfs4_dbe_unlock(fp->rf_dbe);
2479 2583                                  mutex_exit(&vp->v_vsd_lock);
2480 2584                                  rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2481 2585                                  if (fp->rf_vp == NULL) {
2482 2586                                          rw_exit(&fp->rf_file_rwlock);
2483 2587                                          rfs4_file_rele(fp);
2484 2588                                          fp = NULL;
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
2485 2589                                  }
2486 2590                          }
2487 2591                  } else {
2488 2592                          mutex_exit(&vp->v_vsd_lock);
2489 2593                  }
2490 2594          } else {
2491 2595  retry:
2492 2596                  arg.vp = vp;
2493 2597                  arg.fh = fh;
2494 2598  
2495      -                fp = (rfs4_file_t *)rfs4_dbsearch(rfs4_file_idx, vp, create,
2496      -                    &arg, RFS4_DBS_VALID);
     2599 +                fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp,
     2600 +                    create, &arg, RFS4_DBS_VALID);
2497 2601                  if (fp != NULL) {
2498 2602                          rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2499 2603                          if (fp->rf_vp == NULL) {
2500 2604                                  rw_exit(&fp->rf_file_rwlock);
2501 2605                                  rfs4_file_rele(fp);
2502 2606                                  *create = screate;
2503 2607                                  goto retry;
2504 2608                          }
2505 2609                  }
2506 2610          }
2507 2611  
2508 2612          return (fp);
2509 2613  }
2510 2614  
2511 2615  static uint32_t
2512 2616  lo_state_hash(void *key)
2513 2617  {
2514 2618          stateid_t *id = key;
2515 2619  
2516 2620          return (id->bits.ident+id->bits.pid);
2517 2621  }
2518 2622  
2519 2623  static bool_t
2520 2624  lo_state_compare(rfs4_entry_t u_entry, void *key)
2521 2625  {
2522 2626          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2523 2627          stateid_t *id = key;
2524 2628          bool_t rc;
2525 2629  
2526 2630          rc = (lsp->rls_lockid.bits.boottime == id->bits.boottime &&
2527 2631              lsp->rls_lockid.bits.type == id->bits.type &&
2528 2632              lsp->rls_lockid.bits.ident == id->bits.ident &&
2529 2633              lsp->rls_lockid.bits.pid == id->bits.pid);
2530 2634  
2531 2635          return (rc);
2532 2636  }
2533 2637  
2534 2638  static void *
2535 2639  lo_state_mkkey(rfs4_entry_t u_entry)
2536 2640  {
2537 2641          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2538 2642  
2539 2643          return (&lsp->rls_lockid);
2540 2644  }
2541 2645  
2542 2646  static bool_t
2543 2647  rfs4_lo_state_expiry(rfs4_entry_t u_entry)
2544 2648  {
2545 2649          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2546 2650  
2547 2651          if (rfs4_dbe_is_invalid(lsp->rls_dbe))
2548 2652                  return (TRUE);
2549 2653          if (lsp->rls_state->rs_closed)
2550 2654                  return (TRUE);
2551 2655          return ((gethrestime_sec() -
2552 2656              lsp->rls_state->rs_owner->ro_client->rc_last_access
2553 2657              > rfs4_lease_time));
2554 2658  }
2555 2659  
2556 2660  static void
2557 2661  rfs4_lo_state_destroy(rfs4_entry_t u_entry)
2558 2662  {
2559 2663          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2560 2664  
2561 2665          rfs4_dbe_lock(lsp->rls_state->rs_dbe);
2562 2666          list_remove(&lsp->rls_state->rs_lostatelist, lsp);
2563 2667          rfs4_dbe_unlock(lsp->rls_state->rs_dbe);
2564 2668  
2565 2669          rfs4_sw_destroy(&lsp->rls_sw);
2566 2670  
2567 2671          /* Make sure to release the file locks */
2568 2672          if (lsp->rls_locks_cleaned == FALSE) {
2569 2673                  lsp->rls_locks_cleaned = TRUE;
2570 2674                  if (lsp->rls_locker->rl_client->rc_sysidt != LM_NOSYSID) {
2571 2675                          /* Is the PxFS kernel module loaded? */
2572 2676                          if (lm_remove_file_locks != NULL) {
2573 2677                                  int new_sysid;
2574 2678  
2575 2679                                  /* Encode the cluster nodeid in new sysid */
2576 2680                                  new_sysid =
2577 2681                                      lsp->rls_locker->rl_client->rc_sysidt;
2578 2682                                  lm_set_nlmid_flk(&new_sysid);
2579 2683  
2580 2684                                  /*
2581 2685                                   * This PxFS routine removes file locks for a
2582 2686                                   * client over all nodes of a cluster.
2583 2687                                   */
2584 2688                                  DTRACE_PROBE1(nfss_i_clust_rm_lck,
2585 2689                                      int, new_sysid);
2586 2690                                  (*lm_remove_file_locks)(new_sysid);
2587 2691                          } else {
2588 2692                                  (void) cleanlocks(
2589 2693                                      lsp->rls_state->rs_finfo->rf_vp,
2590 2694                                      lsp->rls_locker->rl_pid,
2591 2695                                      lsp->rls_locker->rl_client->rc_sysidt);
2592 2696                          }
2593 2697                  }
2594 2698          }
2595 2699  
2596 2700          /* Free the last reply for this state */
2597 2701          rfs4_free_reply(&lsp->rls_reply);
2598 2702  
2599 2703          rfs4_lockowner_rele(lsp->rls_locker);
2600 2704          lsp->rls_locker = NULL;
2601 2705  
2602 2706          rfs4_state_rele_nounlock(lsp->rls_state);
2603 2707          lsp->rls_state = NULL;
2604 2708  }
2605 2709  
2606 2710  static bool_t
2607 2711  rfs4_lo_state_create(rfs4_entry_t u_entry, void *arg)
2608 2712  {
2609 2713          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2610 2714          rfs4_lo_state_t *argp = (rfs4_lo_state_t *)arg;
2611 2715          rfs4_lockowner_t *lo = argp->rls_locker;
2612 2716          rfs4_state_t *sp = argp->rls_state;
2613 2717  
2614 2718          lsp->rls_state = sp;
2615 2719  
2616 2720          lsp->rls_lockid = sp->rs_stateid;
2617 2721          lsp->rls_lockid.bits.type = LOCKID;
2618 2722          lsp->rls_lockid.bits.chgseq = 0;
2619 2723          lsp->rls_lockid.bits.pid = lo->rl_pid;
2620 2724  
2621 2725          lsp->rls_locks_cleaned = FALSE;
2622 2726          lsp->rls_lock_completed = FALSE;
2623 2727  
2624 2728          rfs4_sw_init(&lsp->rls_sw);
2625 2729  
2626 2730          /* Attached the supplied lock owner */
2627 2731          rfs4_dbe_hold(lo->rl_dbe);
2628 2732          lsp->rls_locker = lo;
2629 2733  
2630 2734          rfs4_dbe_lock(sp->rs_dbe);
2631 2735          list_insert_tail(&sp->rs_lostatelist, lsp);
2632 2736          rfs4_dbe_hold(sp->rs_dbe);
2633 2737          rfs4_dbe_unlock(sp->rs_dbe);
2634 2738  
2635 2739          return (TRUE);
2636 2740  }
2637 2741  
2638 2742  void
2639 2743  rfs4_lo_state_rele(rfs4_lo_state_t *lsp, bool_t unlock_fp)
2640 2744  {
  
    | 
      ↓ open down ↓ | 
    134 lines elided | 
    
      ↑ open up ↑ | 
  
2641 2745          if (unlock_fp == TRUE)
2642 2746                  rw_exit(&lsp->rls_state->rs_finfo->rf_file_rwlock);
2643 2747          rfs4_dbe_rele(lsp->rls_dbe);
2644 2748  }
2645 2749  
2646 2750  static rfs4_lo_state_t *
2647 2751  rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
2648 2752  {
2649 2753          rfs4_lo_state_t *lsp;
2650 2754          bool_t create = FALSE;
     2755 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2651 2756  
2652      -        lsp = (rfs4_lo_state_t *)rfs4_dbsearch(rfs4_lo_state_idx, id,
     2757 +        lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
2653 2758              &create, NULL, RFS4_DBS_VALID);
2654 2759          if (lock_fp == TRUE && lsp != NULL)
2655 2760                  rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
2656 2761  
2657 2762          return (lsp);
2658 2763  }
2659 2764  
2660 2765  
2661 2766  static uint32_t
2662 2767  lo_state_lo_hash(void *key)
2663 2768  {
2664 2769          rfs4_lo_state_t *lsp = key;
2665 2770  
2666 2771          return (ADDRHASH(lsp->rls_locker) ^ ADDRHASH(lsp->rls_state));
2667 2772  }
2668 2773  
2669 2774  static bool_t
2670 2775  lo_state_lo_compare(rfs4_entry_t u_entry, void *key)
2671 2776  {
2672 2777          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2673 2778          rfs4_lo_state_t *keyp = key;
2674 2779  
2675 2780          return (keyp->rls_locker == lsp->rls_locker &&
2676 2781              keyp->rls_state == lsp->rls_state);
2677 2782  }
2678 2783  
2679 2784  static void *
2680 2785  lo_state_lo_mkkey(rfs4_entry_t u_entry)
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
2681 2786  {
2682 2787          return (u_entry);
2683 2788  }
2684 2789  
2685 2790  rfs4_lo_state_t *
2686 2791  rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
2687 2792      bool_t *create)
2688 2793  {
2689 2794          rfs4_lo_state_t *lsp;
2690 2795          rfs4_lo_state_t arg;
     2796 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2691 2797  
2692 2798          arg.rls_locker = lo;
2693 2799          arg.rls_state = sp;
2694 2800  
2695      -        lsp = (rfs4_lo_state_t *)rfs4_dbsearch(rfs4_lo_state_owner_idx, &arg,
2696      -            create, &arg, RFS4_DBS_VALID);
     2801 +        lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
     2802 +            &arg, create, &arg, RFS4_DBS_VALID);
2697 2803  
2698 2804          return (lsp);
2699 2805  }
2700 2806  
2701 2807  static stateid_t
2702 2808  get_stateid(id_t eid)
2703 2809  {
2704 2810          stateid_t id;
     2811 +        nfs4_srv_t *nsrv4;
2705 2812  
2706      -        id.bits.boottime = rfs4_start_time;
     2813 +        nsrv4 = nfs4_get_srv();
     2814 +
     2815 +        id.bits.boottime = nsrv4->rfs4_start_time;
2707 2816          id.bits.ident = eid;
2708 2817          id.bits.chgseq = 0;
2709 2818          id.bits.type = 0;
2710 2819          id.bits.pid = 0;
2711 2820  
2712 2821          /*
2713 2822           * If we are booted as a cluster node, embed our nodeid.
2714 2823           * We've already done sanity checks in rfs4_client_create() so no
2715 2824           * need to repeat them here.
2716 2825           */
2717 2826          id.bits.clnodeid = (cluster_bootflags & CLUSTER_BOOTED) ?
2718 2827              clconf_get_nodeid() : 0;
2719 2828  
2720 2829          return (id);
2721 2830  }
2722 2831  
2723 2832  /*
2724 2833   * For use only when booted as a cluster node.
2725 2834   * Returns TRUE if the embedded nodeid indicates that this stateid was
2726 2835   * generated on another node.
2727 2836   */
2728 2837  static int
2729 2838  foreign_stateid(stateid_t *id)
2730 2839  {
2731 2840          ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2732 2841          return (id->bits.clnodeid != (uint32_t)clconf_get_nodeid());
2733 2842  }
2734 2843  
2735 2844  /*
2736 2845   * For use only when booted as a cluster node.
2737 2846   * Returns TRUE if the embedded nodeid indicates that this clientid was
2738 2847   * generated on another node.
2739 2848   */
2740 2849  static int
2741 2850  foreign_clientid(cid *cidp)
2742 2851  {
2743 2852          ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2744 2853          return (cidp->impl_id.c_id >> CLUSTER_NODEID_SHIFT !=
2745 2854              (uint32_t)clconf_get_nodeid());
2746 2855  }
2747 2856  
2748 2857  /*
2749 2858   * For use only when booted as a cluster node.
2750 2859   * Embed our cluster nodeid into the clientid.
2751 2860   */
2752 2861  static void
2753 2862  embed_nodeid(cid *cidp)
2754 2863  {
2755 2864          int clnodeid;
2756 2865          /*
2757 2866           * Currently, our state tables are small enough that their
2758 2867           * ids will leave enough bits free for the nodeid. If the
2759 2868           * tables become larger, we mustn't overwrite the id.
2760 2869           * Equally, we only have room for so many bits of nodeid, so
2761 2870           * must check that too.
2762 2871           */
2763 2872          ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2764 2873          ASSERT(cidp->impl_id.c_id >> CLUSTER_NODEID_SHIFT == 0);
2765 2874          clnodeid = clconf_get_nodeid();
2766 2875          ASSERT(clnodeid <= CLUSTER_MAX_NODEID);
2767 2876          ASSERT(clnodeid != NODEID_UNKNOWN);
2768 2877          cidp->impl_id.c_id |= (clnodeid << CLUSTER_NODEID_SHIFT);
2769 2878  }
2770 2879  
2771 2880  static uint32_t
2772 2881  state_hash(void *key)
2773 2882  {
2774 2883          stateid_t *ip = (stateid_t *)key;
2775 2884  
2776 2885          return (ip->bits.ident);
2777 2886  }
2778 2887  
2779 2888  static bool_t
2780 2889  state_compare(rfs4_entry_t u_entry, void *key)
2781 2890  {
2782 2891          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2783 2892          stateid_t *id = (stateid_t *)key;
2784 2893          bool_t rc;
2785 2894  
2786 2895          rc = (sp->rs_stateid.bits.boottime == id->bits.boottime &&
2787 2896              sp->rs_stateid.bits.ident == id->bits.ident);
2788 2897  
2789 2898          return (rc);
2790 2899  }
2791 2900  
2792 2901  static void *
2793 2902  state_mkkey(rfs4_entry_t u_entry)
2794 2903  {
2795 2904          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2796 2905  
2797 2906          return (&sp->rs_stateid);
2798 2907  }
2799 2908  
2800 2909  static void
2801 2910  rfs4_state_destroy(rfs4_entry_t u_entry)
2802 2911  {
2803 2912          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2804 2913  
2805 2914          /* remove from openowner list */
2806 2915          rfs4_dbe_lock(sp->rs_owner->ro_dbe);
2807 2916          list_remove(&sp->rs_owner->ro_statelist, sp);
2808 2917          rfs4_dbe_unlock(sp->rs_owner->ro_dbe);
2809 2918  
2810 2919          list_destroy(&sp->rs_lostatelist);
2811 2920  
2812 2921          /* release any share locks for this stateid if it's still open */
2813 2922          if (!sp->rs_closed) {
2814 2923                  rfs4_dbe_lock(sp->rs_dbe);
2815 2924                  (void) rfs4_unshare(sp);
2816 2925                  rfs4_dbe_unlock(sp->rs_dbe);
2817 2926          }
2818 2927  
2819 2928          /* Were done with the file */
2820 2929          rfs4_file_rele(sp->rs_finfo);
2821 2930          sp->rs_finfo = NULL;
2822 2931  
2823 2932          /* And now with the openowner */
2824 2933          rfs4_openowner_rele(sp->rs_owner);
2825 2934          sp->rs_owner = NULL;
2826 2935  }
2827 2936  
2828 2937  static void
2829 2938  rfs4_state_rele_nounlock(rfs4_state_t *sp)
2830 2939  {
2831 2940          rfs4_dbe_rele(sp->rs_dbe);
2832 2941  }
2833 2942  
2834 2943  void
2835 2944  rfs4_state_rele(rfs4_state_t *sp)
2836 2945  {
2837 2946          rw_exit(&sp->rs_finfo->rf_file_rwlock);
2838 2947          rfs4_dbe_rele(sp->rs_dbe);
2839 2948  }
2840 2949  
2841 2950  static uint32_t
2842 2951  deleg_hash(void *key)
2843 2952  {
2844 2953          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)key;
2845 2954  
2846 2955          return (ADDRHASH(dsp->rds_client) ^ ADDRHASH(dsp->rds_finfo));
2847 2956  }
2848 2957  
2849 2958  static bool_t
2850 2959  deleg_compare(rfs4_entry_t u_entry, void *key)
2851 2960  {
2852 2961          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2853 2962          rfs4_deleg_state_t *kdsp = (rfs4_deleg_state_t *)key;
2854 2963  
2855 2964          return (dsp->rds_client == kdsp->rds_client &&
2856 2965              dsp->rds_finfo == kdsp->rds_finfo);
2857 2966  }
2858 2967  
2859 2968  static void *
2860 2969  deleg_mkkey(rfs4_entry_t u_entry)
2861 2970  {
2862 2971          return (u_entry);
2863 2972  }
2864 2973  
2865 2974  static uint32_t
2866 2975  deleg_state_hash(void *key)
2867 2976  {
2868 2977          stateid_t *ip = (stateid_t *)key;
2869 2978  
2870 2979          return (ip->bits.ident);
2871 2980  }
2872 2981  
2873 2982  static bool_t
2874 2983  deleg_state_compare(rfs4_entry_t u_entry, void *key)
2875 2984  {
2876 2985          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2877 2986          stateid_t *id = (stateid_t *)key;
2878 2987          bool_t rc;
2879 2988  
2880 2989          if (id->bits.type != DELEGID)
2881 2990                  return (FALSE);
2882 2991  
2883 2992          rc = (dsp->rds_delegid.bits.boottime == id->bits.boottime &&
2884 2993              dsp->rds_delegid.bits.ident == id->bits.ident);
2885 2994  
2886 2995          return (rc);
2887 2996  }
2888 2997  
2889 2998  static void *
2890 2999  deleg_state_mkkey(rfs4_entry_t u_entry)
2891 3000  {
2892 3001          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2893 3002  
2894 3003          return (&dsp->rds_delegid);
2895 3004  }
2896 3005  
2897 3006  static bool_t
2898 3007  rfs4_deleg_state_expiry(rfs4_entry_t u_entry)
2899 3008  {
2900 3009          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2901 3010  
2902 3011          if (rfs4_dbe_is_invalid(dsp->rds_dbe))
2903 3012                  return (TRUE);
2904 3013  
2905 3014          if (dsp->rds_dtype == OPEN_DELEGATE_NONE)
2906 3015                  return (TRUE);
2907 3016  
2908 3017          if ((gethrestime_sec() - dsp->rds_client->rc_last_access
2909 3018              > rfs4_lease_time)) {
2910 3019                  rfs4_dbe_invalidate(dsp->rds_dbe);
2911 3020                  return (TRUE);
2912 3021          }
2913 3022  
2914 3023          return (FALSE);
2915 3024  }
2916 3025  
2917 3026  static bool_t
2918 3027  rfs4_deleg_state_create(rfs4_entry_t u_entry, void *argp)
2919 3028  {
2920 3029          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2921 3030          rfs4_file_t *fp = ((rfs4_deleg_state_t *)argp)->rds_finfo;
2922 3031          rfs4_client_t *cp = ((rfs4_deleg_state_t *)argp)->rds_client;
2923 3032  
2924 3033          rfs4_dbe_hold(fp->rf_dbe);
2925 3034          rfs4_dbe_hold(cp->rc_dbe);
2926 3035  
2927 3036          dsp->rds_delegid = get_stateid(rfs4_dbe_getid(dsp->rds_dbe));
2928 3037          dsp->rds_delegid.bits.type = DELEGID;
2929 3038          dsp->rds_finfo = fp;
2930 3039          dsp->rds_client = cp;
2931 3040          dsp->rds_dtype = OPEN_DELEGATE_NONE;
2932 3041  
2933 3042          dsp->rds_time_granted = gethrestime_sec();      /* observability */
2934 3043          dsp->rds_time_revoked = 0;
2935 3044  
2936 3045          list_link_init(&dsp->rds_node);
2937 3046  
2938 3047          return (TRUE);
2939 3048  }
2940 3049  
2941 3050  static void
2942 3051  rfs4_deleg_state_destroy(rfs4_entry_t u_entry)
2943 3052  {
2944 3053          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2945 3054  
2946 3055          /* return delegation if necessary */
2947 3056          rfs4_return_deleg(dsp, FALSE);
2948 3057  
2949 3058          /* Were done with the file */
2950 3059          rfs4_file_rele(dsp->rds_finfo);
2951 3060          dsp->rds_finfo = NULL;
  
    | 
      ↓ open down ↓ | 
    235 lines elided | 
    
      ↑ open up ↑ | 
  
2952 3061  
2953 3062          /* And now with the openowner */
2954 3063          rfs4_client_rele(dsp->rds_client);
2955 3064          dsp->rds_client = NULL;
2956 3065  }
2957 3066  
2958 3067  rfs4_deleg_state_t *
2959 3068  rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
2960 3069  {
2961 3070          rfs4_deleg_state_t ds, *dsp;
     3071 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2962 3072  
2963 3073          ds.rds_client = sp->rs_owner->ro_client;
2964 3074          ds.rds_finfo = sp->rs_finfo;
2965 3075  
2966      -        dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(rfs4_deleg_idx, &ds,
     3076 +        dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
2967 3077              create, &ds, RFS4_DBS_VALID);
2968 3078  
2969 3079          return (dsp);
2970 3080  }
2971 3081  
2972 3082  rfs4_deleg_state_t *
2973 3083  rfs4_finddelegstate(stateid_t *id)
2974 3084  {
2975 3085          rfs4_deleg_state_t *dsp;
2976 3086          bool_t create = FALSE;
     3087 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
2977 3088  
2978      -        dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(rfs4_deleg_state_idx, id,
2979      -            &create, NULL, RFS4_DBS_VALID);
     3089 +        dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
     3090 +            id, &create, NULL, RFS4_DBS_VALID);
2980 3091  
2981 3092          return (dsp);
2982 3093  }
2983 3094  
2984 3095  void
2985 3096  rfs4_deleg_state_rele(rfs4_deleg_state_t *dsp)
2986 3097  {
2987 3098          rfs4_dbe_rele(dsp->rds_dbe);
2988 3099  }
2989 3100  
2990 3101  void
2991 3102  rfs4_update_lock_sequence(rfs4_lo_state_t *lsp)
2992 3103  {
2993 3104  
2994 3105          rfs4_dbe_lock(lsp->rls_dbe);
2995 3106  
2996 3107          /*
2997 3108           * If we are skipping sequence id checking, this means that
2998 3109           * this is the first lock request and therefore the sequence
2999 3110           * id does not need to be updated.  This only happens on the
3000 3111           * first lock request for a lockowner
3001 3112           */
3002 3113          if (!lsp->rls_skip_seqid_check)
3003 3114                  lsp->rls_seqid++;
3004 3115  
3005 3116          rfs4_dbe_unlock(lsp->rls_dbe);
3006 3117  }
3007 3118  
3008 3119  void
3009 3120  rfs4_update_lock_resp(rfs4_lo_state_t *lsp, nfs_resop4 *resp)
3010 3121  {
3011 3122  
3012 3123          rfs4_dbe_lock(lsp->rls_dbe);
3013 3124  
3014 3125          rfs4_free_reply(&lsp->rls_reply);
3015 3126  
3016 3127          rfs4_copy_reply(&lsp->rls_reply, resp);
3017 3128  
3018 3129          rfs4_dbe_unlock(lsp->rls_dbe);
3019 3130  }
3020 3131  
3021 3132  void
3022 3133  rfs4_free_opens(rfs4_openowner_t *oo, bool_t invalidate,
3023 3134      bool_t close_of_client)
3024 3135  {
3025 3136          rfs4_state_t *sp;
3026 3137  
3027 3138          rfs4_dbe_lock(oo->ro_dbe);
3028 3139  
3029 3140          for (sp = list_head(&oo->ro_statelist); sp != NULL;
3030 3141              sp = list_next(&oo->ro_statelist, sp)) {
3031 3142                  rfs4_state_close(sp, FALSE, close_of_client, CRED());
3032 3143                  if (invalidate == TRUE)
3033 3144                          rfs4_dbe_invalidate(sp->rs_dbe);
3034 3145          }
3035 3146  
3036 3147          rfs4_dbe_invalidate(oo->ro_dbe);
3037 3148          rfs4_dbe_unlock(oo->ro_dbe);
3038 3149  }
3039 3150  
3040 3151  static uint32_t
3041 3152  state_owner_file_hash(void *key)
3042 3153  {
3043 3154          rfs4_state_t *sp = key;
3044 3155  
3045 3156          return (ADDRHASH(sp->rs_owner) ^ ADDRHASH(sp->rs_finfo));
3046 3157  }
3047 3158  
3048 3159  static bool_t
3049 3160  state_owner_file_compare(rfs4_entry_t u_entry, void *key)
3050 3161  {
3051 3162          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3052 3163          rfs4_state_t *arg = key;
3053 3164  
3054 3165          if (sp->rs_closed == TRUE)
3055 3166                  return (FALSE);
3056 3167  
3057 3168          return (arg->rs_owner == sp->rs_owner && arg->rs_finfo == sp->rs_finfo);
3058 3169  }
3059 3170  
3060 3171  static void *
3061 3172  state_owner_file_mkkey(rfs4_entry_t u_entry)
3062 3173  {
3063 3174          return (u_entry);
3064 3175  }
3065 3176  
3066 3177  static uint32_t
3067 3178  state_file_hash(void *key)
3068 3179  {
3069 3180          return (ADDRHASH(key));
3070 3181  }
3071 3182  
3072 3183  static bool_t
3073 3184  state_file_compare(rfs4_entry_t u_entry, void *key)
3074 3185  {
3075 3186          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3076 3187          rfs4_file_t *fp = key;
3077 3188  
3078 3189          if (sp->rs_closed == TRUE)
3079 3190                  return (FALSE);
3080 3191  
3081 3192          return (fp == sp->rs_finfo);
3082 3193  }
3083 3194  
  
    | 
      ↓ open down ↓ | 
    94 lines elided | 
    
      ↑ open up ↑ | 
  
3084 3195  static void *
3085 3196  state_file_mkkey(rfs4_entry_t u_entry)
3086 3197  {
3087 3198          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3088 3199  
3089 3200          return (sp->rs_finfo);
3090 3201  }
3091 3202  
3092 3203  rfs4_state_t *
3093 3204  rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
3094      -        bool_t *create)
     3205 +    bool_t *create)
3095 3206  {
3096 3207          rfs4_state_t *sp;
3097 3208          rfs4_state_t key;
     3209 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
3098 3210  
3099 3211          key.rs_owner = oo;
3100 3212          key.rs_finfo = fp;
3101 3213  
3102      -        sp = (rfs4_state_t *)rfs4_dbsearch(rfs4_state_owner_file_idx, &key,
3103      -            create, &key, RFS4_DBS_VALID);
     3214 +        sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
     3215 +            &key, create, &key, RFS4_DBS_VALID);
3104 3216  
3105 3217          return (sp);
3106 3218  }
3107 3219  
3108 3220  /* This returns ANY state struct that refers to this file */
3109 3221  static rfs4_state_t *
3110 3222  rfs4_findstate_by_file(rfs4_file_t *fp)
3111 3223  {
3112 3224          bool_t create = FALSE;
     3225 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
3113 3226  
3114      -        return ((rfs4_state_t *)rfs4_dbsearch(rfs4_state_file_idx, fp,
     3227 +        return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
3115 3228              &create, fp, RFS4_DBS_VALID));
3116 3229  }
3117 3230  
3118 3231  static bool_t
3119 3232  rfs4_state_expiry(rfs4_entry_t u_entry)
3120 3233  {
3121 3234          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3122 3235  
3123 3236          if (rfs4_dbe_is_invalid(sp->rs_dbe))
3124 3237                  return (TRUE);
3125 3238  
3126 3239          if (sp->rs_closed == TRUE &&
3127 3240              ((gethrestime_sec() - rfs4_dbe_get_timerele(sp->rs_dbe))
3128 3241              > rfs4_lease_time))
3129 3242                  return (TRUE);
3130 3243  
3131 3244          return ((gethrestime_sec() - sp->rs_owner->ro_client->rc_last_access
3132 3245              > rfs4_lease_time));
3133 3246  }
3134 3247  
3135 3248  static bool_t
3136 3249  rfs4_state_create(rfs4_entry_t u_entry, void *argp)
3137 3250  {
3138 3251          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3139 3252          rfs4_file_t *fp = ((rfs4_state_t *)argp)->rs_finfo;
3140 3253          rfs4_openowner_t *oo = ((rfs4_state_t *)argp)->rs_owner;
3141 3254  
3142 3255          rfs4_dbe_hold(fp->rf_dbe);
3143 3256          rfs4_dbe_hold(oo->ro_dbe);
3144 3257          sp->rs_stateid = get_stateid(rfs4_dbe_getid(sp->rs_dbe));
3145 3258          sp->rs_stateid.bits.type = OPENID;
3146 3259          sp->rs_owner = oo;
3147 3260          sp->rs_finfo = fp;
3148 3261  
3149 3262          list_create(&sp->rs_lostatelist, sizeof (rfs4_lo_state_t),
3150 3263              offsetof(rfs4_lo_state_t, rls_node));
3151 3264  
3152 3265          /* Insert state on per open owner's list */
3153 3266          rfs4_dbe_lock(oo->ro_dbe);
3154 3267          list_insert_tail(&oo->ro_statelist, sp);
  
    | 
      ↓ open down ↓ | 
    30 lines elided | 
    
      ↑ open up ↑ | 
  
3155 3268          rfs4_dbe_unlock(oo->ro_dbe);
3156 3269  
3157 3270          return (TRUE);
3158 3271  }
3159 3272  
3160 3273  static rfs4_state_t *
3161 3274  rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3162 3275  {
3163 3276          rfs4_state_t *sp;
3164 3277          bool_t create = FALSE;
     3278 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
3165 3279  
3166      -        sp = (rfs4_state_t *)rfs4_dbsearch(rfs4_state_idx, id,
     3280 +        sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
3167 3281              &create, NULL, find_invalid);
3168 3282          if (lock_fp == TRUE && sp != NULL)
3169 3283                  rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
3170 3284  
3171 3285          return (sp);
3172 3286  }
3173 3287  
3174 3288  void
3175 3289  rfs4_state_close(rfs4_state_t *sp, bool_t lock_held, bool_t close_of_client,
3176 3290      cred_t *cr)
3177 3291  {
3178 3292          /* Remove the associated lo_state owners */
3179 3293          if (!lock_held)
3180 3294                  rfs4_dbe_lock(sp->rs_dbe);
3181 3295  
3182 3296          /*
3183 3297           * If refcnt == 0, the dbe is about to be destroyed.
3184 3298           * lock state will be released by the reaper thread.
3185 3299           */
3186 3300  
3187 3301          if (rfs4_dbe_refcnt(sp->rs_dbe) > 0) {
3188 3302                  if (sp->rs_closed == FALSE) {
3189 3303                          rfs4_release_share_lock_state(sp, cr, close_of_client);
3190 3304                          sp->rs_closed = TRUE;
3191 3305                  }
3192 3306          }
3193 3307  
3194 3308          if (!lock_held)
3195 3309                  rfs4_dbe_unlock(sp->rs_dbe);
3196 3310  }
3197 3311  
3198 3312  /*
3199 3313   * Remove all state associated with the given client.
3200 3314   */
3201 3315  void
3202 3316  rfs4_client_state_remove(rfs4_client_t *cp)
3203 3317  {
3204 3318          rfs4_openowner_t *oo;
3205 3319  
3206 3320          rfs4_dbe_lock(cp->rc_dbe);
3207 3321  
3208 3322          for (oo = list_head(&cp->rc_openownerlist); oo != NULL;
3209 3323              oo = list_next(&cp->rc_openownerlist, oo)) {
3210 3324                  rfs4_free_opens(oo, TRUE, TRUE);
3211 3325          }
3212 3326  
3213 3327          rfs4_dbe_unlock(cp->rc_dbe);
3214 3328  }
3215 3329  
3216 3330  void
3217 3331  rfs4_client_close(rfs4_client_t *cp)
3218 3332  {
3219 3333          /* Mark client as going away. */
3220 3334          rfs4_dbe_lock(cp->rc_dbe);
3221 3335          rfs4_dbe_invalidate(cp->rc_dbe);
3222 3336          rfs4_dbe_unlock(cp->rc_dbe);
3223 3337  
  
    | 
      ↓ open down ↓ | 
    47 lines elided | 
    
      ↑ open up ↑ | 
  
3224 3338          rfs4_client_state_remove(cp);
3225 3339  
3226 3340          /* Release the client */
3227 3341          rfs4_client_rele(cp);
3228 3342  }
3229 3343  
3230 3344  nfsstat4
3231 3345  rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
3232 3346  {
3233 3347          cid *cidp = (cid *) cp;
     3348 +        nfs4_srv_t *nsrv4;
3234 3349  
     3350 +        nsrv4 = nfs4_get_srv();
     3351 +
3235 3352          /*
3236 3353           * If we are booted as a cluster node, check the embedded nodeid.
3237 3354           * If it indicates that this clientid was generated on another node,
3238 3355           * inform the client accordingly.
3239 3356           */
3240 3357          if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
3241 3358                  return (NFS4ERR_STALE_CLIENTID);
3242 3359  
3243 3360          /*
3244 3361           * If the server start time matches the time provided
3245 3362           * by the client (via the clientid) and this is NOT a
3246 3363           * setclientid_confirm then return EXPIRED.
3247 3364           */
3248      -        if (!setclid_confirm && cidp->impl_id.start_time == rfs4_start_time)
     3365 +        if (!setclid_confirm &&
     3366 +            cidp->impl_id.start_time == nsrv4->rfs4_start_time)
3249 3367                  return (NFS4ERR_EXPIRED);
3250 3368  
3251 3369          return (NFS4ERR_STALE_CLIENTID);
3252 3370  }
3253 3371  
3254 3372  /*
3255 3373   * This is used when a stateid has not been found amongst the
3256 3374   * current server's state.  Check the stateid to see if it
3257 3375   * was from this server instantiation or not.
3258 3376   */
3259 3377  static nfsstat4
3260 3378  what_stateid_error(stateid_t *id, stateid_type_t type)
3261 3379  {
     3380 +        nfs4_srv_t *nsrv4;
     3381 +
     3382 +        nsrv4 = nfs4_get_srv();
     3383 +
3262 3384          /* If we are booted as a cluster node, was stateid locally generated? */
3263 3385          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3264 3386                  return (NFS4ERR_STALE_STATEID);
3265 3387  
3266 3388          /* If types don't match then no use checking further */
3267 3389          if (type != id->bits.type)
3268 3390                  return (NFS4ERR_BAD_STATEID);
3269 3391  
3270 3392          /* From a different server instantiation, return STALE */
3271      -        if (id->bits.boottime != rfs4_start_time)
     3393 +        if (id->bits.boottime != nsrv4->rfs4_start_time)
3272 3394                  return (NFS4ERR_STALE_STATEID);
3273 3395  
3274 3396          /*
3275 3397           * From this server but the state is most likely beyond lease
3276 3398           * timeout: return NFS4ERR_EXPIRED.  However, there is the
3277 3399           * case of a delegation stateid.  For delegations, there is a
3278 3400           * case where the state can be removed without the client's
3279 3401           * knowledge/consent: revocation.  In the case of delegation
3280 3402           * revocation, the delegation state will be removed and will
3281 3403           * not be found.  If the client does something like a
3282 3404           * DELEGRETURN or even a READ/WRITE with a delegatoin stateid
3283 3405           * that has been revoked, the server should return BAD_STATEID
3284 3406           * instead of the more common EXPIRED error.
3285 3407           */
3286      -        if (id->bits.boottime == rfs4_start_time) {
     3408 +        if (id->bits.boottime == nsrv4->rfs4_start_time) {
3287 3409                  if (type == DELEGID)
3288 3410                          return (NFS4ERR_BAD_STATEID);
3289 3411                  else
3290 3412                          return (NFS4ERR_EXPIRED);
3291 3413          }
3292 3414  
3293 3415          return (NFS4ERR_BAD_STATEID);
3294 3416  }
3295 3417  
3296 3418  /*
3297 3419   * Used later on to find the various state structs.  When called from
3298 3420   * rfs4_check_stateid()->rfs4_get_all_state(), no file struct lock is
3299 3421   * taken (it is not needed) and helps on the read/write path with
3300 3422   * respect to performance.
3301 3423   */
3302 3424  static nfsstat4
3303 3425  rfs4_get_state_lockit(stateid4 *stateid, rfs4_state_t **spp,
3304 3426      rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3305 3427  {
3306 3428          stateid_t *id = (stateid_t *)stateid;
3307 3429          rfs4_state_t *sp;
3308 3430  
3309 3431          *spp = NULL;
3310 3432  
3311 3433          /* If we are booted as a cluster node, was stateid locally generated? */
3312 3434          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3313 3435                  return (NFS4ERR_STALE_STATEID);
3314 3436  
3315 3437          sp = rfs4_findstate(id, find_invalid, lock_fp);
3316 3438          if (sp == NULL) {
3317 3439                  return (what_stateid_error(id, OPENID));
3318 3440          }
3319 3441  
3320 3442          if (rfs4_lease_expired(sp->rs_owner->ro_client)) {
3321 3443                  if (lock_fp == TRUE)
3322 3444                          rfs4_state_rele(sp);
3323 3445                  else
3324 3446                          rfs4_state_rele_nounlock(sp);
3325 3447                  return (NFS4ERR_EXPIRED);
3326 3448          }
3327 3449  
3328 3450          *spp = sp;
3329 3451  
3330 3452          return (NFS4_OK);
3331 3453  }
3332 3454  
3333 3455  nfsstat4
3334 3456  rfs4_get_state(stateid4 *stateid, rfs4_state_t **spp,
3335 3457      rfs4_dbsearch_type_t find_invalid)
3336 3458  {
3337 3459          return (rfs4_get_state_lockit(stateid, spp, find_invalid, TRUE));
3338 3460  }
3339 3461  
3340 3462  int
3341 3463  rfs4_check_stateid_seqid(rfs4_state_t *sp, stateid4 *stateid)
3342 3464  {
3343 3465          stateid_t *id = (stateid_t *)stateid;
3344 3466  
3345 3467          if (rfs4_lease_expired(sp->rs_owner->ro_client))
3346 3468                  return (NFS4_CHECK_STATEID_EXPIRED);
3347 3469  
3348 3470          /* Stateid is some time in the future - that's bad */
3349 3471          if (sp->rs_stateid.bits.chgseq < id->bits.chgseq)
3350 3472                  return (NFS4_CHECK_STATEID_BAD);
3351 3473  
3352 3474          if (sp->rs_stateid.bits.chgseq == id->bits.chgseq + 1)
3353 3475                  return (NFS4_CHECK_STATEID_REPLAY);
3354 3476  
3355 3477          /* Stateid is some time in the past - that's old */
3356 3478          if (sp->rs_stateid.bits.chgseq > id->bits.chgseq)
3357 3479                  return (NFS4_CHECK_STATEID_OLD);
3358 3480  
3359 3481          /* Caller needs to know about confirmation before closure */
3360 3482          if (sp->rs_owner->ro_need_confirm)
3361 3483                  return (NFS4_CHECK_STATEID_UNCONFIRMED);
3362 3484  
3363 3485          if (sp->rs_closed == TRUE)
3364 3486                  return (NFS4_CHECK_STATEID_CLOSED);
3365 3487  
3366 3488          return (NFS4_CHECK_STATEID_OKAY);
3367 3489  }
3368 3490  
3369 3491  int
3370 3492  rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *lsp, stateid4 *stateid)
3371 3493  {
3372 3494          stateid_t *id = (stateid_t *)stateid;
3373 3495  
3374 3496          if (rfs4_lease_expired(lsp->rls_state->rs_owner->ro_client))
3375 3497                  return (NFS4_CHECK_STATEID_EXPIRED);
3376 3498  
3377 3499          /* Stateid is some time in the future - that's bad */
3378 3500          if (lsp->rls_lockid.bits.chgseq < id->bits.chgseq)
3379 3501                  return (NFS4_CHECK_STATEID_BAD);
3380 3502  
3381 3503          if (lsp->rls_lockid.bits.chgseq == id->bits.chgseq + 1)
3382 3504                  return (NFS4_CHECK_STATEID_REPLAY);
3383 3505  
3384 3506          /* Stateid is some time in the past - that's old */
3385 3507          if (lsp->rls_lockid.bits.chgseq > id->bits.chgseq)
3386 3508                  return (NFS4_CHECK_STATEID_OLD);
3387 3509  
3388 3510          if (lsp->rls_state->rs_closed == TRUE)
3389 3511                  return (NFS4_CHECK_STATEID_CLOSED);
3390 3512  
3391 3513          return (NFS4_CHECK_STATEID_OKAY);
3392 3514  }
3393 3515  
3394 3516  nfsstat4
3395 3517  rfs4_get_deleg_state(stateid4 *stateid, rfs4_deleg_state_t **dspp)
3396 3518  {
3397 3519          stateid_t *id = (stateid_t *)stateid;
3398 3520          rfs4_deleg_state_t *dsp;
3399 3521  
3400 3522          *dspp = NULL;
3401 3523  
3402 3524          /* If we are booted as a cluster node, was stateid locally generated? */
3403 3525          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3404 3526                  return (NFS4ERR_STALE_STATEID);
3405 3527  
3406 3528          dsp = rfs4_finddelegstate(id);
3407 3529          if (dsp == NULL) {
3408 3530                  return (what_stateid_error(id, DELEGID));
3409 3531          }
3410 3532  
3411 3533          if (rfs4_lease_expired(dsp->rds_client)) {
3412 3534                  rfs4_deleg_state_rele(dsp);
3413 3535                  return (NFS4ERR_EXPIRED);
3414 3536          }
3415 3537  
3416 3538          *dspp = dsp;
3417 3539  
3418 3540          return (NFS4_OK);
3419 3541  }
3420 3542  
3421 3543  nfsstat4
3422 3544  rfs4_get_lo_state(stateid4 *stateid, rfs4_lo_state_t **lspp, bool_t lock_fp)
3423 3545  {
3424 3546          stateid_t *id = (stateid_t *)stateid;
3425 3547          rfs4_lo_state_t *lsp;
3426 3548  
3427 3549          *lspp = NULL;
3428 3550  
3429 3551          /* If we are booted as a cluster node, was stateid locally generated? */
3430 3552          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3431 3553                  return (NFS4ERR_STALE_STATEID);
3432 3554  
3433 3555          lsp = rfs4_findlo_state(id, lock_fp);
3434 3556          if (lsp == NULL) {
3435 3557                  return (what_stateid_error(id, LOCKID));
3436 3558          }
3437 3559  
3438 3560          if (rfs4_lease_expired(lsp->rls_state->rs_owner->ro_client)) {
3439 3561                  rfs4_lo_state_rele(lsp, lock_fp);
3440 3562                  return (NFS4ERR_EXPIRED);
3441 3563          }
3442 3564  
3443 3565          *lspp = lsp;
3444 3566  
3445 3567          return (NFS4_OK);
3446 3568  }
3447 3569  
3448 3570  static nfsstat4
3449 3571  rfs4_get_all_state(stateid4 *sid, rfs4_state_t **spp,
3450 3572      rfs4_deleg_state_t **dspp, rfs4_lo_state_t **lspp)
3451 3573  {
3452 3574          rfs4_state_t *sp = NULL;
3453 3575          rfs4_deleg_state_t *dsp = NULL;
3454 3576          rfs4_lo_state_t *lsp = NULL;
3455 3577          stateid_t *id;
3456 3578          nfsstat4 status;
3457 3579  
3458 3580          *spp = NULL; *dspp = NULL; *lspp = NULL;
3459 3581  
3460 3582          id = (stateid_t *)sid;
3461 3583          switch (id->bits.type) {
3462 3584          case OPENID:
3463 3585                  status = rfs4_get_state_lockit(sid, &sp, FALSE, FALSE);
3464 3586                  break;
3465 3587          case DELEGID:
3466 3588                  status = rfs4_get_deleg_state(sid, &dsp);
3467 3589                  break;
3468 3590          case LOCKID:
3469 3591                  status = rfs4_get_lo_state(sid, &lsp, FALSE);
3470 3592                  if (status == NFS4_OK) {
3471 3593                          sp = lsp->rls_state;
3472 3594                          rfs4_dbe_hold(sp->rs_dbe);
3473 3595                  }
3474 3596                  break;
3475 3597          default:
3476 3598                  status = NFS4ERR_BAD_STATEID;
3477 3599          }
3478 3600  
3479 3601          if (status == NFS4_OK) {
3480 3602                  *spp = sp;
3481 3603                  *dspp = dsp;
3482 3604                  *lspp = lsp;
3483 3605          }
3484 3606  
3485 3607          return (status);
3486 3608  }
3487 3609  
3488 3610  /*
3489 3611   * Given the I/O mode (FREAD or FWRITE), this checks whether the
3490 3612   * rfs4_state_t struct has access to do this operation and if so
3491 3613   * return NFS4_OK; otherwise the proper NFSv4 error is returned.
3492 3614   */
3493 3615  nfsstat4
3494 3616  rfs4_state_has_access(rfs4_state_t *sp, int mode, vnode_t *vp)
3495 3617  {
3496 3618          nfsstat4 stat = NFS4_OK;
3497 3619          rfs4_file_t *fp;
3498 3620          bool_t create = FALSE;
3499 3621  
3500 3622          rfs4_dbe_lock(sp->rs_dbe);
3501 3623          if (mode == FWRITE) {
3502 3624                  if (!(sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE)) {
3503 3625                          stat = NFS4ERR_OPENMODE;
3504 3626                  }
3505 3627          } else if (mode == FREAD) {
3506 3628                  if (!(sp->rs_share_access & OPEN4_SHARE_ACCESS_READ)) {
3507 3629                          /*
3508 3630                           * If we have OPENed the file with DENYing access
3509 3631                           * to both READ and WRITE then no one else could
3510 3632                           * have OPENed the file, hence no conflicting READ
3511 3633                           * deny.  This check is merely an optimization.
3512 3634                           */
3513 3635                          if (sp->rs_share_deny == OPEN4_SHARE_DENY_BOTH)
3514 3636                                  goto out;
3515 3637  
3516 3638                          /* Check against file struct's DENY mode */
3517 3639                          fp = rfs4_findfile(vp, NULL, &create);
3518 3640                          if (fp != NULL) {
3519 3641                                  int deny_read = 0;
3520 3642                                  rfs4_dbe_lock(fp->rf_dbe);
3521 3643                                  /*
3522 3644                                   * Check if any other open owner has the file
3523 3645                                   * OPENed with deny READ.
3524 3646                                   */
3525 3647                                  if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ)
3526 3648                                          deny_read = 1;
3527 3649                                  ASSERT(fp->rf_deny_read >= deny_read);
3528 3650                                  if (fp->rf_deny_read > deny_read)
3529 3651                                          stat = NFS4ERR_OPENMODE;
3530 3652                                  rfs4_dbe_unlock(fp->rf_dbe);
3531 3653                                  rfs4_file_rele(fp);
3532 3654                          }
3533 3655                  }
3534 3656          } else {
3535 3657                  /* Illegal I/O mode */
3536 3658                  stat = NFS4ERR_INVAL;
3537 3659          }
3538 3660  out:
3539 3661          rfs4_dbe_unlock(sp->rs_dbe);
3540 3662          return (stat);
3541 3663  }
3542 3664  
3543 3665  /*
3544 3666   * Given the I/O mode (FREAD or FWRITE), the vnode, the stateid and whether
3545 3667   * the file is being truncated, return NFS4_OK if allowed or appropriate
3546 3668   * V4 error if not. Note NFS4ERR_DELAY will be returned and a recall on
3547 3669   * the associated file will be done if the I/O is not consistent with any
3548 3670   * delegation in effect on the file. Should be holding VOP_RWLOCK, either
3549 3671   * as reader or writer as appropriate. rfs4_op_open will acquire the
3550 3672   * VOP_RWLOCK as writer when setting up delegation. If the stateid is bad
3551 3673   * this routine will return NFS4ERR_BAD_STATEID. In addition, through the
3552 3674   * deleg parameter, we will return whether a write delegation is held by
3553 3675   * the client associated with this stateid.
3554 3676   * If the server instance associated with the relevant client is in its
3555 3677   * grace period, return NFS4ERR_GRACE.
3556 3678   */
3557 3679  
3558 3680  nfsstat4
3559 3681  rfs4_check_stateid(int mode, vnode_t *vp,
3560 3682      stateid4 *stateid, bool_t trunc, bool_t *deleg,
3561 3683      bool_t do_access, caller_context_t *ct)
3562 3684  {
3563 3685          rfs4_file_t *fp;
3564 3686          bool_t create = FALSE;
3565 3687          rfs4_state_t *sp;
3566 3688          rfs4_deleg_state_t *dsp;
3567 3689          rfs4_lo_state_t *lsp;
3568 3690          stateid_t *id = (stateid_t *)stateid;
3569 3691          nfsstat4 stat = NFS4_OK;
3570 3692  
3571 3693          if (ct != NULL) {
3572 3694                  ct->cc_sysid = 0;
3573 3695                  ct->cc_pid = 0;
3574 3696                  ct->cc_caller_id = nfs4_srv_caller_id;
3575 3697                  ct->cc_flags = CC_DONTBLOCK;
3576 3698          }
3577 3699  
3578 3700          if (ISSPECIAL(stateid)) {
3579 3701                  fp = rfs4_findfile(vp, NULL, &create);
3580 3702                  if (fp == NULL)
3581 3703                          return (NFS4_OK);
3582 3704                  if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_NONE) {
3583 3705                          rfs4_file_rele(fp);
3584 3706                          return (NFS4_OK);
3585 3707                  }
3586 3708                  if (mode == FWRITE ||
3587 3709                      fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_WRITE) {
3588 3710                          rfs4_recall_deleg(fp, trunc, NULL);
3589 3711                          rfs4_file_rele(fp);
3590 3712                          return (NFS4ERR_DELAY);
3591 3713                  }
3592 3714                  rfs4_file_rele(fp);
3593 3715                  return (NFS4_OK);
3594 3716          } else {
3595 3717                  stat = rfs4_get_all_state(stateid, &sp, &dsp, &lsp);
3596 3718                  if (stat != NFS4_OK)
3597 3719                          return (stat);
3598 3720                  if (lsp != NULL) {
3599 3721                          /* Is associated server instance in its grace period? */
3600 3722                          if (rfs4_clnt_in_grace(lsp->rls_locker->rl_client)) {
3601 3723                                  rfs4_lo_state_rele(lsp, FALSE);
3602 3724                                  if (sp != NULL)
3603 3725                                          rfs4_state_rele_nounlock(sp);
3604 3726                                  return (NFS4ERR_GRACE);
3605 3727                          }
3606 3728                          if (id->bits.type == LOCKID) {
3607 3729                                  /* Seqid in the future? - that's bad */
3608 3730                                  if (lsp->rls_lockid.bits.chgseq <
3609 3731                                      id->bits.chgseq) {
3610 3732                                          rfs4_lo_state_rele(lsp, FALSE);
3611 3733                                          if (sp != NULL)
3612 3734                                                  rfs4_state_rele_nounlock(sp);
3613 3735                                          return (NFS4ERR_BAD_STATEID);
3614 3736                                  }
3615 3737                                  /* Seqid in the past? - that's old */
3616 3738                                  if (lsp->rls_lockid.bits.chgseq >
3617 3739                                      id->bits.chgseq) {
3618 3740                                          rfs4_lo_state_rele(lsp, FALSE);
3619 3741                                          if (sp != NULL)
3620 3742                                                  rfs4_state_rele_nounlock(sp);
3621 3743                                          return (NFS4ERR_OLD_STATEID);
3622 3744                                  }
3623 3745                                  /* Ensure specified filehandle matches */
3624 3746                                  if (lsp->rls_state->rs_finfo->rf_vp != vp) {
3625 3747                                          rfs4_lo_state_rele(lsp, FALSE);
3626 3748                                          if (sp != NULL)
3627 3749                                                  rfs4_state_rele_nounlock(sp);
3628 3750                                          return (NFS4ERR_BAD_STATEID);
3629 3751                                  }
3630 3752                          }
3631 3753                          if (ct != NULL) {
3632 3754                                  ct->cc_sysid =
3633 3755                                      lsp->rls_locker->rl_client->rc_sysidt;
3634 3756                                  ct->cc_pid = lsp->rls_locker->rl_pid;
3635 3757                          }
3636 3758                          rfs4_lo_state_rele(lsp, FALSE);
3637 3759                  }
3638 3760  
3639 3761                  /* Stateid provided was an "open" stateid */
3640 3762                  if (sp != NULL) {
3641 3763                          /* Is associated server instance in its grace period? */
3642 3764                          if (rfs4_clnt_in_grace(sp->rs_owner->ro_client)) {
3643 3765                                  rfs4_state_rele_nounlock(sp);
3644 3766                                  return (NFS4ERR_GRACE);
3645 3767                          }
3646 3768                          if (id->bits.type == OPENID) {
3647 3769                                  /* Seqid in the future? - that's bad */
3648 3770                                  if (sp->rs_stateid.bits.chgseq <
3649 3771                                      id->bits.chgseq) {
3650 3772                                          rfs4_state_rele_nounlock(sp);
3651 3773                                          return (NFS4ERR_BAD_STATEID);
3652 3774                                  }
3653 3775                                  /* Seqid in the past - that's old */
3654 3776                                  if (sp->rs_stateid.bits.chgseq >
3655 3777                                      id->bits.chgseq) {
3656 3778                                          rfs4_state_rele_nounlock(sp);
3657 3779                                          return (NFS4ERR_OLD_STATEID);
3658 3780                                  }
3659 3781                          }
3660 3782                          /* Ensure specified filehandle matches */
3661 3783                          if (sp->rs_finfo->rf_vp != vp) {
3662 3784                                  rfs4_state_rele_nounlock(sp);
3663 3785                                  return (NFS4ERR_BAD_STATEID);
3664 3786                          }
3665 3787  
3666 3788                          if (sp->rs_owner->ro_need_confirm) {
3667 3789                                  rfs4_state_rele_nounlock(sp);
3668 3790                                  return (NFS4ERR_BAD_STATEID);
3669 3791                          }
3670 3792  
3671 3793                          if (sp->rs_closed == TRUE) {
3672 3794                                  rfs4_state_rele_nounlock(sp);
3673 3795                                  return (NFS4ERR_OLD_STATEID);
3674 3796                          }
3675 3797  
3676 3798                          if (do_access)
3677 3799                                  stat = rfs4_state_has_access(sp, mode, vp);
3678 3800                          else
3679 3801                                  stat = NFS4_OK;
3680 3802  
3681 3803                          /*
3682 3804                           * Return whether this state has write
3683 3805                           * delegation if desired
3684 3806                           */
3685 3807                          if (deleg && (sp->rs_finfo->rf_dinfo.rd_dtype ==
3686 3808                              OPEN_DELEGATE_WRITE))
3687 3809                                  *deleg = TRUE;
3688 3810  
3689 3811                          /*
3690 3812                           * We got a valid stateid, so we update the
3691 3813                           * lease on the client. Ideally we would like
3692 3814                           * to do this after the calling op succeeds,
3693 3815                           * but for now this will be good
3694 3816                           * enough. Callers of this routine are
3695 3817                           * currently insulated from the state stuff.
3696 3818                           */
3697 3819                          rfs4_update_lease(sp->rs_owner->ro_client);
3698 3820  
3699 3821                          /*
3700 3822                           * If a delegation is present on this file and
3701 3823                           * this is a WRITE, then update the lastwrite
3702 3824                           * time to indicate that activity is present.
3703 3825                           */
3704 3826                          if (sp->rs_finfo->rf_dinfo.rd_dtype ==
3705 3827                              OPEN_DELEGATE_WRITE &&
3706 3828                              mode == FWRITE) {
3707 3829                                  sp->rs_finfo->rf_dinfo.rd_time_lastwrite =
3708 3830                                      gethrestime_sec();
3709 3831                          }
3710 3832  
3711 3833                          rfs4_state_rele_nounlock(sp);
3712 3834  
3713 3835                          return (stat);
3714 3836                  }
3715 3837  
3716 3838                  if (dsp != NULL) {
3717 3839                          /* Is associated server instance in its grace period? */
3718 3840                          if (rfs4_clnt_in_grace(dsp->rds_client)) {
3719 3841                                  rfs4_deleg_state_rele(dsp);
3720 3842                                  return (NFS4ERR_GRACE);
3721 3843                          }
3722 3844                          if (dsp->rds_delegid.bits.chgseq != id->bits.chgseq) {
3723 3845                                  rfs4_deleg_state_rele(dsp);
3724 3846                                  return (NFS4ERR_BAD_STATEID);
3725 3847                          }
3726 3848  
3727 3849                          /* Ensure specified filehandle matches */
3728 3850                          if (dsp->rds_finfo->rf_vp != vp) {
3729 3851                                  rfs4_deleg_state_rele(dsp);
3730 3852                                  return (NFS4ERR_BAD_STATEID);
3731 3853                          }
3732 3854                          /*
3733 3855                           * Return whether this state has write
3734 3856                           * delegation if desired
3735 3857                           */
3736 3858                          if (deleg && (dsp->rds_finfo->rf_dinfo.rd_dtype ==
3737 3859                              OPEN_DELEGATE_WRITE))
3738 3860                                  *deleg = TRUE;
3739 3861  
3740 3862                          rfs4_update_lease(dsp->rds_client);
3741 3863  
3742 3864                          /*
3743 3865                           * If a delegation is present on this file and
3744 3866                           * this is a WRITE, then update the lastwrite
3745 3867                           * time to indicate that activity is present.
3746 3868                           */
3747 3869                          if (dsp->rds_finfo->rf_dinfo.rd_dtype ==
3748 3870                              OPEN_DELEGATE_WRITE && mode == FWRITE) {
3749 3871                                  dsp->rds_finfo->rf_dinfo.rd_time_lastwrite =
3750 3872                                      gethrestime_sec();
3751 3873                          }
3752 3874  
3753 3875                          /*
3754 3876                           * XXX - what happens if this is a WRITE and the
3755 3877                           * delegation type of for READ.
3756 3878                           */
3757 3879                          rfs4_deleg_state_rele(dsp);
3758 3880  
3759 3881                          return (stat);
3760 3882                  }
3761 3883                  /*
3762 3884                   * If we got this far, something bad happened
3763 3885                   */
3764 3886                  return (NFS4ERR_BAD_STATEID);
3765 3887          }
3766 3888  }
3767 3889  
3768 3890  
3769 3891  /*
3770 3892   * This is a special function in that for the file struct provided the
3771 3893   * server wants to remove/close all current state associated with the
3772 3894   * file.  The prime use of this would be with OP_REMOVE to force the
3773 3895   * release of state and particularly of file locks.
3774 3896   *
3775 3897   * There is an assumption that there is no delegations outstanding on
3776 3898   * this file at this point.  The caller should have waited for those
3777 3899   * to be returned or revoked.
  
    | 
      ↓ open down ↓ | 
    481 lines elided | 
    
      ↑ open up ↑ | 
  
3778 3900   */
3779 3901  void
3780 3902  rfs4_close_all_state(rfs4_file_t *fp)
3781 3903  {
3782 3904          rfs4_state_t *sp;
3783 3905  
3784 3906          rfs4_dbe_lock(fp->rf_dbe);
3785 3907  
3786 3908  #ifdef DEBUG
3787 3909          /* only applies when server is handing out delegations */
3788      -        if (rfs4_deleg_policy != SRV_NEVER_DELEGATE)
     3910 +        if (nfs4_get_deleg_policy() != SRV_NEVER_DELEGATE)
3789 3911                  ASSERT(fp->rf_dinfo.rd_hold_grant > 0);
3790 3912  #endif
3791 3913  
3792 3914          /* No delegations for this file */
3793 3915          ASSERT(list_is_empty(&fp->rf_delegstatelist));
3794 3916  
3795 3917          /* Make sure that it can not be found */
3796 3918          rfs4_dbe_invalidate(fp->rf_dbe);
3797 3919  
3798 3920          if (fp->rf_vp == NULL) {
3799 3921                  rfs4_dbe_unlock(fp->rf_dbe);
3800 3922                  return;
3801 3923          }
3802 3924          rfs4_dbe_unlock(fp->rf_dbe);
3803 3925  
3804 3926          /*
3805 3927           * Hold as writer to prevent other server threads from
3806 3928           * processing requests related to the file while all state is
3807 3929           * being removed.
3808 3930           */
3809 3931          rw_enter(&fp->rf_file_rwlock, RW_WRITER);
3810 3932  
3811 3933          /* Remove ALL state from the file */
3812 3934          while (sp = rfs4_findstate_by_file(fp)) {
3813 3935                  rfs4_state_close(sp, FALSE, FALSE, CRED());
3814 3936                  rfs4_state_rele_nounlock(sp);
3815 3937          }
3816 3938  
3817 3939          /*
3818 3940           * This is only safe since there are no further references to
3819 3941           * the file.
3820 3942           */
3821 3943          rfs4_dbe_lock(fp->rf_dbe);
3822 3944          if (fp->rf_vp) {
3823 3945                  vnode_t *vp = fp->rf_vp;
3824 3946  
3825 3947                  mutex_enter(&vp->v_vsd_lock);
3826 3948                  (void) vsd_set(vp, nfs4_srv_vkey, NULL);
3827 3949                  mutex_exit(&vp->v_vsd_lock);
3828 3950                  VN_RELE(vp);
3829 3951                  fp->rf_vp = NULL;
3830 3952          }
3831 3953          rfs4_dbe_unlock(fp->rf_dbe);
3832 3954  
3833 3955          /* Finally let other references to proceed */
3834 3956          rw_exit(&fp->rf_file_rwlock);
3835 3957  }
3836 3958  
3837 3959  /*
3838 3960   * This function is used as a target for the rfs4_dbe_walk() call
3839 3961   * below.  The purpose of this function is to see if the
3840 3962   * lockowner_state refers to a file that resides within the exportinfo
3841 3963   * export.  If so, then remove the lock_owner state (file locks and
3842 3964   * share "locks") for this object since the intent is the server is
3843 3965   * unexporting the specified directory.  Be sure to invalidate the
3844 3966   * object after the state has been released
3845 3967   */
3846 3968  static void
3847 3969  rfs4_lo_state_walk_callout(rfs4_entry_t u_entry, void *e)
3848 3970  {
3849 3971          rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
3850 3972          struct exportinfo *exi = (struct exportinfo *)e;
3851 3973          nfs_fh4_fmt_t   fhfmt4, *exi_fhp, *finfo_fhp;
3852 3974          fhandle_t *efhp;
3853 3975  
3854 3976          efhp = (fhandle_t *)&exi->exi_fh;
3855 3977          exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3856 3978  
3857 3979          FH_TO_FMT4(efhp, exi_fhp);
3858 3980  
3859 3981          finfo_fhp = (nfs_fh4_fmt_t *)lsp->rls_state->rs_finfo->
3860 3982              rf_filehandle.nfs_fh4_val;
3861 3983  
3862 3984          if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3863 3985              bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3864 3986              exi_fhp->fh4_xlen) == 0) {
3865 3987                  rfs4_state_close(lsp->rls_state, FALSE, FALSE, CRED());
3866 3988                  rfs4_dbe_invalidate(lsp->rls_dbe);
3867 3989                  rfs4_dbe_invalidate(lsp->rls_state->rs_dbe);
3868 3990          }
3869 3991  }
3870 3992  
3871 3993  /*
3872 3994   * This function is used as a target for the rfs4_dbe_walk() call
3873 3995   * below.  The purpose of this function is to see if the state refers
3874 3996   * to a file that resides within the exportinfo export.  If so, then
3875 3997   * remove the open state for this object since the intent is the
3876 3998   * server is unexporting the specified directory.  The main result for
3877 3999   * this type of entry is to invalidate it such it will not be found in
3878 4000   * the future.
3879 4001   */
3880 4002  static void
3881 4003  rfs4_state_walk_callout(rfs4_entry_t u_entry, void *e)
3882 4004  {
3883 4005          rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3884 4006          struct exportinfo *exi = (struct exportinfo *)e;
3885 4007          nfs_fh4_fmt_t   fhfmt4, *exi_fhp, *finfo_fhp;
3886 4008          fhandle_t *efhp;
3887 4009  
3888 4010          efhp = (fhandle_t *)&exi->exi_fh;
3889 4011          exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3890 4012  
3891 4013          FH_TO_FMT4(efhp, exi_fhp);
3892 4014  
3893 4015          finfo_fhp =
3894 4016              (nfs_fh4_fmt_t *)sp->rs_finfo->rf_filehandle.nfs_fh4_val;
3895 4017  
3896 4018          if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3897 4019              bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3898 4020              exi_fhp->fh4_xlen) == 0) {
3899 4021                  rfs4_state_close(sp, TRUE, FALSE, CRED());
3900 4022                  rfs4_dbe_invalidate(sp->rs_dbe);
3901 4023          }
3902 4024  }
3903 4025  
3904 4026  /*
3905 4027   * This function is used as a target for the rfs4_dbe_walk() call
3906 4028   * below.  The purpose of this function is to see if the state refers
3907 4029   * to a file that resides within the exportinfo export.  If so, then
3908 4030   * remove the deleg state for this object since the intent is the
3909 4031   * server is unexporting the specified directory.  The main result for
3910 4032   * this type of entry is to invalidate it such it will not be found in
3911 4033   * the future.
3912 4034   */
3913 4035  static void
3914 4036  rfs4_deleg_state_walk_callout(rfs4_entry_t u_entry, void *e)
3915 4037  {
3916 4038          rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
3917 4039          struct exportinfo *exi = (struct exportinfo *)e;
3918 4040          nfs_fh4_fmt_t   fhfmt4, *exi_fhp, *finfo_fhp;
3919 4041          fhandle_t *efhp;
3920 4042  
3921 4043          efhp = (fhandle_t *)&exi->exi_fh;
3922 4044          exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3923 4045  
3924 4046          FH_TO_FMT4(efhp, exi_fhp);
3925 4047  
3926 4048          finfo_fhp =
3927 4049              (nfs_fh4_fmt_t *)dsp->rds_finfo->rf_filehandle.nfs_fh4_val;
3928 4050  
3929 4051          if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3930 4052              bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3931 4053              exi_fhp->fh4_xlen) == 0) {
3932 4054                  rfs4_dbe_invalidate(dsp->rds_dbe);
3933 4055          }
3934 4056  }
3935 4057  
3936 4058  /*
3937 4059   * This function is used as a target for the rfs4_dbe_walk() call
3938 4060   * below.  The purpose of this function is to see if the state refers
3939 4061   * to a file that resides within the exportinfo export.  If so, then
3940 4062   * release vnode hold for this object since the intent is the server
3941 4063   * is unexporting the specified directory.  Invalidation will prevent
3942 4064   * this struct from being found in the future.
3943 4065   */
3944 4066  static void
3945 4067  rfs4_file_walk_callout(rfs4_entry_t u_entry, void *e)
3946 4068  {
3947 4069          rfs4_file_t *fp = (rfs4_file_t *)u_entry;
3948 4070          struct exportinfo *exi = (struct exportinfo *)e;
3949 4071          nfs_fh4_fmt_t   fhfmt4, *exi_fhp, *finfo_fhp;
3950 4072          fhandle_t *efhp;
3951 4073  
3952 4074          efhp = (fhandle_t *)&exi->exi_fh;
3953 4075          exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3954 4076  
3955 4077          FH_TO_FMT4(efhp, exi_fhp);
3956 4078  
3957 4079          finfo_fhp = (nfs_fh4_fmt_t *)fp->rf_filehandle.nfs_fh4_val;
3958 4080  
3959 4081          if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3960 4082              bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3961 4083              exi_fhp->fh4_xlen) == 0) {
3962 4084                  if (fp->rf_vp) {
3963 4085                          vnode_t *vp = fp->rf_vp;
3964 4086  
3965 4087                          /*
3966 4088                           * don't leak monitors and remove the reference
3967 4089                           * put on the vnode when the delegation was granted.
3968 4090                           */
3969 4091                          if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_READ) {
3970 4092                                  (void) fem_uninstall(vp, deleg_rdops,
3971 4093                                      (void *)fp);
3972 4094                                  vn_open_downgrade(vp, FREAD);
3973 4095                          } else if (fp->rf_dinfo.rd_dtype ==
3974 4096                              OPEN_DELEGATE_WRITE) {
3975 4097                                  (void) fem_uninstall(vp, deleg_wrops,
3976 4098                                      (void *)fp);
3977 4099                                  vn_open_downgrade(vp, FREAD|FWRITE);
3978 4100                          }
3979 4101                          mutex_enter(&vp->v_vsd_lock);
3980 4102                          (void) vsd_set(vp, nfs4_srv_vkey, NULL);
3981 4103                          mutex_exit(&vp->v_vsd_lock);
3982 4104                          VN_RELE(vp);
3983 4105                          fp->rf_vp = NULL;
  
    | 
      ↓ open down ↓ | 
    185 lines elided | 
    
      ↑ open up ↑ | 
  
3984 4106                  }
3985 4107                  rfs4_dbe_invalidate(fp->rf_dbe);
3986 4108          }
3987 4109  }
3988 4110  
3989 4111  /*
3990 4112   * Given a directory that is being unexported, cleanup/release all
3991 4113   * state in the server that refers to objects residing underneath this
3992 4114   * particular export.  The ordering of the release is important.
3993 4115   * Lock_owner, then state and then file.
     4116 + *
     4117 + * NFS zones note: nfs_export.c:unexport() calls this from a
     4118 + * thread in the global zone for NGZ data structures, so we
     4119 + * CANNOT use zone_getspecific anywhere in this code path.
3994 4120   */
3995 4121  void
3996      -rfs4_clean_state_exi(struct exportinfo *exi)
     4122 +rfs4_clean_state_exi(nfs_export_t *ne, struct exportinfo *exi)
3997 4123  {
3998      -        mutex_enter(&rfs4_state_lock);
     4124 +        nfs_globals_t *ng;
     4125 +        nfs4_srv_t *nsrv4;
3999 4126  
4000      -        if (rfs4_server_state == NULL) {
4001      -                mutex_exit(&rfs4_state_lock);
     4127 +        ng = ne->ne_globals;
     4128 +        ASSERT(ng->nfs_zoneid == exi->exi_zoneid);
     4129 +        nsrv4 = ng->nfs4_srv;
     4130 +
     4131 +        mutex_enter(&nsrv4->state_lock);
     4132 +
     4133 +        if (nsrv4->nfs4_server_state == NULL) {
     4134 +                mutex_exit(&nsrv4->state_lock);
4002 4135                  return;
4003 4136          }
4004 4137  
4005      -        rfs4_dbe_walk(rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
4006      -        rfs4_dbe_walk(rfs4_state_tab, rfs4_state_walk_callout, exi);
4007      -        rfs4_dbe_walk(rfs4_deleg_state_tab, rfs4_deleg_state_walk_callout, exi);
4008      -        rfs4_dbe_walk(rfs4_file_tab, rfs4_file_walk_callout, exi);
     4138 +        rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab,
     4139 +            rfs4_lo_state_walk_callout, exi);
     4140 +        rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
     4141 +        rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab,
     4142 +            rfs4_deleg_state_walk_callout, exi);
     4143 +        rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
4009 4144  
4010      -        mutex_exit(&rfs4_state_lock);
     4145 +        mutex_exit(&nsrv4->state_lock);
4011 4146  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX