618 if (off != 0 || len < dn->dn_datablksz)
619 dmu_tx_count_write(txh, 0, dn->dn_datablksz);
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);
639 ASSERT(dn->dn_indblkshift != 0);
640
641 zio = zio_root(tx->tx_pool->dp_spa,
642 NULL, NULL, ZIO_FLAG_CANFAIL);
643 for (uint64_t i = start; i <= end; i++) {
644 uint64_t ibyte = i << shift;
645 err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0);
646 i = ibyte >> shift;
647 if (err == ESRCH)
648 break;
649 if (err) {
650 tx->tx_err = err;
651 return;
652 }
653
654 err = dmu_tx_check_ioerr(zio, dn, 1, i);
655 if (err) {
656 tx->tx_err = err;
657 return;
658 }
659 }
660 err = zio_wait(zio);
|
618 if (off != 0 || len < dn->dn_datablksz)
619 dmu_tx_count_write(txh, 0, dn->dn_datablksz);
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_indblkshift != 0);
639
640 /*
641 * dnode_reallocate() can result in an object with indirect
642 * blocks having an odd data block size. In this case,
643 * just check the single block.
644 */
645 if (dn->dn_datablkshift == 0)
646 start = end = 0;
647
648 zio = zio_root(tx->tx_pool->dp_spa,
649 NULL, NULL, ZIO_FLAG_CANFAIL);
650 for (uint64_t i = start; i <= end; i++) {
651 uint64_t ibyte = i << shift;
652 err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0);
653 i = ibyte >> shift;
654 if (err == ESRCH)
655 break;
656 if (err) {
657 tx->tx_err = err;
658 return;
659 }
660
661 err = dmu_tx_check_ioerr(zio, dn, 1, i);
662 if (err) {
663 tx->tx_err = err;
664 return;
665 }
666 }
667 err = zio_wait(zio);
|