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