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>


 598                 return;
 599         dn = txh->txh_dnode;
 600 
 601         if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
 602                 return;
 603         if (len == DMU_OBJECT_END)
 604                 len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
 605 
 606         dmu_tx_count_dnode(txh);
 607 
 608         /*
 609          * For i/o error checking, we read the first and last level-0
 610          * blocks if they are not aligned, and all the level-1 blocks.
 611          *
 612          * Note:  dbuf_free_range() assumes that we have not instantiated
 613          * any level-0 dbufs that will be completely freed.  Therefore we must
 614          * exercise care to not read or count the first and last blocks
 615          * if they are blocksize-aligned.
 616          */
 617         if (dn->dn_datablkshift == 0) {

 618                 dmu_tx_count_write(txh, off, len);
 619         } else {
 620                 /* first block will be modified if it is not aligned */
 621                 if (!IS_P2ALIGNED(off, 1 << dn->dn_datablkshift))
 622                         dmu_tx_count_write(txh, off, 1);
 623                 /* last block will be modified if it is not aligned */
 624                 if (!IS_P2ALIGNED(off + len, 1 << dn->dn_datablkshift))
 625                         dmu_tx_count_write(txh, off+len, 1);
 626         }
 627 
 628         /*
 629          * Check level-1 blocks.
 630          */
 631         if (dn->dn_nlevels > 1) {
 632                 int shift = dn->dn_datablkshift + dn->dn_indblkshift -
 633                     SPA_BLKPTRSHIFT;
 634                 uint64_t start = off >> shift;
 635                 uint64_t end = (off + len) >> shift;
 636 
 637                 ASSERT(dn->dn_datablkshift != 0);




 598                 return;
 599         dn = txh->txh_dnode;
 600 
 601         if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
 602                 return;
 603         if (len == DMU_OBJECT_END)
 604                 len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
 605 
 606         dmu_tx_count_dnode(txh);
 607 
 608         /*
 609          * For i/o error checking, we read the first and last level-0
 610          * blocks if they are not aligned, and all the level-1 blocks.
 611          *
 612          * Note:  dbuf_free_range() assumes that we have not instantiated
 613          * any level-0 dbufs that will be completely freed.  Therefore we must
 614          * exercise care to not read or count the first and last blocks
 615          * if they are blocksize-aligned.
 616          */
 617         if (dn->dn_datablkshift == 0) {
 618                 if (off != 0 || len < dn->dn_datablksz)
 619                         dmu_tx_count_write(txh, off, len);
 620         } else {
 621                 /* first block will be modified if it is not aligned */
 622                 if (!IS_P2ALIGNED(off, 1 << dn->dn_datablkshift))
 623                         dmu_tx_count_write(txh, off, 1);
 624                 /* last block will be modified if it is not aligned */
 625                 if (!IS_P2ALIGNED(off + len, 1 << dn->dn_datablkshift))
 626                         dmu_tx_count_write(txh, off+len, 1);
 627         }
 628 
 629         /*
 630          * Check level-1 blocks.
 631          */
 632         if (dn->dn_nlevels > 1) {
 633                 int shift = dn->dn_datablkshift + dn->dn_indblkshift -
 634                     SPA_BLKPTRSHIFT;
 635                 uint64_t start = off >> shift;
 636                 uint64_t end = (off + len) >> shift;
 637 
 638                 ASSERT(dn->dn_datablkshift != 0);