1 /* |
1 /* |
2 * CDDL HEADER START |
2 * CDDL HEADER START |
3 * |
3 * |
4 * The contents of this file are subject to the terms of the |
4 * The contents of this file are subject to the terms of the |
5 * Common Development and Distribution License, Version 1.0 only |
5 * Common Development and Distribution License (the "License"). |
6 * (the "License"). You may not use this file except in compliance |
6 * You may not use this file except in compliance with the License. |
7 * with the License. |
|
8 * |
7 * |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
10 * or http://www.opensolaris.org/os/licensing. |
9 * or http://www.opensolaris.org/os/licensing. |
11 * See the License for the specific language governing permissions |
10 * See the License for the specific language governing permissions |
12 * and limitations under the License. |
11 * and limitations under the License. |
337 error = 0; |
336 error = 0; |
338 th->th_arc_hits++; |
337 th->th_arc_hits++; |
339 } else { |
338 } else { |
340 error = zio_wait(zio_read(NULL, th->th_spa, bp, bc->bc_data, |
339 error = zio_wait(zio_read(NULL, th->th_spa, bp, bc->bc_data, |
341 BP_GET_LSIZE(bp), NULL, NULL, ZIO_PRIORITY_SYNC_READ, |
340 BP_GET_LSIZE(bp), NULL, NULL, ZIO_PRIORITY_SYNC_READ, |
342 th->th_zio_flags | ZIO_FLAG_DONT_CACHE)); |
341 th->th_zio_flags | ZIO_FLAG_DONT_CACHE, zb)); |
343 |
342 |
344 if (BP_SHOULD_BYTESWAP(bp) && error == 0) |
343 if (BP_SHOULD_BYTESWAP(bp) && error == 0) |
345 (zb->zb_level > 0 ? byteswap_uint64_array : |
344 (zb->zb_level > 0 ? byteswap_uint64_array : |
346 dmu_ot[BP_GET_TYPE(bp)].ot_byteswap)(bc->bc_data, |
345 dmu_ot[BP_GET_TYPE(bp)].ot_byteswap)(bc->bc_data, |
347 BP_GET_LSIZE(bp)); |
346 BP_GET_LSIZE(bp)); |
467 *objectp = ZB_MAXOBJECT; |
466 *objectp = ZB_MAXOBJECT; |
468 |
467 |
469 return (rc); |
468 return (rc); |
470 } |
469 } |
471 |
470 |
|
471 /* ARGSUSED */ |
|
472 static void |
|
473 traverse_zil_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t maxtxg) |
|
474 { |
|
475 traverse_handle_t *th = arg; |
|
476 traverse_blk_cache_t *bc = &th->th_zil_cache; |
|
477 zbookmark_t *zb = &bc->bc_bookmark; |
|
478 |
|
479 if (bp->blk_birth < maxtxg) { |
|
480 zb->zb_object = 0; |
|
481 zb->zb_blkid = bp->blk_cksum.zc_word[3]; |
|
482 bc->bc_blkptr = *bp; |
|
483 (void) th->th_func(bc, th->th_spa, th->th_arg); |
|
484 } |
|
485 } |
|
486 |
|
487 /* ARGSUSED */ |
|
488 static void |
|
489 traverse_zil_record(zilog_t *zilog, lr_t *lrc, void *arg, uint64_t maxtxg) |
|
490 { |
|
491 traverse_handle_t *th = arg; |
|
492 traverse_blk_cache_t *bc = &th->th_zil_cache; |
|
493 zbookmark_t *zb = &bc->bc_bookmark; |
|
494 |
|
495 if (lrc->lrc_txtype == TX_WRITE) { |
|
496 lr_write_t *lr = (lr_write_t *)lrc; |
|
497 blkptr_t *bp = &lr->lr_blkptr; |
|
498 |
|
499 if (bp->blk_birth != 0 && bp->blk_birth < maxtxg) { |
|
500 zb->zb_object = lr->lr_foid; |
|
501 zb->zb_blkid = lr->lr_offset / BP_GET_LSIZE(bp); |
|
502 bc->bc_blkptr = *bp; |
|
503 (void) th->th_func(bc, th->th_spa, th->th_arg); |
|
504 } |
|
505 } |
|
506 } |
|
507 |
|
508 static void |
|
509 traverse_zil(traverse_handle_t *th, traverse_blk_cache_t *bc, uint64_t maxtxg) |
|
510 { |
|
511 spa_t *spa = th->th_spa; |
|
512 objset_phys_t *osphys = bc->bc_data; |
|
513 dsl_pool_t *dp = spa_get_dsl(spa); |
|
514 zilog_t *zilog; |
|
515 |
|
516 ASSERT(bc == &th->th_cache[ZB_MDN_CACHE][ZB_MAXLEVEL - 1]); |
|
517 ASSERT(bc->bc_bookmark.zb_level == -1); |
|
518 |
|
519 th->th_zil_cache.bc_bookmark = bc->bc_bookmark; |
|
520 |
|
521 zilog = zil_alloc(dp->dp_meta_objset, &osphys->os_zil_header); |
|
522 |
|
523 zil_parse(zilog, traverse_zil_block, traverse_zil_record, th, maxtxg); |
|
524 |
|
525 zil_free(zilog); |
|
526 } |
|
527 |
472 static int |
528 static int |
473 traverse_segment(traverse_handle_t *th, zseg_t *zseg, blkptr_t *mosbp) |
529 traverse_segment(traverse_handle_t *th, zseg_t *zseg, blkptr_t *mosbp) |
474 { |
530 { |
475 zbookmark_t *zb = &zseg->seg_start; |
531 zbookmark_t *zb = &zseg->seg_start; |
476 traverse_blk_cache_t *bc; |
532 traverse_blk_cache_t *bc; |
477 dnode_phys_t *dn, *dn_tmp; |
533 dnode_phys_t *dn, *dn_tmp; |
478 int worklimit = 1000; |
534 int worklimit = 100; |
479 int rc; |
535 int rc; |
480 |
536 |
481 dprintf("<%llu, %llu, %d, %llx>\n", |
537 dprintf("<%llu, %llu, %d, %llx>\n", |
482 zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid); |
538 zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid); |
483 |
539 |
527 MAX(zseg->seg_mintxg, dsp->ds_prev_snap_txg); |
583 MAX(zseg->seg_mintxg, dsp->ds_prev_snap_txg); |
528 } |
584 } |
529 |
585 |
530 if (zb->zb_level == -1) { |
586 if (zb->zb_level == -1) { |
531 ASSERT(zb->zb_object == 0); |
587 ASSERT(zb->zb_object == 0); |
|
588 ASSERT(zb->zb_blkid == 0); |
|
589 ASSERT(BP_GET_TYPE(&bc->bc_blkptr) == DMU_OT_OBJSET); |
532 |
590 |
533 if (bc->bc_blkptr.blk_birth > zseg->seg_mintxg) { |
591 if (bc->bc_blkptr.blk_birth > zseg->seg_mintxg) { |
534 rc = traverse_callback(th, zseg, bc); |
592 rc = traverse_callback(th, zseg, bc); |
535 if (rc) { |
593 if (rc) { |
536 ASSERT(rc == EINTR); |
594 ASSERT(rc == EINTR); |
537 return (rc); |
595 return (rc); |
538 } |
596 } |
|
597 if ((th->th_advance & ADVANCE_ZIL) && |
|
598 zb->zb_objset != 0) |
|
599 traverse_zil(th, bc, zseg->seg_maxtxg); |
539 } |
600 } |
540 |
601 |
541 return (advance_from_osphys(zseg, th->th_advance)); |
602 return (advance_from_osphys(zseg, th->th_advance)); |
542 } |
603 } |
543 |
604 |