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; |