usr/src/uts/common/fs/zfs/dmu_traverse.c
changeset 1544 938876158511
parent 928 36d72fe4da29
child 1601 438b928f80c7
equal deleted inserted replaced
1543:a02daabdf1b3 1544:938876158511
     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.
    18  * information: Portions Copyright [yyyy] [name of copyright owner]
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    19  *
    18  *
    20  * CDDL HEADER END
    19  * CDDL HEADER END
    21  */
    20  */
    22 /*
    21 /*
    23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
    22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
    24  * Use is subject to license terms.
    23  * Use is subject to license terms.
    25  */
    24  */
    26 
    25 
    27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    28 
    27 
   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