Mercurial > illumos > illumos-gate
changeset 3668:dc5b9a9208ca
6513020 zio pipeline went out to lunch
author | gw25295 |
---|---|
date | Fri, 16 Feb 2007 13:39:57 -0800 |
parents | 089a83b5d0bc |
children | 4e8428f56972 |
files | usr/src/cmd/ztest/ztest.c usr/src/lib/libzpool/common/llib-lzpool usr/src/uts/common/fs/zfs/zil.c usr/src/uts/common/fs/zfs/zio.c |
diffstat | 4 files changed, 59 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/ztest/ztest.c Fri Feb 16 12:27:32 2007 -0800 +++ b/usr/src/cmd/ztest/ztest.c Fri Feb 16 13:39:57 2007 -0800 @@ -234,6 +234,7 @@ static int ztest_dump_core = 1; extern uint64_t zio_gang_bang; +extern uint16_t zio_zil_fail_shift; #define ZTEST_DIROBJ 1 #define ZTEST_MICROZAP_OBJ 2 @@ -359,6 +360,7 @@ "\t[-E(xisting)] (use existing pool instead of creating new one)\n" "\t[-T time] total run time (default: %llu sec)\n" "\t[-P passtime] time per pass (default: %llu sec)\n" + "\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n" "", cmdname, (u_longlong_t)zopt_vdevs, /* -v */ @@ -375,7 +377,8 @@ zopt_pool, /* -p */ zopt_dir, /* -f */ (u_longlong_t)zopt_time, /* -T */ - (u_longlong_t)zopt_passtime); /* -P */ + (u_longlong_t)zopt_passtime, /* -P */ + (u_longlong_t)zio_zil_fail_shift); /* -z */ exit(1); } @@ -409,8 +412,11 @@ /* By default, test gang blocks for blocks 32K and greater */ zio_gang_bang = 32 << 10; + /* Default value, fail every 32nd allocation */ + zio_zil_fail_shift = 5; + while ((opt = getopt(argc, argv, - "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:")) != EOF) { + "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:")) != EOF) { value = 0; switch (opt) { case 'v': @@ -426,6 +432,7 @@ case 'k': case 'T': case 'P': + case 'z': value = nicenumtoull(optarg); } switch (opt) { @@ -480,6 +487,9 @@ case 'P': zopt_passtime = MAX(1, value); break; + case 'z': + zio_zil_fail_shift = MIN(value, 16); + break; case '?': default: usage();
--- a/usr/src/lib/libzpool/common/llib-lzpool Fri Feb 16 12:27:32 2007 -0800 +++ b/usr/src/lib/libzpool/common/llib-lzpool Fri Feb 16 13:39:57 2007 -0800 @@ -49,3 +49,4 @@ #include <sys/zfs_znode.h> extern uint64_t zio_gang_bang; +extern uint16_t zio_zil_fail_shift;
--- a/usr/src/uts/common/fs/zfs/zil.c Fri Feb 16 12:27:32 2007 -0800 +++ b/usr/src/uts/common/fs/zfs/zil.c Fri Feb 16 13:39:57 2007 -0800 @@ -36,6 +36,7 @@ #include <sys/zil_impl.h> #include <sys/dsl_dataset.h> #include <sys/vdev.h> +#include <sys/dmu_tx.h> /* * The zfs intent log (ZIL) saves transaction records of system calls @@ -690,14 +691,29 @@ /* pass the old blkptr in order to spread log blocks across devs */ error = zio_alloc_blk(spa, zil_blksz, bp, &lwb->lwb_blk, txg); if (error) { + dmu_tx_t *tx = dmu_tx_create_assigned(zilog->zl_dmu_pool, txg); + /* - * Reinitialise the lwb. + * We dirty the dataset to ensure that zil_sync() will + * be called to remove this lwb from our zl_lwb_list. + * Failing to do so, may leave an lwb with a NULL lwb_buf + * hanging around on the zl_lwb_list. + */ + dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx); + + + /* + * Since we've just experienced an allocation failure so we + * terminate the current lwb and send it on its way. + */ + ztp->zit_pad = 0; + ztp->zit_nused = lwb->lwb_nused; + ztp->zit_bt.zbt_cksum = lwb->lwb_blk.blk_cksum; + zio_nowait(lwb->lwb_zio); + + /* * By returning NULL the caller will call tx_wait_synced() */ - mutex_enter(&zilog->zl_lock); - lwb->lwb_nused = 0; - mutex_exit(&zilog->zl_lock); - txg_rele_to_sync(&lwb->lwb_txgh); return (NULL); } @@ -1116,6 +1132,15 @@ list_remove(&zilog->zl_lwb_list, lwb); zio_free_blk(spa, &lwb->lwb_blk, txg); kmem_cache_free(zil_lwb_cache, lwb); + + /* + * If we don't have anything left in the lwb list then + * we've had an allocation failure and we need to zero + * out the zil_header blkptr so that we don't end + * up freeing the same block twice. + */ + if (list_head(&zilog->zl_lwb_list) == NULL) + BP_ZERO(&zh->zh_log); } mutex_exit(&zilog->zl_lock); }
--- a/usr/src/uts/common/fs/zfs/zio.c Fri Feb 16 12:27:32 2007 -0800 +++ b/usr/src/uts/common/fs/zfs/zio.c Fri Feb 16 13:39:57 2007 -0800 @@ -64,6 +64,9 @@ /* At or above this size, force gang blocking - for testing */ uint64_t zio_gang_bang = SPA_MAXBLOCKSIZE + 1; +/* Force an allocation failure when non-zero */ +uint16_t zio_zil_fail_shift = 0; + typedef struct zio_sync_pass { int zp_defer_free; /* defer frees after this pass */ int zp_dontcompress; /* don't compress after this pass */ @@ -1751,6 +1754,14 @@ } } +static boolean_t +zio_alloc_should_fail(void) +{ + static uint16_t allocs = 0; + + return (P2PHASE(allocs++, 1U<<zio_zil_fail_shift) == 0); +} + /* * Try to allocate an intent log block. Return 0 on success, errno on failure. */ @@ -1762,6 +1773,11 @@ spa_config_enter(spa, RW_READER, FTAG); + if (zio_zil_fail_shift && zio_alloc_should_fail()) { + spa_config_exit(spa, FTAG); + return (ENOSPC); + } + /* * We were passed the previous log blocks dva_t in bp->blk_dva[0]. */