dmu_tx.c revision 715614a4137a6d2100ff60821e21cabc22d06088
19d8729755d7f4d9503029a628dacbbdabcd2264wrowe * CDDL HEADER START
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * The contents of this file are subject to the terms of the
8cc01204a878dc5f39bba11aa279564b81b15803wrowe * Common Development and Distribution License (the "License").
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * You may not use this file except in compliance with the License.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * See the License for the specific language governing permissions
9ec65cbae2f760e485a1c54df5b19853688d5c91wrowe * and limitations under the License.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * When distributing Covered Code, include this CDDL HEADER in each
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * If applicable, add the following below this CDDL HEADER, with the
9ec65cbae2f760e485a1c54df5b19853688d5c91wrowe * fields enclosed by brackets "[]" replaced with your own identifying
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * information: Portions Copyright [yyyy] [name of copyright owner]
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * CDDL HEADER END
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * Use is subject to license terms.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding#pragma ident "%Z%%M% %I% %E% SMI"
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
8cc01204a878dc5f39bba11aa279564b81b15803wrowe#include <sys/zap_impl.h> /* for fzap_default_block_shift */
8cc01204a878dc5f39bba11aa279564b81b15803wrowetypedef void (*dmu_tx_hold_func_t)(dmu_tx_t *tx, struct dnode *dn,
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
8cc01204a878dc5f39bba11aa279564b81b15803wrowe dmu_tx_t *tx = dmu_tx_create_dd(os->os->os_dsl_dataset->ds_dir);
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os->os_dsl_dataset);
577d813165ace257dd6f3bee143e5413ea1a16acstoddarddmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
37e3f7ccfb0862f3a7626681d0b1d01a3650162bstoddarddmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
37e3f7ccfb0862f3a7626681d0b1d01a3650162bstoddard enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
37e3f7ccfb0862f3a7626681d0b1d01a3650162bstoddard * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
37e3f7ccfb0862f3a7626681d0b1d01a3650162bstoddard * problem, but there's no way for it to happen (for
4099f9c1ec0ad7d2423208089d87592c2846486dwrowe * now, at least).
4099f9c1ec0ad7d2423208089d87592c2846486dwrowedmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
990e1969a428b8844e07aad088df41340cd009d4wrowe * If we're syncing, they can manipulate any object anyhow, and
990e1969a428b8844e07aad088df41340cd009d4wrowe * the hold on the dnode_t can cause problems.
8ad0beaa526f5ebc7a44779020a82814f76e9617stoddarddmu_tx_check_ioerr(zio_t *zio, dnode_t *dn, int level, uint64_t blkid)
4099f9c1ec0ad7d2423208089d87592c2846486dwrowe err = dbuf_read(db, zio, DB_RF_CANFAIL | DB_RF_NOPREFETCH);
4099f9c1ec0ad7d2423208089d87592c2846486dwrowe/* ARGSUSED */
990e1969a428b8844e07aad088df41340cd009d4wrowedmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
990e1969a428b8844e07aad088df41340cd009d4wrowe * For i/o error checking, read the first and last level-0
be8e3c3ad9c5d87951a803b632dccde0a4aba35cwrowe * blocks (if they are not aligned), and all the level-1 blocks.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding /* first level-0 block */
f6bd1c0924641e60dcc56cbaba27d3cb3ce4917erbb /* last level-0 block */
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding /* level-1 blocks */
577d813165ace257dd6f3bee143e5413ea1a16acstoddard * If there's more than one block, the blocksize can't change,
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * so we can make a more precise estimate. Alternatively,
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * if the dnode's ibs is larger than max_ibs, always use that.
577d813165ace257dd6f3bee143e5413ea1a16acstoddard * This ensures that if we reduce DN_MAX_INDBLKSHIFT,
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * the code will still work correctly on existing pools.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding if (dn && (dn->dn_maxblkid != 0 || dn->dn_indblkshift > max_ibs)) {
bcdc8e0b30a73eb30244d66010dbe3233ac755aewrowe * 'end' is the last thing we will access, not one past.
bcdc8e0b30a73eb30244d66010dbe3233ac755aewrowe * This way we won't overflow when accessing the last byte.
bcdc8e0b30a73eb30244d66010dbe3233ac755aewrowe * The object contains at most 2^(64 - min_bs) blocks,
990e1969a428b8844e07aad088df41340cd009d4wrowe * and each indirect level maps 2^epbs.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
f86735dccc1da7eaaa4b32739701b6ed98ad6bf1stoddard * If we increase the number of levels of indirection,
f86735dccc1da7eaaa4b32739701b6ed98ad6bf1stoddard * we'll need new blkid=0 indirect blocks. If start == 0,
990e1969a428b8844e07aad088df41340cd009d4wrowe * we're already accounting for that blocks; and if end == 0,
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * we can't increase the number of levels beyond that.
37e3f7ccfb0862f3a7626681d0b1d01a3650162bstoddard txh->txh_space_towrite += (end - start + 1) << max_ibs;
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding dnode_t *mdn = txh->txh_tx->tx_objset->os->os_meta_dnode;
990e1969a428b8844e07aad088df41340cd009d4wrowe dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
dcd2219e426b64c69306a609cd8261f11283f9e9stoddarddmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len)
83bee7f569bee7534741915e173e6a7de9ddae81stoddarddmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
be8e3c3ad9c5d87951a803b632dccde0a4aba35cwrowe * The struct_rwlock protects us against dn_nlevels
be8e3c3ad9c5d87951a803b632dccde0a4aba35cwrowe * changing, in case (against all odds) we manage to dirty &
990e1969a428b8844e07aad088df41340cd009d4wrowe * sync out the changes after we check for being dirty.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * Also, dbuf_hold_level() wants us to have the struct_rwlock.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding nblks = (len + dn->dn_datablksz - 1) >> dn->dn_datablkshift;
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding for (i = 0; i < nblks; i++) {
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding if (dsl_dataset_block_freeable(ds, bp->blk_birth)) {
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * Add in memory requirements of higher-level indirects.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding * This assumes a worst-possible scenario for dn_nlevels.
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding txh->txh_memory_tohold += blkcnt << dn->dn_indblkshift;
990e1969a428b8844e07aad088df41340cd009d4wrowe err = dbuf_read(dbuf, NULL, DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe if (err != 0) {
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe for (i = 0; i < tochk; i++) {
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe if (dsl_dataset_block_freeable(ds, bp[i].blk_birth)) {
990e1969a428b8844e07aad088df41340cd009d4wrowe /* account for new level 1 indirect blocks that might show up */
f3220f54126b25e1cf93cc26c17177b7aef850fdfielding skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs);
990e1969a428b8844e07aad088df41340cd009d4wrowe txh->txh_memory_tohold += skipped << dn->dn_indblkshift;
f3220f54126b25e1cf93cc26c17177b7aef850fdfieldingdmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
if (off != 0)
if (err) {
if (err) {
if (err) {
if (err) {
if (txh)
int holds = 0;
holds++;
return (holds);
#ifdef ZFS_DEBUG
case THT_WRITE:
if (blkid == 0)
case THT_FREE:
case THT_BONUS:
case THT_ZAP:
case THT_NEWOBJECT:
return (EIO);
return (ERESTART);
return (ERESTART);
return (ERESTART);
#ifdef ZFS_DEBUG
if (err)
return (err);
int err;
return (err);
#ifdef ZFS_DEBUG
if (delta > 0) {
#ifdef ZFS_DEBUG
#ifdef ZFS_DEBUG