usr/src/uts/common/fs/zfs/dmu_tx.c
author eschrock
Fri, 03 Mar 2006 20:08:16 -0800
changeset 1544 938876158511
parent 1491 bdcb30e07e7d
child 1596 2e2377ccbf85
permissions -rw-r--r--
PSARC 2006/077 zpool clear PSARC 2006/139 FMA for ZFS 6284889 arc should replace the znode cache 6333006 DMU & DSL should not panic upon I/O error 6333092 concurrent reads to a file not scaling with number of readers 6338081 ZFS/FMA phase 1 6338386 need persistent error log 6341326 i/o error causes arc buf hash table corruption 6341639 zfs backup/restore should compute/verify checksum of backup stream 6348002 out of space due to changing properties 6354724 inaccurate error message from zfs restore 6354872 dmu_sync() blows predictive accounting 6355416 zpool scrubbing consumes all memory, system hung 6363995 df should only load libzfs when it encounters a ZFS filesystem 6366320 zfs backup/restore doesn't like signals 6368892 mount -m support needed for legacy mounts 6368902 boot archive fstat support needed for ZFS Mountroot 6369424 BFU complains when bfu'ing a ZFS root filesystem 6374062 mountroot support needed for ZFS 6376356 dirtying dbuf obj=43 lvl=0 blkid=0 but not tx_held 6378391 unused members of dmu_objset_stats_t 6378392 clean up zfs_cmd_t structure 6378685 buf_init should allocate its hash table more carefully 6378976 ziltest should be a first class citizen 6381086 zdb segfaults if there is a spa deferred-free bplist 6381203 deadlock due to i/o while assigning (tc_lock held) 6381209 freed space is not immediately available 6381344 'zpool clear' 6381345 FAULTED devices should really be UNAVAIL 6381346 import should mark devices as persistently unavailable 6383272 recursive mutex_enter() during log replay with zfs root 6386326 origin property is not displayed 6386354 libzfs does too much in its _init section, calls exit(1) 6386624 zpool should not complain about non-existent devices from libdiskmgt 6386910 spa needs to be i/o error hardened 6387735 need a mechanism to inject faults into ZFS 6387736 internal ZFS utilities should be placed in an ON-private package 6389928 libzfs should ship a lint library 6390609 malformed vdev config panics on zpool_create() 6390677 version number checking makes upgrades challenging 6390713 ztest hangs in zil_suspend() 6391873 metadata compression should be turned back on 6392113 ztest sometimes reports leaked blocks because ZIL isn't resilvered 6393004 minor memory leak in unique_insert()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
     5
 * Common Development and Distribution License (the "License").
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/dmu_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/dbuf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/dmu_objset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/dsl_pool.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/zap_impl.h>	/* for ZAP_BLOCK_SHIFT */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    40
typedef void (*dmu_tx_hold_func_t)(dmu_tx_t *tx, struct dnode *dn,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    41
    uint64_t arg1, uint64_t arg2);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    42
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
int dmu_use_tx_debug_bufs = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
dmu_tx_create_ds(dsl_dir_t *dd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	tx->tx_dir = dd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	if (dd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
		tx->tx_pool = dd->dd_pool;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	    offsetof(dmu_tx_hold_t, dth_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	refcount_create(&tx->tx_space_written);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	refcount_create(&tx->tx_space_freed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
dmu_tx_create(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	dmu_tx_t *tx = dmu_tx_create_ds(os->os->os_dsl_dataset->ds_dir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	tx->tx_objset = os;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    66
	tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os->os_dsl_dataset);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
	dmu_tx_t *tx = dmu_tx_create_ds(NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	tx->tx_pool = dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	tx->tx_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
	tx->tx_anyobj = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
dmu_tx_is_syncing(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	return (tx->tx_anyobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
dmu_tx_private_ok(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    92
	return (tx->tx_anyobj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
    enum dmu_tx_hold_type type, dmu_tx_hold_func_t func,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
    uint64_t arg1, uint64_t arg2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	dnode_t *dn = NULL;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   102
	int err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	if (object != DMU_NEW_OBJECT) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   105
		err = dnode_hold(os->os, object, tx, &dn);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   106
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   107
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   108
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   109
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   111
		if (err == 0 && tx->tx_txg != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
			mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			 * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			 * problem, but there's no way for it to happen (for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			 * now, at least).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
			ASSERT(dn->dn_assigned_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
			ASSERT(dn->dn_assigned_tx == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
			dn->dn_assigned_txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
			dn->dn_assigned_tx = tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	dth = kmem_zalloc(sizeof (dmu_tx_hold_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	dth->dth_dnode = dn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	dth->dth_type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	dth->dth_arg1 = arg1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
	dth->dth_arg2 = arg2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	list_insert_tail(&tx->tx_holds, dth);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   133
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   134
	if (func)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   135
		func(tx, dn, arg1, arg2);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	 * If we're syncing, they can manipulate any object anyhow, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	 * the hold on the dnode_t can cause problems.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	if (!dmu_tx_is_syncing(tx)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
		dmu_tx_hold_object_impl(tx, os, object, THT_NEWOBJECT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
		    NULL, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   151
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   152
dmu_tx_check_ioerr(zio_t *zio, dnode_t *dn, int level, uint64_t blkid)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   153
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   154
	int err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   155
	dmu_buf_impl_t *db;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   156
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   157
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   158
	db = dbuf_hold_level(dn, level, blkid, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   159
	rw_exit(&dn->dn_struct_rwlock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   160
	if (db == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   161
		return (EIO);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   162
	err = dbuf_read(db, zio, DB_RF_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   163
	dbuf_rele(db, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   164
	return (err);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   165
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   166
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
dmu_tx_count_write(dmu_tx_t *tx, dnode_t *dn, uint64_t off, uint64_t len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   171
	uint64_t start, end, i, space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	int min_bs, max_bs, min_ibs, max_ibs, epbs, bits;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	if (len == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	min_bs = SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	max_bs = SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	min_ibs = DN_MIN_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
	max_ibs = DN_MAX_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   183
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   184
	 * blocks, and all the level-1 blocks.  We needn't do this on
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   185
	 * the meta-dnode, because we've already read it in.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   186
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   187
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   188
	if (dn && dn->dn_object != DMU_META_DNODE_OBJECT) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   189
		int err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   190
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   191
		if (dn->dn_maxblkid == 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   192
			err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   193
			if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   194
				tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   195
				return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   196
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   197
		} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   198
			zio_t *zio = zio_root(tx->tx_pool->dp_spa,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   199
			    NULL, NULL, ZIO_FLAG_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   200
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   201
			/* first level-0 block */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   202
			start = off/dn->dn_datablksz;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   203
			err = dmu_tx_check_ioerr(zio, dn, 0, start);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   204
			if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   205
				tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   206
				return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   207
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   208
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   209
			/* last level-0 block */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   210
			end = (off+len)/dn->dn_datablksz;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   211
			if (end != start) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   212
				err = dmu_tx_check_ioerr(zio, dn, 0, end);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   213
				if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   214
					tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   215
					return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   216
				}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   217
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   218
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   219
			/* level-1 blocks */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   220
			if (dn->dn_nlevels > 1) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   221
				start >>= dn->dn_indblkshift - SPA_BLKPTRSHIFT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   222
				end >>= dn->dn_indblkshift - SPA_BLKPTRSHIFT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   223
				for (i = start+1; i < end; i++) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   224
					err = dmu_tx_check_ioerr(zio, dn, 1, i);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   225
					if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   226
						tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   227
						return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   228
					}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   229
				}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   230
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   231
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   232
			err = zio_wait(zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   233
			if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   234
				tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   235
				return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   236
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   237
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   238
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   239
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   240
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	 * If there's more than one block, the blocksize can't change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	 * so we can make a more precise estimate.  Alternatively,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	 * if the dnode's ibs is larger than max_ibs, always use that.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	 * This ensures that if we reduce DN_MAX_INDBLKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	 * the code will still work correctly on existing pools.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	if (dn && (dn->dn_maxblkid != 0 || dn->dn_indblkshift > max_ibs)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
		min_ibs = max_ibs = dn->dn_indblkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
		if (dn->dn_datablkshift != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
			min_bs = max_bs = dn->dn_datablkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	 * 'end' is the last thing we will access, not one past.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	 * This way we won't overflow when accessing the last byte.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	start = P2ALIGN(off, 1ULL << max_bs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	space = end - start + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	start >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	end >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	epbs = min_ibs - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	 * The object contains at most 2^(64 - min_bs) blocks,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
	 * and each indirect level maps 2^epbs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
		start >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		end >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		 * If we increase the number of levels of indirection,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
		 * we'll need new blkid=0 indirect blocks.  If start == 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
		 * we're already accounting for that blocks; and if end == 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		 * we can't increase the number of levels beyond that.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		if (start != 0 && end != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
			space += 1ULL << max_ibs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		space += (end - start + 1) << max_ibs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
	ASSERT(space < 2 * DMU_MAX_ACCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
	tx->tx_space_towrite += space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
dmu_tx_count_dnode(dmu_tx_t *tx, dnode_t *dn)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
	dnode_t *mdn = tx->tx_objset->os->os_meta_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	uint64_t object = dn ? dn->dn_object : DN_MAX_OBJECT - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	uint64_t pre_write_space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	ASSERT(object < DN_MAX_OBJECT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	pre_write_space = tx->tx_space_towrite;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
	dmu_tx_count_write(tx, mdn, object << DNODE_SHIFT, 1 << DNODE_SHIFT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	if (dn && dn->dn_dbuf->db_blkptr &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	    dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   301
	    dn->dn_dbuf->db_blkptr->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
		tx->tx_space_tooverwrite +=
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
			tx->tx_space_towrite - pre_write_space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		tx->tx_space_towrite = pre_write_space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
dmu_tx_hold_write_impl(dmu_tx_t *tx, dnode_t *dn, uint64_t off, uint64_t len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	dmu_tx_count_write(tx, dn, off, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	dmu_tx_count_dnode(tx, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	ASSERT(tx->tx_txg == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   320
	ASSERT(len < DMU_MAX_ACCESS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	ASSERT(UINT64_MAX - off >= len - 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	dmu_tx_hold_object_impl(tx, tx->tx_objset, object, THT_WRITE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	    dmu_tx_hold_write_impl, off, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
dmu_tx_count_free(dmu_tx_t *tx, dnode_t *dn, uint64_t off, uint64_t len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	uint64_t blkid, nblks;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	uint64_t space = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	if (dn->dn_datablkshift == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	 * not that the dnode can change, since it isn't dirty, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	 * dbuf_hold_impl() wants us to have the struct_rwlock.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	 * also need it to protect dn_maxblkid.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	blkid = off >> dn->dn_datablkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	nblks = (off + len) >> dn->dn_datablkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   345
	if (blkid >= dn->dn_maxblkid) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   346
		rw_exit(&dn->dn_struct_rwlock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   347
		return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   348
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	if (blkid + nblks > dn->dn_maxblkid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
		nblks = dn->dn_maxblkid - blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	/* don't bother after the 100,000 blocks */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	nblks = MIN(nblks, 128*1024);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	if (dn->dn_phys->dn_nlevels == 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
		for (i = 0; i < nblks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
			blkptr_t *bp = dn->dn_phys->dn_blkptr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
			ASSERT3U(blkid + i, <, dn->dn_phys->dn_nblkptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
			bp += blkid + i;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   361
			if (dsl_dataset_block_freeable(ds, bp->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
				dprintf_bp(bp, "can free old%s", "");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
				space += BP_GET_ASIZE(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   366
		nblks = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
	while (nblks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
		dmu_buf_impl_t *dbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
		int err, epbs, blkoff, tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
		epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
		blkoff = P2PHASE(blkid, 1<<epbs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
		tochk = MIN((1<<epbs) - blkoff, nblks);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		err = dbuf_hold_impl(dn, 1, blkid >> epbs, TRUE, FTAG, &dbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
		if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
			int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
			blkptr_t *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   382
			err = dbuf_read(dbuf, NULL,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   383
			    DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   384
			if (err != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   385
				tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   386
				dbuf_rele(dbuf, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   387
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   388
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
			bp = dbuf->db.db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
			bp += blkoff;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
			for (i = 0; i < tochk; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
				if (dsl_dataset_block_freeable(ds,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   395
				    bp[i].blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
					dprintf_bp(&bp[i],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
					    "can free old%s", "");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
					space += BP_GET_ASIZE(&bp[i]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
			}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   401
			dbuf_rele(dbuf, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
			/* the indirect block is sparse */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
			ASSERT(err == ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		blkid += tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
		nblks -= tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
	rw_exit(&dn->dn_struct_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
	tx->tx_space_tofree += space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
dmu_tx_hold_free_impl(dmu_tx_t *tx, dnode_t *dn, uint64_t off, uint64_t len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   418
	uint64_t start, end, i;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   419
	int dirty, err, shift;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   420
	zio_t *zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
	/* first block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	if (off != 0 /* || dn->dn_maxblkid == 0 */)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
		dmu_tx_count_write(tx, dn, off, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
	/* last block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
	if (len != DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
		dmu_tx_count_write(tx, dn, off+len, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
	if (len == DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   434
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   435
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   436
	 * blocks, and all the level-1 blocks.  The above count_write's
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   437
	 * will take care of the level-0 blocks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   438
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   439
	shift = dn->dn_datablkshift + dn->dn_indblkshift - SPA_BLKPTRSHIFT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   440
	start = off >> shift;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   441
	end = dn->dn_datablkshift ? ((off+len) >> shift) : 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   442
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   443
	zio = zio_root(tx->tx_pool->dp_spa, NULL, NULL, ZIO_FLAG_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   444
	for (i = start+1; i < end; i++) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   445
		uint64_t ibyte = i << shift;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   446
		err = dnode_next_offset(dn, FALSE, &ibyte, 2, 1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   447
		i = ibyte >> shift;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   448
		if (err == ESRCH)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   449
			break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   450
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   451
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   452
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   453
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   454
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   455
		err = dmu_tx_check_ioerr(zio, dn, 1, i);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   456
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   457
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   458
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   459
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   460
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   461
	err = zio_wait(zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   462
	if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   463
		tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   464
		return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   465
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   466
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   467
	dmu_tx_count_dnode(tx, dn);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   468
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	/* XXX locking */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	dirty = dn->dn_dirtyblksz[0] | dn->dn_dirtyblksz[1] |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	    dn->dn_dirtyblksz[2] | dn->dn_dirtyblksz[3];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
	if (dn->dn_assigned_tx != NULL && !dirty)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
		dmu_tx_count_free(tx, dn, off, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	dmu_tx_hold_object_impl(tx, tx->tx_objset, object, THT_FREE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	    dmu_tx_hold_free_impl, off, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
static void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   487
dmu_tx_hold_zap_impl(dmu_tx_t *tx, dnode_t *dn, uint64_t add, uint64_t iname)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	uint64_t nblocks;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   490
	int epbs, err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   491
	char *name = (char *)(uintptr_t)iname;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
	dmu_tx_count_dnode(tx, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
	if (dn == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   497
		 * We will be able to fit a new object's entries into one leaf
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
		 * block.  So there will be at most 2 blocks total,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
		 * including the header block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
		 */
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
   501
		dmu_tx_count_write(tx, dn, 0, 2 << fzap_default_block_shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   507
	if (dn->dn_maxblkid == 0 && !add) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
		 * If there is only one block  (i.e. this is a micro-zap)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   510
		 * and we are not adding anything, the accounting is simple.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   512
		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   513
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   514
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   515
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   516
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   517
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   519
		    dn->dn_phys->dn_blkptr[0].blk_birth))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
			tx->tx_space_tooverwrite += dn->dn_datablksz;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
			tx->tx_space_towrite += dn->dn_datablksz;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   526
	if (dn->dn_maxblkid > 0 && name) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   527
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   528
		 * access the name in this fat-zap so that we'll check
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   529
		 * for i/o errors to the leaf blocks, etc.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   530
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   531
		err = zap_lookup(&dn->dn_objset->os, dn->dn_object, name,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   532
		    8, 0, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   533
		if (err == EIO) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   534
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   535
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   536
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   537
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   538
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   540
	 * 3 blocks overwritten: target leaf, ptrtbl block, header block
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   541
	 * 3 new blocks written if adding: new split leaf, 2 grown ptrtbl blocks
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
	dmu_tx_count_write(tx, dn, dn->dn_maxblkid * dn->dn_datablksz,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   544
	    (3 + add ? 3 : 0) << dn->dn_datablkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	 * If the modified blocks are scattered to the four winds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	 * we'll have to modify an indirect twig for each.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
	for (nblocks = dn->dn_maxblkid >> epbs; nblocks != 0; nblocks >>= epbs)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   552
		tx->tx_space_towrite += 3 << dn->dn_indblkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   556
dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, char *name)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
	dmu_tx_hold_object_impl(tx, tx->tx_objset, object, THT_ZAP,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   561
	    dmu_tx_hold_zap_impl, add, (uintptr_t)name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	dmu_tx_hold_object_impl(tx, tx->tx_objset, object, THT_BONUS,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	    dmu_tx_hold_write_impl, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
dmu_tx_hold_space_impl(dmu_tx_t *tx, dnode_t *dn,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
    uint64_t space, uint64_t unused)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	tx->tx_space_towrite += space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
	dmu_tx_hold_object_impl(tx, tx->tx_objset, DMU_NEW_OBJECT, THT_SPACE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	    dmu_tx_hold_space_impl, space, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
	int holds = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	 * By asserting that the tx is assigned, we're counting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	 * number of dn_tx_holds, which is the same as the number of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
	 * dn_tx_holds could be 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	/* if (tx->tx_anyobj == TRUE) */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
		/* return (0); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	for (dth = list_head(&tx->tx_holds); dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
	    dth = list_next(&tx->tx_holds, dth)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
		if (dth->dth_dnode && dth->dth_dnode->dn_object == object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
			holds++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	return (holds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   617
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	int match_object = FALSE, match_offset = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
	dnode_t *dn = db->db_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset->os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
	ASSERT3U(dn->dn_object, ==, db->db.db_object);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	if (tx->tx_anyobj)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	/* XXX No checking on the meta dnode for now */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   633
	if (db->db.db_object == DMU_META_DNODE_OBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
	for (dth = list_head(&tx->tx_holds); dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
	    dth = list_next(&tx->tx_holds, dth)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
		ASSERT(dn == NULL || dn->dn_assigned_txg == tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
		if (dth->dth_dnode == dn && dth->dth_type != THT_NEWOBJECT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
			match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
		if (dth->dth_dnode == NULL || dth->dth_dnode == dn) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
			int datablkshift = dn->dn_datablkshift ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
			int shift = datablkshift + epbs * db->db_level;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
			uint64_t beginblk = shift >= 64 ? 0 :
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
			    (dth->dth_arg1 >> shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
			uint64_t endblk = shift >= 64 ? 0 :
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
			    ((dth->dth_arg1 + dth->dth_arg2 - 1) >> shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
			uint64_t blkid = db->db_blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
			/* XXX dth_arg2 better not be zero... */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
			dprintf("found dth type %x beginblk=%llx endblk=%llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
			    dth->dth_type, beginblk, endblk);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
			switch (dth->dth_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
			case THT_WRITE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
				if (blkid >= beginblk && blkid <= endblk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
				 * We will let this hold work for the bonus
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
				 * buffer so that we don't need to hold it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
				 * when creating a new object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
				 * They might have to increase nlevels,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
				 * thus dirtying the new TLIBs.  Or the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
				 * might have to change the block size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
				 * thus dirying the new lvl=0 blk=0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
				if (blkid == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
			case THT_FREE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
				if (blkid == beginblk &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
				    (dth->dth_arg1 != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
				    dn->dn_maxblkid == 0))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
				if (blkid == endblk &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
				    dth->dth_arg2 != DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
			case THT_BONUS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
			case THT_ZAP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
				match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
			case THT_NEWOBJECT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
				match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
			default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
				ASSERT(!"bad dth_type");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
		if (match_object && match_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
	    (u_longlong_t)db->db.db_object, db->db_level,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	    (u_longlong_t)db->db_blkid);
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   706
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how, dmu_tx_hold_t **last_dth)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
	dmu_tx_hold_t *dth;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   713
	uint64_t lsize, asize, fsize, towrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
	*last_dth = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
	tx->tx_txg = txg_hold_open(tx->tx_pool, &tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
	if (txg_how >= TXG_INITIAL && txg_how != tx->tx_txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
		return (ERESTART);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   721
	if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   722
		return (tx->tx_err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
	for (dth = list_head(&tx->tx_holds); dth;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   725
	    dth = list_next(&tx->tx_holds, dth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
		dnode_t *dn = dth->dth_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
		if (dn != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
			mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
			while (dn->dn_assigned_txg == tx->tx_txg - 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
				if (txg_how != TXG_WAIT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
					mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
					return (ERESTART);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
				cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
			if (dn->dn_assigned_txg == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
				ASSERT(dn->dn_assigned_tx == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
				dn->dn_assigned_txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
				dn->dn_assigned_tx = tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
				ASSERT(dn->dn_assigned_txg == tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
				if (dn->dn_assigned_tx != tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
					dn->dn_assigned_tx = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   748
		*last_dth = dth;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   749
		if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   750
			return (tx->tx_err);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   751
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   752
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   753
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   754
	 * If a snapshot has been taken since we made our estimates,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   755
	 * assume that we won't be able to free or overwrite anything.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   756
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   757
	if (tx->tx_objset &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   758
	    dsl_dataset_prev_snap_txg(tx->tx_objset->os->os_dsl_dataset) >
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   759
	    tx->tx_lastsnap_txg) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   760
		tx->tx_space_towrite += tx->tx_space_tooverwrite;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   761
		tx->tx_space_tooverwrite = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   762
		tx->tx_space_tofree = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	 * Convert logical size to worst-case allocated size.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	fsize = spa_get_asize(tx->tx_pool->dp_spa, tx->tx_space_tooverwrite) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
	    tx->tx_space_tofree;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	lsize = tx->tx_space_towrite + tx->tx_space_tooverwrite;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
	asize = spa_get_asize(tx->tx_pool->dp_spa, lsize);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   772
	towrite = tx->tx_space_towrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
	tx->tx_space_towrite = asize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
	if (tx->tx_dir && asize != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
		int err = dsl_dir_tempreserve_space(tx->tx_dir,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
		    lsize, asize, fsize, &tx->tx_tempreserve_cookie, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   778
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   779
			tx->tx_space_towrite = towrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
			return (err);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   781
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
static uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
dmu_tx_unassign(dmu_tx_t *tx, dmu_tx_hold_t *last_dth)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
	uint64_t txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
	ASSERT(txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
	for (dth = last_dth; dth; dth = list_prev(&tx->tx_holds, dth)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
		dnode_t *dn = dth->dth_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
		ASSERT3U(dn->dn_assigned_txg, ==, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
			dn->dn_assigned_tx = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
	txg_rele_to_sync(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	tx->tx_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
	return (txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
 * Assign tx to a transaction group.  txg_how can be one of:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
 * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
 *	a new one.  This should be used when you're not holding locks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
 *	If will only fail if we're truly out of space (or over quota).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
 * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
 *	blocking, returns immediately with ERESTART.  This should be used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
 *	whenever you're holding locks.  On an ERESTART error, the caller
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
 *	should drop locks, do a txg_wait_open(dp, 0), and try again.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
 * (3)	A specific txg.  Use this if you need to ensure that multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
 *	transactions all sync in the same txg.  Like TXG_NOWAIT, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
 *	returns ERESTART if it can't assign you into the requested txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
	dmu_tx_hold_t *last_dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	ASSERT(txg_how != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
	while ((err = dmu_tx_try_assign(tx, txg_how, &last_dth)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
		uint64_t txg = dmu_tx_unassign(tx, last_dth);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
		if (err != ERESTART || txg_how != TXG_WAIT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
		txg_wait_open(tx->tx_pool, txg + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
	if (tx->tx_dir == NULL || delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
	if (delta > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
		    tx->tx_space_towrite);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
dmu_tx_commit(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
	while (dth = list_head(&tx->tx_holds)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
		dnode_t *dn = dth->dth_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
		list_remove(&tx->tx_holds, dth);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
		kmem_free(dth, sizeof (dmu_tx_hold_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
			dn->dn_assigned_tx = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
		dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
	if (tx->tx_dir && tx->tx_space_towrite > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
	if (tx->tx_anyobj == FALSE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
		txg_rele_to_sync(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
	if (tx->tx_debug_buf)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
		kmem_free(tx->tx_debug_buf, 4096);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   917
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   920
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
dmu_tx_abort(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
	dmu_tx_hold_t *dth;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
	while (dth = list_head(&tx->tx_holds)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
		dnode_t *dn = dth->dth_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
		list_remove(&tx->tx_holds, dth);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
		kmem_free(dth, sizeof (dmu_tx_hold_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
		if (dn != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
			dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
	if (tx->tx_debug_buf)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
		kmem_free(tx->tx_debug_buf, 4096);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
dmu_tx_get_txg(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
	return (tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
}