Print this page
3752 want more verifiable dbuf user eviction
Submitted by:   Justin Gibbs <justing@spectralogic.com>
Submitted by:   Will Andrews <willa@spectralogic.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dnode.c
          +++ new/usr/src/uts/common/fs/zfs/dnode.c
↓ open down ↓ 450 lines elided ↑ open up ↑
 451  451          dn->dn_allocated_txg = 0;
 452  452          dn->dn_free_txg = 0;
 453  453          dn->dn_assigned_txg = 0;
 454  454  
 455  455          dn->dn_dirtyctx = 0;
 456  456          if (dn->dn_dirtyctx_firstset != NULL) {
 457  457                  kmem_free(dn->dn_dirtyctx_firstset, 1);
 458  458                  dn->dn_dirtyctx_firstset = NULL;
 459  459          }
 460  460          if (dn->dn_bonus != NULL) {
      461 +                list_t evict_list;
      462 +
      463 +                dmu_buf_create_user_evict_list(&evict_list);
 461  464                  mutex_enter(&dn->dn_bonus->db_mtx);
 462      -                dbuf_evict(dn->dn_bonus);
      465 +                dbuf_evict(dn->dn_bonus, &evict_list);
      466 +                dmu_buf_destroy_user_evict_list(&evict_list);
 463  467                  dn->dn_bonus = NULL;
 464  468          }
 465  469          dn->dn_zio = NULL;
 466  470  
 467  471          dn->dn_have_spill = B_FALSE;
 468  472          dn->dn_oldused = 0;
 469  473          dn->dn_oldflags = 0;
 470  474          dn->dn_olduid = 0;
 471  475          dn->dn_oldgid = 0;
 472  476          dn->dn_newuid = 0;
↓ open down ↓ 477 lines elided ↑ open up ↑
 950  954      dnode_handle_t *dnh)
 951  955  {
 952  956          dnode_t *dn = dnode_create(os, dnp, NULL, object, dnh);
 953  957          dnh->dnh_dnode = dn;
 954  958          zrl_init(&dnh->dnh_zrlock);
 955  959          DNODE_VERIFY(dn);
 956  960          return (dn);
 957  961  }
 958  962  
 959  963  static void
 960      -dnode_buf_pageout(dmu_buf_t *db, void *arg)
      964 +dnode_buf_pageout(dmu_buf_user_t *dbu)
 961  965  {
 962      -        dnode_children_t *children_dnodes = arg;
      966 +        dnode_children_t *children_dnodes = (dnode_children_t *)dbu;
 963  967          int i;
 964      -        int epb = db->db_size >> DNODE_SHIFT;
 965      -
 966      -        ASSERT(epb == children_dnodes->dnc_count);
 967  968  
 968      -        for (i = 0; i < epb; i++) {
      969 +        for (i = 0; i < children_dnodes->dnc_count; i++) {
 969  970                  dnode_handle_t *dnh = &children_dnodes->dnc_children[i];
 970  971                  dnode_t *dn;
 971  972  
 972  973                  /*
 973  974                   * The dnode handle lock guards against the dnode moving to
 974  975                   * another valid address, so there is no need here to guard
 975  976                   * against changes to or from NULL.
 976  977                   */
 977  978                  if (dnh->dnh_dnode == NULL) {
 978  979                          zrl_destroy(&dnh->dnh_zrlock);
↓ open down ↓ 9 lines elided ↑ open up ↑
 988  989                   * would not have been called.
 989  990                   */
 990  991                  ASSERT(refcount_is_zero(&dn->dn_holds));
 991  992                  ASSERT(refcount_is_zero(&dn->dn_tx_holds));
 992  993  
 993  994                  dnode_destroy(dn); /* implicit zrl_remove() */
 994  995                  zrl_destroy(&dnh->dnh_zrlock);
 995  996                  dnh->dnh_dnode = NULL;
 996  997          }
 997  998          kmem_free(children_dnodes, sizeof (dnode_children_t) +
 998      -            (epb - 1) * sizeof (dnode_handle_t));
      999 +            (children_dnodes->dnc_count - 1) * sizeof (dnode_handle_t));
 999 1000  }
1000 1001  
1001 1002  /*
1002 1003   * errors:
1003 1004   * EINVAL - invalid object number.
1004 1005   * EIO - i/o error.
1005 1006   * succeeds even for free dnodes.
1006 1007   */
1007 1008  int
1008 1009  dnode_hold_impl(objset_t *os, uint64_t object, int flag,
↓ open down ↓ 59 lines elided ↑ open up ↑
1068 1069                  dbuf_rele(db, FTAG);
1069 1070                  return (err);
1070 1071          }
1071 1072  
1072 1073          ASSERT3U(db->db.db_size, >=, 1<<DNODE_SHIFT);
1073 1074          epb = db->db.db_size >> DNODE_SHIFT;
1074 1075  
1075 1076          idx = object & (epb-1);
1076 1077  
1077 1078          ASSERT(DB_DNODE(db)->dn_type == DMU_OT_DNODE);
1078      -        children_dnodes = dmu_buf_get_user(&db->db);
     1079 +        children_dnodes = (dnode_children_t *)dmu_buf_get_user(&db->db);
1079 1080          if (children_dnodes == NULL) {
1080 1081                  int i;
1081 1082                  dnode_children_t *winner;
1082 1083                  children_dnodes = kmem_alloc(sizeof (dnode_children_t) +
1083 1084                      (epb - 1) * sizeof (dnode_handle_t), KM_SLEEP);
1084 1085                  children_dnodes->dnc_count = epb;
1085 1086                  dnh = &children_dnodes->dnc_children[0];
1086 1087                  for (i = 0; i < epb; i++) {
1087 1088                          zrl_init(&dnh[i].dnh_zrlock);
1088 1089                          dnh[i].dnh_dnode = NULL;
1089 1090                  }
1090      -                if (winner = dmu_buf_set_user(&db->db, children_dnodes, NULL,
1091      -                    dnode_buf_pageout)) {
     1091 +                dmu_buf_init_user(&children_dnodes->db_evict,
     1092 +                    dnode_buf_pageout);
     1093 +                winner = (dnode_children_t *)
     1094 +                    dmu_buf_set_user(&db->db, &children_dnodes->db_evict);
     1095 +                if (winner) {
1092 1096                          kmem_free(children_dnodes, sizeof (dnode_children_t) +
1093 1097                              (epb - 1) * sizeof (dnode_handle_t));
1094 1098                          children_dnodes = winner;
1095 1099                  }
1096 1100          }
1097 1101          ASSERT(children_dnodes->dnc_count == epb);
1098 1102  
1099 1103          dnh = &children_dnodes->dnc_children[idx];
1100 1104          zrl_add(&dnh->dnh_zrlock);
1101 1105          if ((dn = dnh->dnh_dnode) == NULL) {
↓ open down ↓ 899 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX