Mercurial > illumos > illumos-gate
changeset 11724:a2728800460e
6848238 zdb -bcsv does not report all corruptions
author | Victor Latushkin <Victor.Latushkin@Sun.COM> |
---|---|
date | Sat, 20 Feb 2010 06:04:42 +0300 |
parents | b7b5ccb8e5c5 |
children | 68a79ddc6b27 |
files | usr/src/cmd/zdb/zdb.c usr/src/uts/common/fs/zfs/dmu_traverse.c usr/src/uts/common/fs/zfs/sys/dmu_traverse.h |
diffstat | 3 files changed, 56 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/zdb/zdb.c Fri Feb 19 18:04:10 2010 -0800 +++ b/usr/src/cmd/zdb/zdb.c Sat Feb 20 06:04:42 2010 +0300 @@ -1904,7 +1904,7 @@ zdb_cb_t zcb = { 0 }; zdb_blkstats_t *zb, *tzb; uint64_t norm_alloc, norm_space, total_alloc, total_found; - int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA; + int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD; int leaks = 0; (void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
--- a/usr/src/uts/common/fs/zfs/dmu_traverse.c Fri Feb 19 18:04:10 2010 -0800 +++ b/usr/src/uts/common/fs/zfs/dmu_traverse.c Sat Feb 20 06:04:42 2010 +0300 @@ -132,9 +132,10 @@ arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb) { zbookmark_t czb; - int err = 0; + int err = 0, lasterr = 0; arc_buf_t *buf = NULL; struct prefetch_data *pd = td->td_pfd; + boolean_t hard = td->td_flags & TRAVERSE_HARD; if (bp->blk_birth == 0) { err = td->td_func(td->td_spa, NULL, NULL, zb, dnp, td->td_arg); @@ -181,8 +182,11 @@ zb->zb_level - 1, zb->zb_blkid * epb + i); err = traverse_visitbp(td, dnp, buf, cbp, &czb); - if (err) - break; + if (err) { + if (!hard) + break; + lasterr = err; + } } } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { uint32_t flags = ARC_WAIT; @@ -197,11 +201,14 @@ /* recursively visitbp() blocks below this */ dnp = buf->b_data; - for (i = 0; i < epb && err == 0; i++, dnp++) { + for (i = 0; i < epb; i++, dnp++) { err = traverse_dnode(td, dnp, buf, zb->zb_objset, zb->zb_blkid * epb + i); - if (err) - break; + if (err) { + if (!hard) + break; + lasterr = err; + } } } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { uint32_t flags = ARC_WAIT; @@ -220,11 +227,19 @@ dnp = &osp->os_meta_dnode; err = traverse_dnode(td, dnp, buf, zb->zb_objset, DMU_META_DNODE_OBJECT); + if (err && hard) { + lasterr = err; + err = 0; + } if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) { dnp = &osp->os_userused_dnode; err = traverse_dnode(td, dnp, buf, zb->zb_objset, DMU_USERUSED_OBJECT); } + if (err && hard) { + 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, buf, zb->zb_objset, @@ -235,27 +250,31 @@ if (buf) (void) arc_buf_remove_ref(buf, &buf); - if (err == 0 && (td->td_flags & TRAVERSE_POST)) + if (err == 0 && lasterr == 0 && (td->td_flags & TRAVERSE_POST)) err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg); - return (err); + return (err != 0 ? err : lasterr); } static int traverse_dnode(struct traverse_data *td, const dnode_phys_t *dnp, arc_buf_t *buf, uint64_t objset, uint64_t object) { - int j, err = 0; + int j, err = 0, lasterr = 0; zbookmark_t czb; + boolean_t hard = (td->td_flags & TRAVERSE_HARD); for (j = 0; j < dnp->dn_nblkptr; j++) { SET_BOOKMARK(&czb, objset, object, dnp->dn_nlevels - 1, j); err = traverse_visitbp(td, dnp, buf, (blkptr_t *)&dnp->dn_blkptr[j], &czb); - if (err) - break; + if (err) { + if (!hard) + break; + lasterr = err; + } } - return (err); + return (err != 0 ? err : lasterr); } /* ARGSUSED */ @@ -379,10 +398,11 @@ traverse_pool(spa_t *spa, uint64_t txg_start, int flags, blkptr_cb_t func, void *arg) { - int err; + int err, lasterr = 0; uint64_t obj; dsl_pool_t *dp = spa_get_dsl(spa); objset_t *mos = dp->dp_meta_objset; + boolean_t hard = (flags & TRAVERSE_HARD); /* visit the MOS */ err = traverse_impl(spa, 0, spa_get_rootblkptr(spa), @@ -391,13 +411,17 @@ return (err); /* visit each dataset */ - for (obj = 1; err == 0; err = dmu_object_next(mos, &obj, FALSE, - txg_start)) { + for (obj = 1; err == 0 || (err != ESRCH && hard); + err = dmu_object_next(mos, &obj, FALSE, txg_start)) { dmu_object_info_t doi; err = dmu_object_info(mos, obj, &doi); - if (err) - return (err); + if (err) { + if (!hard) + return (err); + lasterr = err; + continue; + } if (doi.doi_type == DMU_OT_DSL_DATASET) { dsl_dataset_t *ds; @@ -406,17 +430,24 @@ rw_enter(&dp->dp_config_rwlock, RW_READER); err = dsl_dataset_hold_obj(dp, obj, FTAG, &ds); rw_exit(&dp->dp_config_rwlock); - if (err) - return (err); + if (err) { + if (!hard) + return (err); + lasterr = err; + continue; + } if (ds->ds_phys->ds_prev_snap_txg > txg) txg = ds->ds_phys->ds_prev_snap_txg; err = traverse_dataset(ds, txg, flags, func, arg); dsl_dataset_rele(ds, FTAG); - if (err) - return (err); + if (err) { + if (!hard) + return (err); + lasterr = err; + } } } if (err == ESRCH) err = 0; - return (err); + return (err != 0 ? err : lasterr); }
--- a/usr/src/uts/common/fs/zfs/sys/dmu_traverse.h Fri Feb 19 18:04:10 2010 -0800 +++ b/usr/src/uts/common/fs/zfs/sys/dmu_traverse.h Sat Feb 20 06:04:42 2010 +0300 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,6 +46,7 @@ #define TRAVERSE_PREFETCH_METADATA (1<<2) #define TRAVERSE_PREFETCH_DATA (1<<3) #define TRAVERSE_PREFETCH (TRAVERSE_PREFETCH_METADATA | TRAVERSE_PREFETCH_DATA) +#define TRAVERSE_HARD (1<<4) int traverse_dataset(struct dsl_dataset *ds, uint64_t txg_start, int flags, blkptr_cb_t func, void *arg);