View | Details | Raw Unified | Return to bug 207714
Collapse All | Expand All

(-)./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c (-1 / +7 lines)
Lines 20-26 Link Here
20
 */
20
 */
21
/*
21
/*
22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23
 * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
23
 * Copyright (c) 2013, 2015 by Delphix. All rights reserved.
24
 * Copyright 2014 HybridCluster. All rights reserved.
24
 * Copyright 2014 HybridCluster. All rights reserved.
25
 */
25
 */
26
26
Lines 50-55 Link Here
50
		 * reasonably sparse (at most 1/4 full).  Look from the
50
		 * reasonably sparse (at most 1/4 full).  Look from the
51
		 * beginning once, but after that keep looking from here.
51
		 * beginning once, but after that keep looking from here.
52
		 * If we can't find one, just keep going from here.
52
		 * If we can't find one, just keep going from here.
53
		 *
54
		 * Note that dmu_traverse depends on the behavior that we use
55
		 * multiple blocks of the dnode object before going back to
56
		 * reuse objects.  Any change to this algorithm should preserve
57
		 * that property or find another solution to the issues described
58
		 * in traverse_visitbp.
53
		 */
59
		 */
54
		if (P2PHASE(object, L2_dnode_count) == 0) {
60
		if (P2PHASE(object, L2_dnode_count) == 0) {
55
			uint64_t offset = restarted ? object << DNODE_SHIFT : 0;
61
			uint64_t offset = restarted ? object << DNODE_SHIFT : 0;
(-)./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c (-13 / +36 lines)
Lines 20-26 Link Here
20
 */
20
 */
21
/*
21
/*
22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23
 * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
23
 * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
24
 * Copyright (c) 2015 Chunwei Chen. All rights reserved.
24
 * Copyright (c) 2015 Chunwei Chen. All rights reserved.
25
 */
25
 */
26
26
Lines 63-68 Link Here
63
	uint64_t td_hole_birth_enabled_txg;
63
	uint64_t td_hole_birth_enabled_txg;
64
	blkptr_cb_t *td_func;
64
	blkptr_cb_t *td_func;
65
	void *td_arg;
65
	void *td_arg;
66
	boolean_t td_realloc_possible;
66
} traverse_data_t;
67
} traverse_data_t;
67
68
68
static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
69
static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
Lines 232-249 Link Here
232
233
233
	if (bp->blk_birth == 0) {
234
	if (bp->blk_birth == 0) {
234
		/*
235
		/*
235
		 * Since this block has a birth time of 0 it must be a
236
		 * Since this block has a birth time of 0 it must be one of two
236
		 * hole created before the SPA_FEATURE_HOLE_BIRTH
237
		 * things: a hole created before the SPA_FEATURE_HOLE_BIRTH
237
		 * feature was enabled.  If SPA_FEATURE_HOLE_BIRTH
238
		 * feature was enabled, or a hole which has always been a hole
238
		 * was enabled before the min_txg for this traveral we
239
		 * in an object.  This occurs when an object is created and then
239
		 * know the hole must have been created before the
240
		 * a write is performed that leaves part of the file as zeroes.
240
		 * min_txg for this traveral, so we can skip it. If
241
		 * Normally we don't care about this case, but if this object
241
		 * SPA_FEATURE_HOLE_BIRTH was enabled after the min_txg
242
		 * has the same object number as an object that has been
242
		 * for this traveral we cannot tell if the hole was
243
		 * destroyed, callers of dmu_traverse may not be able to tell
243
		 * created before or after the min_txg for this
244
		 * that the object has been recreated.  Thus, we must give them
244
		 * traversal, so we cannot skip it.
245
		 * all of the holes with birth == 0 in any objects that may have
246
		 * been recreated. Thus, we cannot skip the block if it is
247
		 * possible the object has been recreated. If it isn't, then if
248
		 * SPA_FEATURE_HOLE_BIRTH was enabled before the min_txg for
249
		 * this traversal we know the hole must have been created before
250
		 * the min_txg for this traversal, so we can skip it. If
251
		 * SPA_FEATURE_HOLE_BIRTH was enabled after the min_txg for this
252
		 * traversal we cannot tell if the hole was created before or
253
		 * after the min_txg for this traversal, so we cannot skip it.
254
		 * Note that the meta-dnode cannot be reallocated, so we needn't
255
		 * worry about that case.
245
		 */
256
		 */
246
		if (td->td_hole_birth_enabled_txg < td->td_min_txg)
257
		if ((!td->td_realloc_possible ||
258
		    zb->zb_object == DMU_META_DNODE_OBJECT) &&
259
		    td->td_hole_birth_enabled_txg <= td->td_min_txg)
247
			return (0);
260
			return (0);
248
	} else if (bp->blk_birth <= td->td_min_txg) {
261
	} else if (bp->blk_birth <= td->td_min_txg) {
249
		return (0);
262
		return (0);
Lines 338-343 Link Here
338
		objset_phys_t *osp = buf->b_data;
351
		objset_phys_t *osp = buf->b_data;
339
		prefetch_dnode_metadata(td, &osp->os_meta_dnode, zb->zb_objset,
352
		prefetch_dnode_metadata(td, &osp->os_meta_dnode, zb->zb_objset,
340
		    DMU_META_DNODE_OBJECT);
353
		    DMU_META_DNODE_OBJECT);
354
		/*
355
		 * See the block comment above for the goal of this variable.
356
		 * If the maxblkid of the meta-dnode is 0, then we know that
357
		 * we've never had more than DNODES_PER_BLOCK objects in the
358
		 * dataset, which means we can't have reused any object ids.
359
		 */
360
		if (osp->os_meta_dnode.dn_maxblkid == 0)
361
			td->td_realloc_possible = B_FALSE;
362
341
		if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
363
		if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
342
			prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
364
			prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
343
			    zb->zb_objset, DMU_GROUPUSED_OBJECT);
365
			    zb->zb_objset, DMU_GROUPUSED_OBJECT);
Lines 544-555 Link Here
544
	td.td_pfd = &pd;
566
	td.td_pfd = &pd;
545
	td.td_flags = flags;
567
	td.td_flags = flags;
546
	td.td_paused = B_FALSE;
568
	td.td_paused = B_FALSE;
569
	td.td_realloc_possible = (txg_start == 0 ? B_FALSE : B_TRUE);
547
570
548
	if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
571
	if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
549
		VERIFY(spa_feature_enabled_txg(spa,
572
		VERIFY(spa_feature_enabled_txg(spa,
550
		    SPA_FEATURE_HOLE_BIRTH, &td.td_hole_birth_enabled_txg));
573
		    SPA_FEATURE_HOLE_BIRTH, &td.td_hole_birth_enabled_txg));
551
	} else {
574
	} else {
552
		td.td_hole_birth_enabled_txg = 0;
575
		td.td_hole_birth_enabled_txg = UINT64_MAX;
553
	}
576
	}
554
577
555
	pd.pd_flags = flags;
578
	pd.pd_flags = flags;

Return to bug 207714