Skip to content

Commit

Permalink
Fix generation of non-standard "scan" and "bptree_obj" in object dire…
Browse files Browse the repository at this point in the history
…ctory.

Commit 1421c89 expanded the size of a zbookmark_t from 24 to 25 64-bit
values which similarly expands the size of the "scan" entry in the pool's
object directory and causes the pool to become un-importable by other
OpenZFS implementations.

This commit renames "struct zbookmark" to "struct zbookmark_phys" since
it is related to an on-disk format and adds a new "struct zbookmark" that
contains the former as its first member.  The effect is that the "struct
zbookmark" items written to the object directory in both the "scan" and
"bptree_obj" entries contain only the correct subset of the bookmark.

Fixes openzfs#2094
  • Loading branch information
dweeezil committed Feb 3, 2014
1 parent 8b46464 commit 89a6e7c
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 151 deletions.
50 changes: 25 additions & 25 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -941,16 +941,16 @@ static uint64_t
blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb)
{
if (dnp == NULL) {
ASSERT(zb->zb_level < 0);
if (zb->zb_object == 0)
return (zb->zb_blkid);
return (zb->zb_blkid * BP_GET_LSIZE(bp));
ASSERT(zb->zb_phys.zb_level < 0);
if (zb->zb_phys.zb_object == 0)
return (zb->zb_phys.zb_blkid);
return (zb->zb_phys.zb_blkid * BP_GET_LSIZE(bp));
}

ASSERT(zb->zb_level >= 0);
ASSERT(zb->zb_phys.zb_level >= 0);

return ((zb->zb_blkid <<
(zb->zb_level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) *
return ((zb->zb_phys.zb_blkid <<
(zb->zb_phys.zb_level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) *
dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
}

Expand Down Expand Up @@ -991,15 +991,15 @@ print_indirect(blkptr_t *bp, const zbookmark_t *zb,
int l;

ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_phys.zb_level);

(void) printf("%16llx ", (u_longlong_t)blkid2offset(dnp, bp, zb));

ASSERT(zb->zb_level >= 0);
ASSERT(zb->zb_phys.zb_level >= 0);

for (l = dnp->dn_nlevels - 1; l >= -1; l--) {
if (l == zb->zb_level) {
(void) printf("L%llx", (u_longlong_t)zb->zb_level);
if (l == zb->zb_phys.zb_level) {
(void) printf("L%llx", (u_longlong_t)zb->zb_phys.zb_level);
} else {
(void) printf(" ");
}
Expand Down Expand Up @@ -1039,9 +1039,9 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
for (i = 0; i < epb; i++, cbp++) {
zbookmark_t czb;

SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
SET_BOOKMARK(&czb, zb->zb_phys.zb_objset, zb->zb_phys.zb_object,
zb->zb_phys.zb_level - 1,
zb->zb_phys.zb_blkid * epb + i);
err = visit_indirect(spa, dnp, cbp, &czb);
if (err)
break;
Expand All @@ -1068,7 +1068,7 @@ dump_indirect(dnode_t *dn)
SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
dn->dn_object, dnp->dn_nlevels - 1, 0);
for (j = 0; j < dnp->dn_nblkptr; j++) {
czb.zb_blkid = j;
czb.zb_phys.zb_blkid = j;
(void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
&dnp->dn_blkptr[j], &czb);
}
Expand Down Expand Up @@ -2166,10 +2166,10 @@ zdb_blkptr_done(zio_t *zio)
"Got error %d reading "
"<%llu, %llu, %lld, %llx> %s -- skipping\n",
ioerr,
(u_longlong_t)zb->zb_objset,
(u_longlong_t)zb->zb_object,
(u_longlong_t)zb->zb_level,
(u_longlong_t)zb->zb_blkid,
(u_longlong_t)zb->zb_phys.zb_objset,
(u_longlong_t)zb->zb_phys.zb_object,
(u_longlong_t)zb->zb_phys.zb_level,
(u_longlong_t)zb->zb_phys.zb_blkid,
blkbuf);
}
mutex_exit(&spa->spa_scrub_lock);
Expand Down Expand Up @@ -2200,7 +2200,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;

/* If it's an intent log block, failure is expected. */
if (zb->zb_level == ZB_ZIL_LEVEL)
if (zb->zb_phys.zb_level == ZB_ZIL_LEVEL)
flags |= ZIO_FLAG_SPECULATIVE;

mutex_enter(&spa->spa_scrub_lock);
Expand All @@ -2219,9 +2219,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
sprintf_blkptr(blkbuf, bp);
(void) printf("objset %llu object %llu "
"level %lld offset 0x%llx %s\n",
(u_longlong_t)zb->zb_objset,
(u_longlong_t)zb->zb_object,
(longlong_t)zb->zb_level,
(u_longlong_t)zb->zb_phys.zb_objset,
(u_longlong_t)zb->zb_phys.zb_object,
(longlong_t)zb->zb_phys.zb_level,
(u_longlong_t)blkid2offset(dnp, bp, zb),
blkbuf);
}
Expand Down Expand Up @@ -2593,10 +2593,10 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
if (bp == NULL)
return (0);

if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
if (dump_opt['S'] > 1 && zb->zb_phys.zb_level == ZB_ROOT_LEVEL) {
(void) printf("traversing objset %llu, %llu objects, "
"%lu blocks so far\n",
(u_longlong_t)zb->zb_objset,
(u_longlong_t)zb->zb_phys.zb_objset,
(u_longlong_t)bp->blk_fill,
avl_numnodes(t));
}
Expand Down
33 changes: 22 additions & 11 deletions include/sys/zio.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,21 +255,32 @@ extern const char *zio_type_name[ZIO_TYPES];
* Therefore it must not change size or alignment between 32/64 bit
* compilation options.
*/
struct zbookmark {
struct zbookmark_phys {
uint64_t zb_objset;
uint64_t zb_object;
int64_t zb_level;
uint64_t zb_blkid;
};

struct zbookmark {
/*
* The zbookmark_phys must be the first member.
*/
struct zbookmark_phys zb_phys;

/*
* Add additional members here; they're not stored on-disk.
*/
char * zb_func;
};

#define SET_BOOKMARK(zb, objset, object, level, blkid) \
{ \
(zb)->zb_objset = objset; \
(zb)->zb_object = object; \
(zb)->zb_level = level; \
(zb)->zb_blkid = blkid; \
(zb)->zb_func = FTAG; \
(zb)->zb_phys.zb_objset = objset; \
(zb)->zb_phys.zb_object = object; \
(zb)->zb_phys.zb_level = level; \
(zb)->zb_phys.zb_blkid = blkid; \
(zb)->zb_func = FTAG; \
}

#define ZB_DESTROYED_OBJSET (-1ULL)
Expand All @@ -282,12 +293,12 @@ struct zbookmark {
#define ZB_ZIL_LEVEL (-2LL)

#define ZB_IS_ZERO(zb) \
((zb)->zb_objset == 0 && (zb)->zb_object == 0 && \
(zb)->zb_level == 0 && (zb)->zb_blkid == 0)
((zb)->zb_phys.zb_objset == 0 && (zb)->zb_phys.zb_object == 0 && \
(zb)->zb_phys.zb_level == 0 && (zb)->zb_phys.zb_blkid == 0)
#define ZB_IS_ROOT(zb) \
((zb)->zb_object == ZB_ROOT_OBJECT && \
(zb)->zb_level == ZB_ROOT_LEVEL && \
(zb)->zb_blkid == ZB_ROOT_BLKID)
((zb)->zb_phys.zb_object == ZB_ROOT_OBJECT && \
(zb)->zb_phys.zb_level == ZB_ROOT_LEVEL && \
(zb)->zb_phys.zb_blkid == ZB_ROOT_BLKID)

typedef struct zio_prop {
enum zio_checksum zp_checksum;
Expand Down
8 changes: 4 additions & 4 deletions lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -3568,19 +3568,19 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
nvlist_t *nv;

/* ignoring zb_blkid and zb_level for now */
if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
zb[i-1].zb_object == zb[i].zb_object)
if (i > 0 && zb[i-1].zb_phys.zb_objset == zb[i].zb_phys.zb_objset &&
zb[i-1].zb_phys.zb_object == zb[i].zb_phys.zb_object)
continue;

if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
goto nomem;
if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
zb[i].zb_objset) != 0) {
zb[i].zb_phys.zb_objset) != 0) {
nvlist_free(nv);
goto nomem;
}
if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
zb[i].zb_object) != 0) {
zb[i].zb_phys.zb_object) != 0) {
nvlist_free(nv);
goto nomem;
}
Expand Down
4 changes: 2 additions & 2 deletions module/zfs/bptree.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
if (free) {
if (err == ERESTART) {
/* save bookmark for future resume */
ASSERT3U(bte.be_zb.zb_objset, ==,
ASSERT3U(bte.be_zb.zb_phys.zb_objset, ==,
ZB_DESTROYED_OBJSET);
ASSERT0(bte.be_zb.zb_level);
ASSERT0(bte.be_zb.zb_phys.zb_level);
dmu_write(os, obj, i * sizeof (bte),
sizeof (bte), &bte, tx);
break;
Expand Down
10 changes: 5 additions & 5 deletions module/zfs/dmu_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,18 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
if (issig(JUSTLOOKING) && issig(FORREAL))
return (SET_ERROR(EINTR));

if (zb->zb_object != DMU_META_DNODE_OBJECT)
if (zb->zb_phys.zb_object != DMU_META_DNODE_OBJECT)
return (0);

if (bp == NULL) {
uint64_t span = DBP_SPAN(dnp, zb->zb_level);
uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
uint64_t span = DBP_SPAN(dnp, zb->zb_phys.zb_level);
uint64_t dnobj = (zb->zb_phys.zb_blkid * span) >> DNODE_SHIFT;

err = report_free_dnode_range(da, dnobj,
dnobj + (span >> DNODE_SHIFT) - 1);
if (err)
return (err);
} else if (zb->zb_level == 0) {
} else if (zb->zb_phys.zb_level == 0) {
dnode_phys_t *blk;
arc_buf_t *abuf;
uint32_t aflags = ARC_WAIT;
Expand All @@ -140,7 +140,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,

blk = abuf->b_data;
for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
uint64_t dnobj = (zb->zb_blkid <<
uint64_t dnobj = (zb->zb_phys.zb_blkid <<
(DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
err = report_dnode(da, dnobj, blk+i);
if (err)
Expand Down
22 changes: 11 additions & 11 deletions module/zfs/dmu_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,17 +382,17 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
if (issig(JUSTLOOKING) && issig(FORREAL))
return (SET_ERROR(EINTR));

if (zb->zb_object != DMU_META_DNODE_OBJECT &&
DMU_OBJECT_IS_SPECIAL(zb->zb_object)) {
if (zb->zb_phys.zb_object != DMU_META_DNODE_OBJECT &&
DMU_OBJECT_IS_SPECIAL(zb->zb_phys.zb_object)) {
return (0);
} else if (bp == NULL && zb->zb_object == DMU_META_DNODE_OBJECT) {
uint64_t span = BP_SPAN(dnp, zb->zb_level);
uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
} else if (bp == NULL && zb->zb_phys.zb_object == DMU_META_DNODE_OBJECT) {
uint64_t span = BP_SPAN(dnp, zb->zb_phys.zb_level);
uint64_t dnobj = (zb->zb_phys.zb_blkid * span) >> DNODE_SHIFT;
err = dump_freeobjects(dsp, dnobj, span >> DNODE_SHIFT);
} else if (bp == NULL) {
uint64_t span = BP_SPAN(dnp, zb->zb_level);
err = dump_free(dsp, zb->zb_object, zb->zb_blkid * span, span);
} else if (zb->zb_level > 0 || type == DMU_OT_OBJSET) {
uint64_t span = BP_SPAN(dnp, zb->zb_phys.zb_level);
err = dump_free(dsp, zb->zb_phys.zb_object, zb->zb_phys.zb_blkid * span, span);
} else if (zb->zb_phys.zb_level > 0 || type == DMU_OT_OBJSET) {
return (0);
} else if (type == DMU_OT_DNODE) {
dnode_phys_t *blk;
Expand All @@ -408,7 +408,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,

blk = abuf->b_data;
for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
uint64_t dnobj = (zb->zb_blkid <<
uint64_t dnobj = (zb->zb_phys.zb_blkid <<
(DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
err = dump_dnode(dsp, dnobj, blk+i);
if (err != 0)
Expand All @@ -425,7 +425,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
&aflags, zb) != 0)
return (SET_ERROR(EIO));

err = dump_spill(dsp, zb->zb_object, blksz, abuf->b_data);
err = dump_spill(dsp, zb->zb_phys.zb_object, blksz, abuf->b_data);
(void) arc_buf_remove_ref(abuf, &abuf);
} else { /* it's a level-0 block of a regular object */
uint32_t aflags = ARC_WAIT;
Expand All @@ -449,7 +449,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
}
}

err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
err = dump_data(dsp, type, zb->zb_phys.zb_object, zb->zb_phys.zb_blkid * blksz,
blksz, bp, abuf->b_data);
(void) arc_buf_remove_ref(abuf, &abuf);
}
Expand Down
36 changes: 18 additions & 18 deletions module/zfs/dmu_traverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp,
* If we found the block we're trying to resume from, zero
* the bookmark out to indicate that we have resumed.
*/
ASSERT3U(zb->zb_object, <=, td->td_resume->zb_object);
ASSERT3U(zb->zb_phys.zb_object, <=, td->td_resume->zb_phys.zb_object);
if (bcmp(zb, td->td_resume, sizeof (*zb)) == 0) {
bzero(td->td_resume, sizeof (*zb));
if (td->td_flags & TRAVERSE_POST)
Expand All @@ -178,7 +178,7 @@ static void
traverse_pause(traverse_data_t *td, const zbookmark_t *zb)
{
ASSERT(td->td_resume != NULL);
ASSERT0(zb->zb_level);
ASSERT0(zb->zb_phys.zb_level);
bcopy(zb, td->td_resume, sizeof (*td->td_resume));
}

Expand Down Expand Up @@ -271,18 +271,18 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
czb = kmem_alloc(sizeof (zbookmark_t), KM_PUSHPAGE);

for (i = 0; i < epb; i++) {
SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
SET_BOOKMARK(czb, zb->zb_phys.zb_objset, zb->zb_phys.zb_object,
zb->zb_phys.zb_level - 1,
zb->zb_phys.zb_blkid * epb + i);
traverse_prefetch_metadata(td,
&((blkptr_t *)buf->b_data)[i], czb);
}

/* recursively visitbp() blocks below this */
for (i = 0; i < epb; i++) {
SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
SET_BOOKMARK(czb, zb->zb_phys.zb_objset, zb->zb_phys.zb_object,
zb->zb_phys.zb_level - 1,
zb->zb_phys.zb_blkid * epb + i);
err = traverse_visitbp(td, dnp,
&((blkptr_t *)buf->b_data)[i], czb);
if (err != 0) {
Expand All @@ -306,14 +306,14 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
dnp = buf->b_data;

for (i = 0; i < epb; i++) {
prefetch_dnode_metadata(td, &dnp[i], zb->zb_objset,
zb->zb_blkid * epb + i);
prefetch_dnode_metadata(td, &dnp[i], zb->zb_phys.zb_objset,
zb->zb_phys.zb_blkid * epb + i);
}

/* recursively visitbp() blocks below this */
for (i = 0; i < epb; i++) {
err = traverse_dnode(td, &dnp[i], zb->zb_objset,
zb->zb_blkid * epb + i);
err = traverse_dnode(td, &dnp[i], zb->zb_phys.zb_objset,
zb->zb_phys.zb_blkid * epb + i);
if (err != 0) {
if (!TD_HARD(td))
break;
Expand All @@ -332,24 +332,24 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,

osp = buf->b_data;
dnp = &osp->os_meta_dnode;
prefetch_dnode_metadata(td, dnp, zb->zb_objset,
prefetch_dnode_metadata(td, dnp, zb->zb_phys.zb_objset,
DMU_META_DNODE_OBJECT);
if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
zb->zb_objset, DMU_GROUPUSED_OBJECT);
zb->zb_phys.zb_objset, DMU_GROUPUSED_OBJECT);
prefetch_dnode_metadata(td, &osp->os_userused_dnode,
zb->zb_objset, DMU_USERUSED_OBJECT);
zb->zb_phys.zb_objset, DMU_USERUSED_OBJECT);
}

err = traverse_dnode(td, dnp, zb->zb_objset,
err = traverse_dnode(td, dnp, zb->zb_phys.zb_objset,
DMU_META_DNODE_OBJECT);
if (err && TD_HARD(td)) {
lasterr = err;
err = 0;
}
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
dnp = &osp->os_groupused_dnode;
err = traverse_dnode(td, dnp, zb->zb_objset,
err = traverse_dnode(td, dnp, zb->zb_phys.zb_objset,
DMU_GROUPUSED_OBJECT);
}
if (err && TD_HARD(td)) {
Expand All @@ -358,7 +358,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
}
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
dnp = &osp->os_userused_dnode;
err = traverse_dnode(td, dnp, zb->zb_objset,
err = traverse_dnode(td, dnp, zb->zb_phys.zb_objset,
DMU_USERUSED_OBJECT);
}
}
Expand Down
Loading

0 comments on commit 89a6e7c

Please sign in to comment.