Print this page
NEX-20218 Backport Illumos #9474 txg_kick() fails to see that we are quiescing, forcing transactions to their next stages without leaving them accumulate changes
MFV illumos-gate@fa41d87de9ec9000964c605eb01d6dc19e4a1abe
    9464 txg_kick() fails to see that we are quiescing, forcing transactions to their next stages without leaving them accumulate changes
    Reviewed by: Matt Ahrens <matt@delphix.com>
    Reviewed by: Brad Lewis <brad.lewis@delphix.com>
    Reviewed by: Andriy Gapon <avg@FreeBSD.org>
    Approved by: Dan McDonald <danmcd@joyent.com>
NEX-6859 TX-commit callback that is registered in sync-ctx causes system panic
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-5795 Rename 'wrc' as 'wbc' in the source and in the tech docs
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-4582 update wrc test cases for allow to use write back cache per tree of datasets
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
5960 zfs recv should prefetch indirect blocks
5925 zfs receive -o origin=
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
5911 ZFS "hangs" while deleting file
Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com>
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Simon Klinkert <simon.klinkert@gmail.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-1823 Slow performance doing of a large dataset
5911 ZFS "hangs" while deleting file
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Moved closed ZFS files to open repo, changed Makefiles accordingly
Removed unneeded weak symbols
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
Bug 11205: add missing libzfs_closed_stubs.c to fix opensource-only build.
ZFS plus work: special vdevs, cos, cos/vdev properties

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dmu.h> --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dmu.h>
*** 299,325 **** dmu_tx_count_dnode(txh); } } void - dmu_tx_hold_remap_l1indirect(dmu_tx_t *tx, uint64_t object) - { - dmu_tx_hold_t *txh; - - ASSERT(tx->tx_txg == 0); - txh = dmu_tx_hold_object_impl(tx, tx->tx_objset, - object, THT_WRITE, 0, 0); - if (txh == NULL) - return; - - dnode_t *dn = txh->txh_dnode; - (void) refcount_add_many(&txh->txh_space_towrite, - 1ULL << dn->dn_indblkshift, FTAG); - dmu_tx_count_dnode(txh); - } - - void dmu_tx_hold_write_by_dnode(dmu_tx_t *tx, dnode_t *dn, uint64_t off, int len) { dmu_tx_hold_t *txh; ASSERT0(tx->tx_txg); --- 299,308 ----
*** 867,877 **** * usage by one transaction. Also, as we approach the allowed usage, * we will allow a very limited amount of changes into each TXG, thus * decreasing performance. */ static int ! dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) { spa_t *spa = tx->tx_pool->dp_spa; ASSERT0(tx->tx_txg); --- 850,860 ---- * usage by one transaction. Also, as we approach the allowed usage, * we will allow a very limited amount of changes into each TXG, thus * decreasing performance. */ static int ! dmu_tx_try_assign(dmu_tx_t *tx, txg_how_t txg_how) { spa_t *spa = tx->tx_pool->dp_spa; ASSERT0(tx->tx_txg);
*** 887,903 **** * * Note that we always honor the txg_how flag regardless * of the failuremode setting. */ if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE && ! !(txg_how & TXG_WAIT)) return (SET_ERROR(EIO)); return (SET_ERROR(ERESTART)); } ! if (!tx->tx_dirty_delayed && dsl_pool_need_dirty_delay(tx->tx_pool)) { tx->tx_wait_dirty = B_TRUE; return (SET_ERROR(ERESTART)); } --- 870,886 ---- * * Note that we always honor the txg_how flag regardless * of the failuremode setting. */ if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE && ! txg_how != TXG_WAIT) return (SET_ERROR(EIO)); return (SET_ERROR(ERESTART)); } ! if (!tx->tx_waited && dsl_pool_need_dirty_delay(tx->tx_pool)) { tx->tx_wait_dirty = B_TRUE; return (SET_ERROR(ERESTART)); }
*** 981,1028 **** tx->tx_lasttried_txg = tx->tx_txg; tx->tx_txg = 0; } /* ! * Assign tx to a transaction group; txg_how is a bitmask: * ! * If TXG_WAIT is set and the currently open txg is full, this function ! * will wait until there's a new txg. This should be used when no locks ! * are being held. With this bit set, this function will only fail if ! * we're truly out of space (or over quota). * ! * If TXG_WAIT is *not* set and we can't assign into the currently open ! * txg without blocking, this function will return immediately with ! * ERESTART. This should be used whenever locks are being held. On an ! * ERESTART error, the caller should drop all locks, call dmu_tx_wait(), ! * and try again. * ! * If TXG_NOTHROTTLE is set, this indicates that this tx should not be ! * delayed due on the ZFS Write Throttle (see comments in dsl_pool.c for ! * details on the throttle). This is used by the VFS operations, after ! * they have already called dmu_tx_wait() (though most likely on a ! * different tx). */ int ! dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how) { int err; ASSERT(tx->tx_txg == 0); ! ASSERT0(txg_how & ~(TXG_WAIT | TXG_NOTHROTTLE)); ASSERT(!dsl_pool_sync_context(tx->tx_pool)); /* If we might wait, we must not hold the config lock. */ ! IMPLY((txg_how & TXG_WAIT), !dsl_pool_config_held(tx->tx_pool)); ! if ((txg_how & TXG_NOTHROTTLE)) ! tx->tx_dirty_delayed = B_TRUE; while ((err = dmu_tx_try_assign(tx, txg_how)) != 0) { dmu_tx_unassign(tx); ! if (err != ERESTART || !(txg_how & TXG_WAIT)) return (err); dmu_tx_wait(tx); } --- 964,1008 ---- tx->tx_lasttried_txg = tx->tx_txg; tx->tx_txg = 0; } /* ! * Assign tx to a transaction group. txg_how can be one of: * ! * (1) TXG_WAIT. If the current open txg is full, waits until there's ! * a new one. This should be used when you're not holding locks. ! * It will only fail if we're truly out of space (or over quota). * ! * (2) TXG_NOWAIT. If we can't assign into the current open txg without ! * blocking, returns immediately with ERESTART. This should be used ! * whenever you're holding locks. On an ERESTART error, the caller ! * should drop locks, do a dmu_tx_wait(tx), and try again. * ! * (3) TXG_WAITED. Like TXG_NOWAIT, but indicates that dmu_tx_wait() ! * has already been called on behalf of this operation (though ! * most likely on a different tx). */ int ! dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how) { int err; ASSERT(tx->tx_txg == 0); ! ASSERT(txg_how == TXG_WAIT || txg_how == TXG_NOWAIT || ! txg_how == TXG_WAITED); ASSERT(!dsl_pool_sync_context(tx->tx_pool)); /* If we might wait, we must not hold the config lock. */ ! ASSERT(txg_how != TXG_WAIT || !dsl_pool_config_held(tx->tx_pool)); ! if (txg_how == TXG_WAITED) ! tx->tx_waited = B_TRUE; while ((err = dmu_tx_try_assign(tx, txg_how)) != 0) { dmu_tx_unassign(tx); ! if (err != ERESTART || txg_how != TXG_WAIT) return (err); dmu_tx_wait(tx); }
*** 1055,1070 **** dmu_tx_delay(tx, dirty); tx->tx_wait_dirty = B_FALSE; /* ! * Note: setting tx_dirty_delayed only has effect if the ! * caller used TX_WAIT. Otherwise they are going to ! * destroy this tx and try again. The common case, ! * zfs_write(), uses TX_WAIT. */ ! tx->tx_dirty_delayed = B_TRUE; } else if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) { /* * If the pool is suspended we need to wait until it * is resumed. Note that it's possible that the pool * has become active after this thread has tried to --- 1035,1050 ---- dmu_tx_delay(tx, dirty); tx->tx_wait_dirty = B_FALSE; /* ! * Note: setting tx_waited only has effect if the caller ! * used TX_WAIT. Otherwise they are going to destroy ! * this tx and try again. The common case, zfs_write(), ! * uses TX_WAIT. */ ! tx->tx_waited = B_TRUE; } else if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) { /* * If the pool is suspended we need to wait until it * is resumed. Note that it's possible that the pool * has become active after this thread has tried to
*** 1083,1093 **** while (dn->dn_assigned_txg == tx->tx_lasttried_txg - 1) cv_wait(&dn->dn_notxholds, &dn->dn_mtx); mutex_exit(&dn->dn_mtx); tx->tx_needassign_txh = NULL; } else { ! txg_wait_open(tx->tx_pool, tx->tx_lasttried_txg + 1); } } static void dmu_tx_destroy(dmu_tx_t *tx) --- 1063,1078 ---- while (dn->dn_assigned_txg == tx->tx_lasttried_txg - 1) cv_wait(&dn->dn_notxholds, &dn->dn_mtx); mutex_exit(&dn->dn_mtx); tx->tx_needassign_txh = NULL; } else { ! /* ! * If we have a lot of dirty data just wait until we sync ! * out a TXG at which point we'll hopefully have synced ! * a portion of the changes. ! */ ! txg_wait_synced(dp, spa_last_synced_txg(spa) + 1); } } static void dmu_tx_destroy(dmu_tx_t *tx)
*** 1139,1150 **** } if (tx->tx_tempreserve_cookie) dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx); ! if (!list_is_empty(&tx->tx_callbacks)) ! txg_register_callbacks(&tx->tx_txgh, &tx->tx_callbacks); if (tx->tx_anyobj == FALSE) txg_rele_to_sync(&tx->tx_txgh); dmu_tx_destroy(tx); --- 1124,1142 ---- } if (tx->tx_tempreserve_cookie) dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx); ! if (!list_is_empty(&tx->tx_callbacks)) { ! if (dmu_tx_is_syncing(tx)) { ! txg_register_callbacks_sync(tx->tx_pool, ! tx->tx_txg, &tx->tx_callbacks); ! } else { ! txg_register_callbacks(&tx->tx_txgh, ! &tx->tx_callbacks); ! } ! } if (tx->tx_anyobj == FALSE) txg_rele_to_sync(&tx->tx_txgh); dmu_tx_destroy(tx);