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_db.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_db.c
↓ 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   24   */
  24   25  
       26 +/*
       27 + * Copyright 2018 Nexenta Systems, Inc.
       28 + */
       29 +
  25   30  #include <sys/systm.h>
  26   31  #include <sys/cmn_err.h>
  27   32  #include <sys/kmem.h>
  28   33  #include <sys/disp.h>
  29   34  #include <sys/id_space.h>
  30   35  #include <sys/atomic.h>
  31   36  #include <rpc/rpc.h>
  32   37  #include <nfs/nfs4.h>
  33   38  #include <nfs/nfs4_db_impl.h>
  34   39  #include <sys/sdt.h>
↓ open down ↓ 207 lines elided ↑ open up ↑
 242  247          for (next = db->db_tables; next; ) {
 243  248                  tmp = next;
 244  249                  next = tmp->dbt_tnext;
 245  250                  rfs4_table_destroy(db, tmp);
 246  251          }
 247  252  
 248  253          mutex_destroy(db->db_lock);
 249  254          kmem_free(db, sizeof (rfs4_database_t));
 250  255  }
 251  256  
      257 +/*
      258 + * Used to get the correct kmem_cache database for the state table being
      259 + * created.
      260 + * Helper function for rfs4_table_create
      261 + */
      262 +static kmem_cache_t *
      263 +get_db_mem_cache(char *name)
      264 +{
      265 +        int i;
      266 +
      267 +        for (i = 0; i < RFS4_DB_MEM_CACHE_NUM; i++) {
      268 +                if (strcmp(name, rfs4_db_mem_cache_table[i].r_db_name) == 0)
      269 +                        return (rfs4_db_mem_cache_table[i].r_db_mem_cache);
      270 +        }
      271 +        /*
      272 +         * There is no associated kmem cache for this NFS4 server state
      273 +         * table name
      274 +         */
      275 +        return (NULL);
      276 +}
      277 +
      278 +/*
      279 + * Used to initialize the global NFSv4 server state database.
      280 + * Helper funtion for rfs4_state_g_init and called when module is loaded.
      281 + */
      282 +kmem_cache_t *
      283 +/* CSTYLED */
      284 +nfs4_init_mem_cache(char *cache_name, uint32_t idxcnt, uint32_t size, uint32_t idx)
      285 +{
      286 +        kmem_cache_t *mem_cache = kmem_cache_create(cache_name,
      287 +            sizeof (rfs4_dbe_t) + idxcnt * sizeof (rfs4_link_t) + size,
      288 +            0,
      289 +            rfs4_dbe_kmem_constructor,
      290 +            rfs4_dbe_kmem_destructor,
      291 +            NULL,
      292 +            NULL,
      293 +            NULL,
      294 +            0);
      295 +        (void) strlcpy(rfs4_db_mem_cache_table[idx].r_db_name, cache_name,
      296 +            strlen(cache_name) + 1);
      297 +        rfs4_db_mem_cache_table[idx].r_db_mem_cache = mem_cache;
      298 +        return (mem_cache);
      299 +}
      300 +
 252  301  rfs4_table_t *
 253  302  rfs4_table_create(rfs4_database_t *db, char *tabname, time_t max_cache_time,
 254  303      uint32_t idxcnt, bool_t (*create)(rfs4_entry_t, void *),
 255  304      void (*destroy)(rfs4_entry_t),
 256  305      bool_t (*expiry)(rfs4_entry_t),
 257  306      uint32_t size, uint32_t hashsize,
 258  307      uint32_t maxentries, id_t start)
 259  308  {
 260  309          rfs4_table_t    *table;
 261  310          int              len;
↓ open down ↓ 35 lines elided ↑ open up ↑
 297  346          ASSERT(t_lowat != 0);
 298  347          table->dbt_id_lwat = (maxentries * t_lowat) / 100;
 299  348          ASSERT(t_hiwat != 0);
 300  349          table->dbt_id_hwat = (maxentries * t_hiwat) / 100;
 301  350          table->dbt_id_reap = MIN(rfs4_reap_interval, max_cache_time);
 302  351          table->dbt_maxentries = maxentries;
 303  352          table->dbt_create = create;
 304  353          table->dbt_destroy = destroy;
 305  354          table->dbt_expiry = expiry;
 306  355  
 307      -        table->dbt_mem_cache = kmem_cache_create(cache_name,
 308      -            sizeof (rfs4_dbe_t) + idxcnt * sizeof (rfs4_link_t) + size,
 309      -            0,
 310      -            rfs4_dbe_kmem_constructor,
 311      -            rfs4_dbe_kmem_destructor,
 312      -            NULL,
 313      -            table,
 314      -            NULL,
 315      -            0);
      356 +        /*
      357 +         * get the correct kmem_cache for this table type based on the name.
      358 +         */
      359 +        table->dbt_mem_cache = get_db_mem_cache(cache_name);
      360 +
 316  361          kmem_free(cache_name, len+13);
 317  362  
 318  363          table->dbt_debug = db->db_debug_flags;
 319  364  
 320  365          mutex_enter(db->db_lock);
 321  366          table->dbt_tnext = db->db_tables;
 322  367          db->db_tables = table;
 323  368          mutex_exit(db->db_lock);
 324  369  
 325  370          rfs4_start_reaper(table);
↓ open down ↓ 31 lines elided ↑ open up ↑
 357  402          }
 358  403  
 359  404          rw_destroy(table->dbt_t_lock);
 360  405          mutex_destroy(table->dbt_lock);
 361  406          mutex_destroy(&table->dbt_reaper_cv_lock);
 362  407          cv_destroy(&table->dbt_reaper_wait);
 363  408  
 364  409          kmem_free(table->dbt_name, strlen(table->dbt_name) + 1);
 365  410          if (table->dbt_id_space)
 366  411                  id_space_destroy(table->dbt_id_space);
 367      -        kmem_cache_destroy(table->dbt_mem_cache);
      412 +        table->dbt_mem_cache = NULL;
 368  413          kmem_free(table, sizeof (rfs4_table_t));
 369  414  }
 370  415  
 371  416  rfs4_index_t *
 372  417  rfs4_index_create(rfs4_table_t *table, char *keyname,
 373  418      uint32_t (*hash)(void *),
 374  419      bool_t (compare)(rfs4_entry_t, void *),
 375  420      void *(*mkkey)(rfs4_entry_t),
 376  421      bool_t createable)
 377  422  {
↓ open down ↓ 298 lines elided ↑ open up ↑
 676  721              (CE_NOTE, "Entry %p created for %s = %p in table %s",
 677  722              (void*)entry, idx->dbi_keyname, (void*)key, table->dbt_name));
 678  723  
 679  724          return (entry->dbe_data);
 680  725  }
 681  726  
 682  727  /*ARGSUSED*/
 683  728  boolean_t
 684  729  rfs4_cpr_callb(void *arg, int code)
 685  730  {
 686      -        rfs4_table_t *table = rfs4_client_tab;
 687  731          rfs4_bucket_t *buckets, *bp;
 688  732          rfs4_link_t *l;
 689  733          rfs4_client_t *cp;
 690  734          int i;
 691  735  
      736 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
      737 +        rfs4_table_t *table = nsrv4->rfs4_client_tab;
      738 +
 692  739          /*
 693  740           * We get called for Suspend and Resume events.
 694  741           * For the suspend case we simply don't care!  Nor do we care if
 695  742           * there are no clients.
 696  743           */
 697  744          if (code == CB_CODE_CPR_CHKPT || table == NULL) {
 698  745                  return (B_TRUE);
 699  746          }
 700  747  
 701  748          buckets = table->dbt_indices->dbi_buckets;
↓ open down ↓ 170 lines elided ↑ open up ↑
 872  919          CALLB_CPR_EXIT(&table->dbt_reaper_cpr_info);
 873  920  
 874  921          NFS4_DEBUG(table->dbt_debug,
 875  922              (CE_NOTE, "rfs4_reaper_thread exiting for %s", table->dbt_name));
 876  923  
 877  924          /* Notify the database shutdown processing that the table is shutdown */
 878  925          mutex_enter(table->dbt_db->db_lock);
 879  926          table->dbt_db->db_shutdown_count--;
 880  927          cv_signal(&table->dbt_db->db_shutdown_wait);
 881  928          mutex_exit(table->dbt_db->db_lock);
      929 +        zthread_exit();
 882  930  }
 883  931  
 884  932  static void
 885  933  rfs4_start_reaper(rfs4_table_t *table)
 886  934  {
 887  935          if (table->dbt_max_cache_time == 0)
 888  936                  return;
 889  937  
 890      -        (void) thread_create(NULL, 0, reaper_thread, table, 0, &p0, TS_RUN,
      938 +        (void) zthread_create(NULL, 0, reaper_thread, table, 0,
 891  939              minclsyspri);
 892  940  }
 893  941  
 894  942  #ifdef DEBUG
 895  943  void
 896  944  rfs4_dbe_debug(rfs4_dbe_t *entry)
 897  945  {
 898  946          cmn_err(CE_NOTE, "Entry %p from table %s",
 899  947              (void *)entry, entry->dbe_table->dbt_name);
 900  948          cmn_err(CE_CONT, "\trefcnt = %d id = %d",
 901  949              entry->dbe_refcnt, entry->dbe_id);
 902  950  }
 903  951  #endif
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX