Deleted Added
full compact
dmu_traverse.c (289362) dmu_traverse.c (296610)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
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.
25 */
26
27#include <sys/zfs_context.h>
28#include <sys/dmu_objset.h>
29#include <sys/dmu_traverse.h>
30#include <sys/dsl_dataset.h>
31#include <sys/dsl_dir.h>

--- 26 unchanged lines hidden (view full) ---

58 uint64_t td_min_txg;
59 zbookmark_phys_t *td_resume;
60 int td_flags;
61 prefetch_data_t *td_pfd;
62 boolean_t td_paused;
63 uint64_t td_hole_birth_enabled_txg;
64 blkptr_cb_t *td_func;
65 void *td_arg;
24 * Copyright (c) 2015 Chunwei Chen. All rights reserved.
25 */
26
27#include <sys/zfs_context.h>
28#include <sys/dmu_objset.h>
29#include <sys/dmu_traverse.h>
30#include <sys/dsl_dataset.h>
31#include <sys/dsl_dir.h>

--- 26 unchanged lines hidden (view full) ---

58 uint64_t td_min_txg;
59 zbookmark_phys_t *td_resume;
60 int td_flags;
61 prefetch_data_t *td_pfd;
62 boolean_t td_paused;
63 uint64_t td_hole_birth_enabled_txg;
64 blkptr_cb_t *td_func;
65 void *td_arg;
66 boolean_t td_realloc_possible;
66} traverse_data_t;
67
68static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
69 uint64_t objset, uint64_t object);
70static void prefetch_dnode_metadata(traverse_data_t *td, const dnode_phys_t *,
71 uint64_t objset, uint64_t object);
72
73static int

--- 153 unchanged lines hidden (view full) ---

227 case RESUME_SKIP_NONE:
228 break;
229 default:
230 ASSERT(0);
231 }
232
233 if (bp->blk_birth == 0) {
234 /*
67} traverse_data_t;
68
69static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
70 uint64_t objset, uint64_t object);
71static void prefetch_dnode_metadata(traverse_data_t *td, const dnode_phys_t *,
72 uint64_t objset, uint64_t object);
73
74static int

--- 153 unchanged lines hidden (view full) ---

228 case RESUME_SKIP_NONE:
229 break;
230 default:
231 ASSERT(0);
232 }
233
234 if (bp->blk_birth == 0) {
235 /*
235 * Since this block has a birth time of 0 it must be a
236 * hole created before the SPA_FEATURE_HOLE_BIRTH
237 * feature was enabled. If SPA_FEATURE_HOLE_BIRTH
238 * was enabled before the min_txg for this traveral we
239 * know the hole must have been created before the
240 * min_txg for this traveral, so we can skip it. If
241 * SPA_FEATURE_HOLE_BIRTH was enabled after the min_txg
242 * for this traveral we cannot tell if the hole was
243 * created before or after the min_txg for this
244 * traversal, so we cannot skip it.
236 * Since this block has a birth time of 0 it must be one of
237 * two things: a hole created before the
238 * SPA_FEATURE_HOLE_BIRTH feature was enabled, or a hole
239 * which has always been a hole in an object.
240 *
241 * If a file is written sparsely, then the unwritten parts of
242 * the file were "always holes" -- that is, they have been
243 * holes since this object was allocated. However, we (and
244 * our callers) can not necessarily tell when an object was
245 * allocated. Therefore, if it's possible that this object
246 * was freed and then its object number reused, we need to
247 * visit all the holes with birth==0.
248 *
249 * If it isn't possible that the object number was reused,
250 * then if SPA_FEATURE_HOLE_BIRTH was enabled before we wrote
251 * all the blocks we will visit as part of this traversal,
252 * then this hole must have always existed, so we can skip
253 * it. We visit blocks born after (exclusive) td_min_txg.
254 *
255 * Note that the meta-dnode cannot be reallocated.
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);
248 } else if (bp->blk_birth <= td->td_min_txg) {
249 return (0);
250 }
251
252 if (pd != NULL && !pd->pd_exited && prefetch_needed(pd, bp)) {
253 uint64_t size = BP_GET_LSIZE(bp);
254 mutex_enter(&pd->pd_mtx);

--- 78 unchanged lines hidden (view full) ---

333 err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
334 ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
335 if (err != 0)
336 goto post;
337
338 objset_phys_t *osp = buf->b_data;
339 prefetch_dnode_metadata(td, &osp->os_meta_dnode, zb->zb_objset,
340 DMU_META_DNODE_OBJECT);
260 return (0);
261 } else if (bp->blk_birth <= td->td_min_txg) {
262 return (0);
263 }
264
265 if (pd != NULL && !pd->pd_exited && prefetch_needed(pd, bp)) {
266 uint64_t size = BP_GET_LSIZE(bp);
267 mutex_enter(&pd->pd_mtx);

--- 78 unchanged lines hidden (view full) ---

346 err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
347 ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
348 if (err != 0)
349 goto post;
350
351 objset_phys_t *osp = buf->b_data;
352 prefetch_dnode_metadata(td, &osp->os_meta_dnode, zb->zb_objset,
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)) {
342 prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
343 zb->zb_objset, DMU_GROUPUSED_OBJECT);
344 prefetch_dnode_metadata(td, &osp->os_userused_dnode,
345 zb->zb_objset, DMU_USERUSED_OBJECT);
346 }
347
348 err = traverse_dnode(td, &osp->os_meta_dnode, zb->zb_objset,

--- 190 unchanged lines hidden (view full) ---

539 td.td_rootbp = rootbp;
540 td.td_min_txg = txg_start;
541 td.td_resume = resume;
542 td.td_func = func;
543 td.td_arg = arg;
544 td.td_pfd = &pd;
545 td.td_flags = flags;
546 td.td_paused = B_FALSE;
363 if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
364 prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
365 zb->zb_objset, DMU_GROUPUSED_OBJECT);
366 prefetch_dnode_metadata(td, &osp->os_userused_dnode,
367 zb->zb_objset, DMU_USERUSED_OBJECT);
368 }
369
370 err = traverse_dnode(td, &osp->os_meta_dnode, zb->zb_objset,

--- 190 unchanged lines hidden (view full) ---

561 td.td_rootbp = rootbp;
562 td.td_min_txg = txg_start;
563 td.td_resume = resume;
564 td.td_func = func;
565 td.td_arg = arg;
566 td.td_pfd = &pd;
567 td.td_flags = flags;
568 td.td_paused = B_FALSE;
569 td.td_realloc_possible = (txg_start == 0 ? B_FALSE : B_TRUE);
547
548 if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
549 VERIFY(spa_feature_enabled_txg(spa,
550 SPA_FEATURE_HOLE_BIRTH, &td.td_hole_birth_enabled_txg));
551 } else {
570
571 if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
572 VERIFY(spa_feature_enabled_txg(spa,
573 SPA_FEATURE_HOLE_BIRTH, &td.td_hole_birth_enabled_txg));
574 } else {
552 td.td_hole_birth_enabled_txg = 0;
575 td.td_hole_birth_enabled_txg = UINT64_MAX;
553 }
554
555 pd.pd_flags = flags;
556 if (resume != NULL)
557 pd.pd_resume = *resume;
558 mutex_init(&pd.pd_mtx, NULL, MUTEX_DEFAULT, NULL);
559 cv_init(&pd.pd_cv, NULL, CV_DEFAULT, NULL);
560

--- 122 unchanged lines hidden ---
576 }
577
578 pd.pd_flags = flags;
579 if (resume != NULL)
580 pd.pd_resume = *resume;
581 mutex_init(&pd.pd_mtx, NULL, MUTEX_DEFAULT, NULL);
582 cv_init(&pd.pd_cv, NULL, CV_DEFAULT, NULL);
583

--- 122 unchanged lines hidden ---