Print this page
4047 panic from dbuf_free_range() from dmu_free_object() while doing zfs receive
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.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 ↓ 107 lines elided ↑ open up ↑
 108  108          dn->dn_zio = NULL;
 109  109          dn->dn_oldused = 0;
 110  110          dn->dn_oldflags = 0;
 111  111          dn->dn_olduid = 0;
 112  112          dn->dn_oldgid = 0;
 113  113          dn->dn_newuid = 0;
 114  114          dn->dn_newgid = 0;
 115  115          dn->dn_id_flags = 0;
 116  116  
 117  117          dn->dn_dbufs_count = 0;
      118 +        dn->dn_unlisted_l0_blkid = 0;
 118  119          list_create(&dn->dn_dbufs, sizeof (dmu_buf_impl_t),
 119  120              offsetof(dmu_buf_impl_t, db_link));
 120  121  
 121  122          dn->dn_moved = 0;
 122  123          return (0);
 123  124  }
 124  125  
 125  126  /* ARGSUSED */
 126  127  static void
 127  128  dnode_dest(void *arg, void *unused)
↓ open down ↓ 32 lines elided ↑ open up ↑
 160  161          ASSERT3P(dn->dn_zio, ==, NULL);
 161  162          ASSERT0(dn->dn_oldused);
 162  163          ASSERT0(dn->dn_oldflags);
 163  164          ASSERT0(dn->dn_olduid);
 164  165          ASSERT0(dn->dn_oldgid);
 165  166          ASSERT0(dn->dn_newuid);
 166  167          ASSERT0(dn->dn_newgid);
 167  168          ASSERT0(dn->dn_id_flags);
 168  169  
 169  170          ASSERT0(dn->dn_dbufs_count);
      171 +        ASSERT0(dn->dn_unlisted_l0_blkid);
 170  172          list_destroy(&dn->dn_dbufs);
 171  173  }
 172  174  
 173  175  void
 174  176  dnode_init(void)
 175  177  {
 176  178          ASSERT(dnode_cache == NULL);
 177  179          dnode_cache = kmem_cache_create("dnode_t",
 178  180              sizeof (dnode_t),
 179  181              0, dnode_cons, dnode_dest, NULL, NULL, NULL, 0);
↓ open down ↓ 285 lines elided ↑ open up ↑
 465  467          dn->dn_zio = NULL;
 466  468  
 467  469          dn->dn_have_spill = B_FALSE;
 468  470          dn->dn_oldused = 0;
 469  471          dn->dn_oldflags = 0;
 470  472          dn->dn_olduid = 0;
 471  473          dn->dn_oldgid = 0;
 472  474          dn->dn_newuid = 0;
 473  475          dn->dn_newgid = 0;
 474  476          dn->dn_id_flags = 0;
      477 +        dn->dn_unlisted_l0_blkid = 0;
 475  478  
 476  479          dmu_zfetch_rele(&dn->dn_zfetch);
 477  480          kmem_cache_free(dnode_cache, dn);
 478  481          arc_space_return(sizeof (dnode_t), ARC_SPACE_OTHER);
 479  482  }
 480  483  
 481  484  void
 482  485  dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
 483  486      dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 484  487  {
↓ open down ↓ 210 lines elided ↑ open up ↑
 695  698          ndn->dn_allocated_txg = odn->dn_allocated_txg;
 696  699          ndn->dn_free_txg = odn->dn_free_txg;
 697  700          ndn->dn_assigned_txg = odn->dn_assigned_txg;
 698  701          ndn->dn_dirtyctx = odn->dn_dirtyctx;
 699  702          ndn->dn_dirtyctx_firstset = odn->dn_dirtyctx_firstset;
 700  703          ASSERT(refcount_count(&odn->dn_tx_holds) == 0);
 701  704          refcount_transfer(&ndn->dn_holds, &odn->dn_holds);
 702  705          ASSERT(list_is_empty(&ndn->dn_dbufs));
 703  706          list_move_tail(&ndn->dn_dbufs, &odn->dn_dbufs);
 704  707          ndn->dn_dbufs_count = odn->dn_dbufs_count;
      708 +        ndn->dn_unlisted_l0_blkid = odn->dn_unlisted_l0_blkid;
 705  709          ndn->dn_bonus = odn->dn_bonus;
 706  710          ndn->dn_have_spill = odn->dn_have_spill;
 707  711          ndn->dn_zio = odn->dn_zio;
 708  712          ndn->dn_oldused = odn->dn_oldused;
 709  713          ndn->dn_oldflags = odn->dn_oldflags;
 710  714          ndn->dn_olduid = odn->dn_olduid;
 711  715          ndn->dn_oldgid = odn->dn_oldgid;
 712  716          ndn->dn_newuid = odn->dn_newuid;
 713  717          ndn->dn_newgid = odn->dn_newgid;
 714  718          ndn->dn_id_flags = odn->dn_id_flags;
↓ open down ↓ 14 lines elided ↑ open up ↑
 729  733          }
 730  734  
 731  735          /*
 732  736           * Invalidate the original dnode by clearing all of its back pointers.
 733  737           */
 734  738          odn->dn_dbuf = NULL;
 735  739          odn->dn_handle = NULL;
 736  740          list_create(&odn->dn_dbufs, sizeof (dmu_buf_impl_t),
 737  741              offsetof(dmu_buf_impl_t, db_link));
 738  742          odn->dn_dbufs_count = 0;
      743 +        odn->dn_unlisted_l0_blkid = 0;
 739  744          odn->dn_bonus = NULL;
 740  745          odn->dn_zfetch.zf_dnode = NULL;
 741  746  
 742  747          /*
 743  748           * Set the low bit of the objset pointer to ensure that dnode_move()
 744  749           * recognizes the dnode as invalid in any subsequent callback.
 745  750           */
 746  751          POINTER_INVALIDATE(&odn->dn_objset);
 747  752  
 748  753          /*
↓ open down ↓ 767 lines elided ↑ open up ↑
1516 1521          uint64_t blkoff, blkid, nblks;
1517 1522          int blksz, blkshift, head, tail;
1518 1523          int trunc = FALSE;
1519 1524          int epbs;
1520 1525  
1521 1526          rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
1522 1527          blksz = dn->dn_datablksz;
1523 1528          blkshift = dn->dn_datablkshift;
1524 1529          epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
1525 1530  
1526      -        if (len == -1ULL) {
     1531 +        if (len == DMU_OBJECT_END) {
1527 1532                  len = UINT64_MAX - off;
1528 1533                  trunc = TRUE;
1529 1534          }
1530 1535  
1531 1536          /*
1532 1537           * First, block align the region to free:
1533 1538           */
1534 1539          if (ISP2(blksz)) {
1535 1540                  head = P2NPHASE(off, blksz);
1536 1541                  blkoff = P2PHASE(off, blksz);
↓ open down ↓ 466 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX