FreeBSD Bugzilla – Attachment 167864 Details for
Bug 207714
[zfs] send/receive does not recreate holes correctly
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch applicable to releng/10.3
patch.txt (text/plain), 4.98 KB, created by
Martin Birgmeier
on 2016-03-08 18:10:14 UTC
(
hide
)
Description:
patch applicable to releng/10.3
Filename:
MIME Type:
Creator:
Martin Birgmeier
Created:
2016-03-08 18:10:14 UTC
Size:
4.98 KB
patch
obsolete
>--- ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c.ORIG 2016-03-05 14:06:30.367932144 +0100 >+++ ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c 2016-03-06 18:08:48.479622033 +0100 >@@ -20,7 +20,7 @@ > */ > /* > * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. >- * Copyright (c) 2013, 2014 by Delphix. All rights reserved. >+ * Copyright (c) 2013, 2015 by Delphix. All rights reserved. > * Copyright 2014 HybridCluster. All rights reserved. > */ > >@@ -50,6 +50,12 @@ > * reasonably sparse (at most 1/4 full). Look from the > * beginning once, but after that keep looking from here. > * If we can't find one, just keep going from here. >+ * >+ * Note that dmu_traverse depends on the behavior that we use >+ * multiple blocks of the dnode object before going back to >+ * reuse objects. Any change to this algorithm should preserve >+ * that property or find another solution to the issues described >+ * in traverse_visitbp. > */ > if (P2PHASE(object, L2_dnode_count) == 0) { > uint64_t offset = restarted ? object << DNODE_SHIFT : 0; >--- ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c.ORIG 2016-03-05 14:06:30.351992125 +0100 >+++ ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c 2016-03-06 18:08:48.516597206 +0100 >@@ -20,7 +20,7 @@ > */ > /* > * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. >- * Copyright (c) 2012, 2014 by Delphix. All rights reserved. >+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved. > * Copyright (c) 2015 Chunwei Chen. All rights reserved. > */ > >@@ -63,6 +63,7 @@ > uint64_t td_hole_birth_enabled_txg; > blkptr_cb_t *td_func; > void *td_arg; >+ boolean_t td_realloc_possible; > } traverse_data_t; > > static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp, >@@ -232,18 +233,30 @@ > > if (bp->blk_birth == 0) { > /* >- * Since this block has a birth time of 0 it must be a >- * hole created before the SPA_FEATURE_HOLE_BIRTH >- * feature was enabled. If SPA_FEATURE_HOLE_BIRTH >- * was enabled before the min_txg for this traveral we >- * know the hole must have been created before the >- * min_txg for this traveral, so we can skip it. If >- * SPA_FEATURE_HOLE_BIRTH was enabled after the min_txg >- * for this traveral we cannot tell if the hole was >- * created before or after the min_txg for this >- * traversal, so we cannot skip it. >+ * Since this block has a birth time of 0 it must be one of two >+ * things: a hole created before the SPA_FEATURE_HOLE_BIRTH >+ * feature was enabled, or a hole which has always been a hole >+ * in an object. This occurs when an object is created and then >+ * a write is performed that leaves part of the file as zeroes. >+ * Normally we don't care about this case, but if this object >+ * has the same object number as an object that has been >+ * destroyed, callers of dmu_traverse may not be able to tell >+ * that the object has been recreated. Thus, we must give them >+ * all of the holes with birth == 0 in any objects that may have >+ * been recreated. Thus, we cannot skip the block if it is >+ * possible the object has been recreated. If it isn't, then if >+ * SPA_FEATURE_HOLE_BIRTH was enabled before the min_txg for >+ * this traversal we know the hole must have been created before >+ * the min_txg for this traversal, so we can skip it. If >+ * SPA_FEATURE_HOLE_BIRTH was enabled after the min_txg for this >+ * traversal we cannot tell if the hole was created before or >+ * after the min_txg for this traversal, so we cannot skip it. >+ * Note that the meta-dnode cannot be reallocated, so we needn't >+ * worry about that case. > */ >- if (td->td_hole_birth_enabled_txg < td->td_min_txg) >+ if ((!td->td_realloc_possible || >+ zb->zb_object == DMU_META_DNODE_OBJECT) && >+ td->td_hole_birth_enabled_txg <= td->td_min_txg) > return (0); > } else if (bp->blk_birth <= td->td_min_txg) { > return (0); >@@ -338,6 +351,15 @@ > objset_phys_t *osp = buf->b_data; > prefetch_dnode_metadata(td, &osp->os_meta_dnode, zb->zb_objset, > DMU_META_DNODE_OBJECT); >+ /* >+ * See the block comment above for the goal of this variable. >+ * If the maxblkid of the meta-dnode is 0, then we know that >+ * we've never had more than DNODES_PER_BLOCK objects in the >+ * dataset, which means we can't have reused any object ids. >+ */ >+ if (osp->os_meta_dnode.dn_maxblkid == 0) >+ td->td_realloc_possible = B_FALSE; >+ > if (arc_buf_size(buf) >= sizeof (objset_phys_t)) { > prefetch_dnode_metadata(td, &osp->os_groupused_dnode, > zb->zb_objset, DMU_GROUPUSED_OBJECT); >@@ -544,12 +566,13 @@ > td.td_pfd = &pd; > td.td_flags = flags; > td.td_paused = B_FALSE; >+ td.td_realloc_possible = (txg_start == 0 ? B_FALSE : B_TRUE); > > if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) { > VERIFY(spa_feature_enabled_txg(spa, > SPA_FEATURE_HOLE_BIRTH, &td.td_hole_birth_enabled_txg)); > } else { >- td.td_hole_birth_enabled_txg = 0; >+ td.td_hole_birth_enabled_txg = UINT64_MAX; > } > > pd.pd_flags = flags;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 207714
: 167864