Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs4_srv.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_srv.c
↓ open down ↓ 145 lines elided ↑ open up ↑
 146  146   *
 147  147   * dirent64: named padded to provide 8 byte struct alignment
 148  148   *      d_ino(8) + d_off(8) + d_reclen(2) + d_name(namelen + null(1) + pad)
 149  149   *
 150  150   * cookie: uint64_t   +  utf8namelen: uint_t  +   utf8name padded to 8 bytes
 151  151   *
 152  152   */
 153  153  #define DIRENT64_TO_DIRCOUNT(dp) \
 154  154          (3 * BYTES_PER_XDR_UNIT + DIRENT64_NAMELEN((dp)->d_reclen))
 155  155  
 156      -zone_key_t      rfs4_zone_key;
 157  156  
 158  157  static sysid_t          lockt_sysid;    /* dummy sysid for all LOCKT calls */
 159  158  
 160  159  u_longlong_t    nfs4_srv_caller_id;
 161  160  uint_t          nfs4_srv_vkey = 0;
 162  161  
 163  162  void    rfs4_init_compound_state(struct compound_state *);
 164  163  
 165  164  static void     nullfree(caddr_t);
 166  165  static void     rfs4_op_inval(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
↓ open down ↓ 327 lines elided ↑ open up ↑
 494  493          VOPNAME_READ,           { .femop_read = deleg_wr_read },
 495  494          VOPNAME_WRITE,          { .femop_write = deleg_wr_write },
 496  495          VOPNAME_SETATTR,        { .femop_setattr = deleg_wr_setattr },
 497  496          VOPNAME_RWLOCK,         { .femop_rwlock = deleg_wr_rwlock },
 498  497          VOPNAME_SPACE,          { .femop_space = deleg_wr_space },
 499  498          VOPNAME_SETSECATTR,     { .femop_setsecattr = deleg_wr_setsecattr },
 500  499          VOPNAME_VNEVENT,        { .femop_vnevent = deleg_wr_vnevent },
 501  500          NULL,                   NULL
 502  501  };
 503  502  
 504      -/* ARGSUSED */
 505      -static void *
 506      -rfs4_zone_init(zoneid_t zoneid)
      503 +nfs4_srv_t *
      504 +nfs4_get_srv(void)
 507  505  {
      506 +        nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
      507 +        nfs4_srv_t *srv = ng->nfs4_srv;
      508 +        ASSERT(srv != NULL);
      509 +        return (srv);
      510 +}
      511 +
      512 +void
      513 +rfs4_srv_zone_init(nfs_globals_t *ng)
      514 +{
 508  515          nfs4_srv_t *nsrv4;
 509  516          timespec32_t verf;
 510  517  
 511  518          nsrv4 = kmem_zalloc(sizeof (*nsrv4), KM_SLEEP);
 512  519  
 513  520          /*
 514  521           * The following algorithm attempts to find a unique verifier
 515  522           * to be used as the write verifier returned from the server
 516  523           * to the client.  It is important that this verifier change
 517  524           * whenever the server reboots.  Of secondary importance, it
↓ open down ↓ 24 lines elided ↑ open up ↑
 542  549  
 543  550          /* Used to manage create/destroy of server state */
 544  551          nsrv4->nfs4_server_state = NULL;
 545  552          nsrv4->nfs4_cur_servinst = NULL;
 546  553          nsrv4->nfs4_deleg_policy = SRV_NEVER_DELEGATE;
 547  554          mutex_init(&nsrv4->deleg_lock, NULL, MUTEX_DEFAULT, NULL);
 548  555          mutex_init(&nsrv4->state_lock, NULL, MUTEX_DEFAULT, NULL);
 549  556          mutex_init(&nsrv4->servinst_lock, NULL, MUTEX_DEFAULT, NULL);
 550  557          rw_init(&nsrv4->deleg_policy_lock, NULL, RW_DEFAULT, NULL);
 551  558  
 552      -        return (nsrv4);
      559 +        ng->nfs4_srv = nsrv4;
 553  560  }
 554  561  
 555      -/* ARGSUSED */
 556      -static void
 557      -rfs4_zone_fini(zoneid_t zoneid, void *data)
      562 +void
      563 +rfs4_srv_zone_fini(nfs_globals_t *ng)
 558  564  {
 559      -        nfs4_srv_t *nsrv4 = data;
      565 +        nfs4_srv_t *nsrv4 = ng->nfs4_srv;
 560  566  
      567 +        ng->nfs4_srv = NULL;
      568 +
 561  569          mutex_destroy(&nsrv4->deleg_lock);
 562  570          mutex_destroy(&nsrv4->state_lock);
 563  571          mutex_destroy(&nsrv4->servinst_lock);
 564  572          rw_destroy(&nsrv4->deleg_policy_lock);
 565  573  
 566  574          kmem_free(nsrv4, sizeof (*nsrv4));
 567  575  }
 568  576  
 569  577  void
 570  578  rfs4_srvrinit(void)
 571  579  {
 572  580          extern void rfs4_attr_init();
 573  581  
 574      -        zone_key_create(&rfs4_zone_key, rfs4_zone_init, NULL, rfs4_zone_fini);
 575      -
 576  582          rfs4_attr_init();
 577  583  
 578      -
 579  584          if (fem_create("deleg_rdops", nfs4_rd_deleg_tmpl, &deleg_rdops) != 0) {
 580  585                  rfs4_disable_delegation();
 581  586          } else if (fem_create("deleg_wrops", nfs4_wr_deleg_tmpl,
 582  587              &deleg_wrops) != 0) {
 583  588                  rfs4_disable_delegation();
 584  589                  fem_free(deleg_rdops);
 585  590          }
 586  591  
 587  592          nfs4_srv_caller_id = fs_new_caller_id();
 588  593          lockt_sysid = lm_alloc_sysidt();
↓ open down ↓ 6 lines elided ↑ open up ↑
 595  600  {
 596  601          if (lockt_sysid != LM_NOSYSID) {
 597  602                  lm_free_sysidt(lockt_sysid);
 598  603                  lockt_sysid = LM_NOSYSID;
 599  604          }
 600  605  
 601  606          rfs4_state_g_fini();
 602  607  
 603  608          fem_free(deleg_rdops);
 604  609          fem_free(deleg_wrops);
 605      -
 606      -        (void) zone_key_delete(rfs4_zone_key);
 607  610  }
 608  611  
 609  612  void
 610  613  rfs4_do_server_start(int server_upordown,
 611  614      int srv_delegation, int cluster_booted)
 612  615  {
 613      -        nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
      616 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
 614  617  
 615  618          /* Is this a warm start? */
 616  619          if (server_upordown == NFS_SERVER_QUIESCED) {
 617  620                  cmn_err(CE_NOTE, "nfs4_srv: "
 618  621                      "server was previously quiesced; "
 619  622                      "existing NFSv4 state will be re-used");
 620  623  
 621  624                  /*
 622  625                   * HA-NFSv4: this is also the signal
 623  626                   * that a Resource Group failover has
↓ open down ↓ 886 lines elided ↑ open up ↑
1510 1513                  goto out;
1511 1514          }
1512 1515  
1513 1516          error = VOP_FSYNC(vp, FSYNC, cr, NULL);
1514 1517  
1515 1518          if (error) {
1516 1519                  *cs->statusp = resp->status = puterrno4(error);
1517 1520                  goto out;
1518 1521          }
1519 1522  
1520      -        nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
     1523 +        nsrv4 = nfs4_get_srv();
1521 1524          *cs->statusp = resp->status = NFS4_OK;
1522 1525          resp->writeverf = nsrv4->write4verf;
1523 1526  out:
1524 1527          DTRACE_NFSV4_2(op__commit__done, struct compound_state *, cs,
1525 1528              COMMIT4res *, resp);
1526 1529  }
1527 1530  
1528 1531  /*
1529 1532   * rfs4_op_mknod is called from rfs4_op_create after all initial verification
1530 1533   * was completed. It does the nfsv4 create for special files.
↓ open down ↓ 4126 lines elided ↑ open up ↑
5657 5660              (error = VOP_ACCESS(vp, VWRITE, 0, cr, &ct))) {
5658 5661                  *cs->statusp = resp->status = puterrno4(error);
5659 5662                  goto out;
5660 5663          }
5661 5664  
5662 5665          if (MANDLOCK(vp, bva.va_mode)) {
5663 5666                  *cs->statusp = resp->status = NFS4ERR_ACCESS;
5664 5667                  goto out;
5665 5668          }
5666 5669  
5667      -        nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
     5670 +        nsrv4 = nfs4_get_srv();
5668 5671          if (args->data_len == 0) {
5669 5672                  *cs->statusp = resp->status = NFS4_OK;
5670 5673                  resp->count = 0;
5671 5674                  resp->committed = args->stable;
5672 5675                  resp->writeverf = nsrv4->write4verf;
5673 5676                  goto out;
5674 5677          }
5675 5678  
5676 5679          if (args->mblk != NULL) {
5677 5680                  mblk_t *m;
↓ open down ↓ 159 lines elided ↑ open up ↑
5837 5840                  svcerr_badcred(req->rq_xprt);
5838 5841                  if (rv != NULL)
5839 5842                          *rv = 1;
5840 5843                  return;
5841 5844          }
5842 5845          resp->array_len = args->array_len;
5843 5846          resp->array = kmem_zalloc(args->array_len * sizeof (nfs_resop4),
5844 5847              KM_SLEEP);
5845 5848  
5846 5849          cs.basecr = cr;
5847      -        nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
     5850 +        nsrv4 = nfs4_get_srv();
5848 5851  
5849 5852          DTRACE_NFSV4_2(compound__start, struct compound_state *, &cs,
5850 5853              COMPOUND4args *, args);
5851 5854  
5852 5855          /*
5853 5856           * For now, NFS4 compound processing must be protected by
5854 5857           * exported_lock because it can access more than one exportinfo
5855 5858           * per compound and share/unshare can now change multiple
5856 5859           * exinfo structs.  The NFS2/3 code only refs 1 exportinfo
5857 5860           * per proc (excluding public exinfo), and exi_count design
↓ open down ↓ 791 lines elided ↑ open up ↑
6649 6652                  if (trunc) {
6650 6653                          int in_crit = 0;
6651 6654                          rfs4_file_t *fp;
6652 6655                          nfs4_srv_t *nsrv4;
6653 6656                          bool_t create = FALSE;
6654 6657  
6655 6658                          /*
6656 6659                           * We are writing over an existing file.
6657 6660                           * Check to see if we need to recall a delegation.
6658 6661                           */
6659      -                        nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
     6662 +                        nsrv4 = nfs4_get_srv();
6660 6663                          rfs4_hold_deleg_policy(nsrv4);
6661 6664                          if ((fp = rfs4_findfile(vp, NULL, &create)) != NULL) {
6662 6665                                  if (rfs4_check_delegated_byfp(FWRITE, fp,
6663 6666                                      (reqsize == 0), FALSE, FALSE, &clientid)) {
6664 6667                                          rfs4_file_rele(fp);
6665 6668                                          rfs4_rele_deleg_policy(nsrv4);
6666 6669                                          VN_RELE(vp);
6667 6670                                          *attrset = 0;
6668 6671                                          return (NFS4ERR_DELAY);
6669 6672                                  }
↓ open down ↓ 1556 lines elided ↑ open up ↑
8226 8229              &argop->nfs_argop4_u.opsetclientid_confirm;
8227 8230          SETCLIENTID_CONFIRM4res *res =
8228 8231              &resop->nfs_resop4_u.opsetclientid_confirm;
8229 8232          rfs4_client_t *cp, *cptoclose = NULL;
8230 8233          nfs4_srv_t *nsrv4;
8231 8234  
8232 8235          DTRACE_NFSV4_2(op__setclientid__confirm__start,
8233 8236              struct compound_state *, cs,
8234 8237              SETCLIENTID_CONFIRM4args *, args);
8235 8238  
8236      -        nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
     8239 +        nsrv4 = nfs4_get_srv();
8237 8240          *cs->statusp = res->status = NFS4_OK;
8238 8241  
8239 8242          cp = rfs4_findclient_by_id(args->clientid, TRUE);
8240 8243  
8241 8244          if (cp == NULL) {
8242 8245                  *cs->statusp = res->status =
8243 8246                      rfs4_check_clientid(&args->clientid, 1);
8244 8247                  goto out;
8245 8248          }
8246 8249  
↓ open down ↓ 1856 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX