Mercurial > illumos > illumos-gate
changeset 1793:d371fba21a3e
6407444 unhandled i/o error from dnode_next_offset_level()
6411780 unhandled i/o error from dnode_sync_free() due to faulty pre-read logic
author | ahrens |
---|---|
date | Tue, 11 Apr 2006 15:06:44 -0700 |
parents | 7e25f1c5948e |
children | bc0b5efe21a1 |
files | usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/uts/common/fs/zfs/dmu_tx.c usr/src/uts/common/fs/zfs/dnode.c |
diffstat | 3 files changed, 43 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Tue Apr 11 13:06:32 2006 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Tue Apr 11 15:06:44 2006 -0700 @@ -2073,6 +2073,15 @@ zhp->zfs_name); break; + case EIO: + /* + * I/O error. + */ + zfs_error(dgettext(TEXT_DOMAIN, + "cannot destroy '%s': I/O error"), + zhp->zfs_name); + break; + case ENOENT: /* * We've hit a race condition where the dataset has been
--- a/usr/src/uts/common/fs/zfs/dmu_tx.c Tue Apr 11 13:06:32 2006 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu_tx.c Tue Apr 11 15:06:44 2006 -0700 @@ -449,7 +449,7 @@ zio_t *zio; /* first block */ - if (off != 0 /* || dn->dn_maxblkid == 0 */) + if (off != 0) dmu_tx_count_write(tx, dn, off, 1); /* last block */ if (len != DMU_OBJECT_END) @@ -465,32 +465,36 @@ * blocks, and all the level-1 blocks. The above count_write's * will take care of the level-0 blocks. */ - shift = dn->dn_datablkshift + dn->dn_indblkshift - SPA_BLKPTRSHIFT; - start = off >> shift; - end = dn->dn_datablkshift ? ((off+len) >> shift) : 0; + if (dn->dn_nlevels > 1) { + shift = dn->dn_datablkshift + dn->dn_indblkshift - + SPA_BLKPTRSHIFT; + start = off >> shift; + end = dn->dn_datablkshift ? ((off+len) >> shift) : 0; - zio = zio_root(tx->tx_pool->dp_spa, NULL, NULL, ZIO_FLAG_CANFAIL); - for (i = start+1; i < end; i++) { - uint64_t ibyte = i << shift; - err = dnode_next_offset(dn, FALSE, &ibyte, 2, 1); - i = ibyte >> shift; - if (err == ESRCH) - break; + zio = zio_root(tx->tx_pool->dp_spa, + NULL, NULL, ZIO_FLAG_CANFAIL); + for (i = start; i <= end; i++) { + uint64_t ibyte = i << shift; + err = dnode_next_offset(dn, FALSE, &ibyte, 2, 1); + i = ibyte >> shift; + if (err == ESRCH) + break; + if (err) { + tx->tx_err = err; + return; + } + + err = dmu_tx_check_ioerr(zio, dn, 1, i); + if (err) { + tx->tx_err = err; + return; + } + } + err = zio_wait(zio); if (err) { tx->tx_err = err; return; } - - err = dmu_tx_check_ioerr(zio, dn, 1, i); - if (err) { - tx->tx_err = err; - return; - } - } - err = zio_wait(zio); - if (err) { - tx->tx_err = err; - return; } dmu_tx_count_dnode(tx, dn);
--- a/usr/src/uts/common/fs/zfs/dnode.c Tue Apr 11 13:06:32 2006 -0700 +++ b/usr/src/uts/common/fs/zfs/dnode.c Tue Apr 11 15:06:44 2006 -0700 @@ -1180,8 +1180,11 @@ return (hole ? 0 : ESRCH); return (error); } - (void) dbuf_read(db, NULL, - DB_RF_MUST_SUCCEED | DB_RF_HAVESTRUCT); + error = dbuf_read(db, NULL, DB_RF_CANFAIL | DB_RF_HAVESTRUCT); + if (error) { + dbuf_rele(db, FTAG); + return (error); + } data = db->db.db_data; } @@ -1275,7 +1278,7 @@ for (lvl = minlvl; lvl <= maxlvl; lvl++) { error = dnode_next_offset_level(dn, hole, offset, lvl, blkfill); - if (error == 0) + if (error != ESRCH) break; } @@ -1284,8 +1287,8 @@ rw_exit(&dn->dn_struct_rwlock); - if (initial_offset > *offset) - return (ESRCH); + if (error == 0 && initial_offset > *offset) + error = ESRCH; return (error); }