Mercurial > illumos > illumos-gate
changeset 10209:91f47f0e7728
6830541 zfs_get_data trips on a verify
6696242 multiple zfs_fillpage() zfs: accessing past end of object panics
6785914 zfs fails to drop dn_struct_rwlock in recovery code path
author | Mark J Musante <Mark.Musante@Sun.COM> |
---|---|
date | Thu, 30 Jul 2009 08:43:06 -0400 |
parents | 98cb0a515a01 |
children | a7483403391a |
files | usr/src/uts/common/fs/zfs/dmu.c usr/src/uts/common/fs/zfs/zfs_vnops.c usr/src/uts/common/fs/zfs/zil.c |
diffstat | 3 files changed, 28 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dmu.c Thu Jul 30 02:52:07 2009 -0400 +++ b/usr/src/uts/common/fs/zfs/dmu.c Thu Jul 30 08:43:06 2009 -0400 @@ -195,7 +195,7 @@ ASSERT(length <= DMU_MAX_ACCESS); - dbuf_flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT; + dbuf_flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT | DB_RF_HAVESTRUCT; if (flags & DMU_READ_NO_PREFETCH || length > zfetch_array_rd_sz) dbuf_flags |= DB_RF_NOPREFETCH; @@ -212,6 +212,7 @@ os_dsl_dataset->ds_object, (longlong_t)dn->dn_object, dn->dn_datablksz, (longlong_t)offset, (longlong_t)length); + rw_exit(&dn->dn_struct_rwlock); return (EIO); } nblks = 1; @@ -234,9 +235,7 @@ } /* initiate async i/o */ if (read) { - rw_exit(&dn->dn_struct_rwlock); (void) dbuf_read(db, zio, dbuf_flags); - rw_enter(&dn->dn_struct_rwlock, RW_READER); } dbp[i] = &db->db; } @@ -543,7 +542,7 @@ { dnode_t *dn; dmu_buf_t **dbp; - int numbufs, i, err; + int numbufs, err; err = dnode_hold(os->os, object, FTAG, &dn); if (err) @@ -554,7 +553,7 @@ * block. If we ever do the tail block optimization, we will need to * handle that here as well. */ - if (dn->dn_datablkshift == 0) { + if (dn->dn_maxblkid == 0) { int newsz = offset > dn->dn_datablksz ? 0 : MIN(size, dn->dn_datablksz - offset); bzero((char *)buf + newsz, size - newsz); @@ -563,6 +562,7 @@ while (size > 0) { uint64_t mylen = MIN(size, DMU_MAX_ACCESS / 2); + int i; /* * NB: we could do this block-at-a-time, but it's nice
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c Thu Jul 30 02:52:07 2009 -0400 +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c Thu Jul 30 08:43:06 2009 -0400 @@ -855,6 +855,10 @@ kmem_free(zgd, sizeof (zgd_t)); } +#ifdef DEBUG +static int zil_fault_io = 0; +#endif + /* * Get data to generate a TX_WRITE intent log record. */ @@ -936,7 +940,21 @@ zgd->zgd_rl = rl; zgd->zgd_zilog = zfsvfs->z_log; zgd->zgd_bp = &lr->lr_blkptr; - VERIFY(0 == dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db)); +#ifdef DEBUG + if (zil_fault_io) { + error = EIO; + zil_fault_io = 0; + } else { + error = dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db); + } +#else + error = dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db); +#endif + if (error != 0) { + kmem_free(zgd, sizeof (zgd_t)); + goto out; + } + ASSERT(boff == db->db_offset); lr->lr_blkoff = off - boff; error = dmu_sync(zio, db, &lr->lr_blkptr,
--- a/usr/src/uts/common/fs/zfs/zil.c Thu Jul 30 02:52:07 2009 -0400 +++ b/usr/src/uts/common/fs/zfs/zil.c Thu Jul 30 08:43:06 2009 -0400 @@ -926,6 +926,10 @@ } error = zilog->zl_get_data( itx->itx_private, lr, dbuf, lwb->lwb_zio); + if (error == EIO) { + txg_wait_synced(zilog->zl_dmu_pool, txg); + return (lwb); + } if (error) { ASSERT(error == ENOENT || error == EEXIST || error == EALREADY);