usr/src/uts/common/fs/zfs/dmu_tx.c
author ck153898
Mon, 29 Oct 2007 22:45:33 -0700
changeset 5378 111aa1baa84a
parent 5329 33cb98223b2d
child 5765 86c482ef4a34
permissions -rw-r--r--
PSARC 2007/555 zfs fs-only quotas and reservations 6431277 want filesystem-only quotas 6483677 need immediate reservation
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
/*
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
    22
 * Copyright 2007 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>
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    36
#include <sys/zap_impl.h> /* for fzap_default_block_shift */
789
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
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
dmu_tx_t *
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    45
dmu_tx_create_dd(dsl_dir_t *dd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	tx->tx_dir = dd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	if (dd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
		tx->tx_pool = dd->dd_pool;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t),
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    52
	    offsetof(dmu_tx_hold_t, txh_node));
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    53
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	refcount_create(&tx->tx_space_written);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	refcount_create(&tx->tx_space_freed);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    56
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
dmu_tx_create(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
{
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    63
	dmu_tx_t *tx = dmu_tx_create_dd(os->os->os_dsl_dataset->ds_dir);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	tx->tx_objset = os;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    65
	tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os->os_dsl_dataset);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
{
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    72
	dmu_tx_t *tx = dmu_tx_create_dd(NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	tx->tx_pool = dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	tx->tx_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	tx->tx_anyobj = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
dmu_tx_is_syncing(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
	return (tx->tx_anyobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
dmu_tx_private_ok(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    91
	return (tx->tx_anyobj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    94
static dmu_tx_hold_t *
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    96
    enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    98
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	dnode_t *dn = NULL;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   100
	int err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	if (object != DMU_NEW_OBJECT) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   103
		err = dnode_hold(os->os, object, tx, &dn);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   104
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   105
			tx->tx_err = err;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   106
			return (NULL);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   107
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   109
		if (err == 0 && tx->tx_txg != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
			mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
			 * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
			 * problem, but there's no way for it to happen (for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			 * now, at least).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			ASSERT(dn->dn_assigned_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
			dn->dn_assigned_txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   123
	txh = kmem_zalloc(sizeof (dmu_tx_hold_t), KM_SLEEP);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   124
	txh->txh_tx = tx;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   125
	txh->txh_dnode = dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   126
#ifdef ZFS_DEBUG
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   127
	txh->txh_type = type;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   128
	txh->txh_arg1 = arg1;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   129
	txh->txh_arg2 = arg2;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   130
#endif
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   131
	list_insert_tail(&tx->tx_holds, txh);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   132
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   133
	return (txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	 * If we're syncing, they can manipulate any object anyhow, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	 * the hold on the dnode_t can cause problems.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	if (!dmu_tx_is_syncing(tx)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   144
		(void) dmu_tx_hold_object_impl(tx, os,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   145
		    object, THT_NEWOBJECT, 0, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   149
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   150
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
   151
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   152
	int err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   153
	dmu_buf_impl_t *db;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   154
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   155
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   156
	db = dbuf_hold_level(dn, level, blkid, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   157
	rw_exit(&dn->dn_struct_rwlock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   158
	if (db == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   159
		return (EIO);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   160
	err = dbuf_read(db, zio, DB_RF_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   161
	dbuf_rele(db, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   162
	return (err);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   163
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   164
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   167
dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   169
	dnode_t *dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   170
	uint64_t start, end, i;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	int min_bs, max_bs, min_ibs, max_ibs, epbs, bits;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   172
	int err = 0;
789
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
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   182
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   184
	 * For i/o error checking, read the first and last level-0
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   185
	 * blocks (if they are not aligned), and all the level-1 blocks.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   186
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   187
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   188
	if (dn) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   189
		if (dn->dn_maxblkid == 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   190
			err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   191
			if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   192
				goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   193
		} else {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   194
			zio_t *zio = zio_root(dn->dn_objset->os_spa,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   195
			    NULL, NULL, ZIO_FLAG_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   196
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   197
			/* first level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   198
			start = off >> dn->dn_datablkshift;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   199
			if (P2PHASE(off, dn->dn_datablksz) ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   200
			    len < dn->dn_datablksz) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   201
				err = dmu_tx_check_ioerr(zio, dn, 0, start);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   202
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   203
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   204
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   205
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   206
			/* last level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   207
			end = (off+len-1) >> dn->dn_datablkshift;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   208
			if (end != start &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   209
			    P2PHASE(off+len, dn->dn_datablksz)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   210
				err = dmu_tx_check_ioerr(zio, dn, 0, end);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   211
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   212
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   213
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   214
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   215
			/* level-1 blocks */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   216
			if (dn->dn_nlevels > 1) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   217
				start >>= dn->dn_indblkshift - SPA_BLKPTRSHIFT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   218
				end >>= dn->dn_indblkshift - SPA_BLKPTRSHIFT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   219
				for (i = start+1; i < end; i++) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   220
					err = dmu_tx_check_ioerr(zio, dn, 1, i);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   221
					if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   222
						goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   223
				}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   224
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   225
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   226
			err = zio_wait(zio);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   227
			if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   228
				goto out;
1544
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
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
	 * If there's more than one block, the blocksize can't change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
	 * so we can make a more precise estimate.  Alternatively,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
	 * if the dnode's ibs is larger than max_ibs, always use that.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
	 * This ensures that if we reduce DN_MAX_INDBLKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
	 * the code will still work correctly on existing pools.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	if (dn && (dn->dn_maxblkid != 0 || dn->dn_indblkshift > max_ibs)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
		min_ibs = max_ibs = dn->dn_indblkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
		if (dn->dn_datablkshift != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
			min_bs = max_bs = dn->dn_datablkshift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	 * 'end' is the last thing we will access, not one past.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	 * This way we won't overflow when accessing the last byte.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	start = P2ALIGN(off, 1ULL << max_bs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   251
	txh->txh_space_towrite += end - start + 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	start >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	end >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	epbs = min_ibs - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	 * The object contains at most 2^(64 - min_bs) blocks,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	 * and each indirect level maps 2^epbs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
		start >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		end >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
		 * If we increase the number of levels of indirection,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
		 * we'll need new blkid=0 indirect blocks.  If start == 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
		 * we're already accounting for that blocks; and if end == 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
		 * we can't increase the number of levels beyond that.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
		if (start != 0 && end != 0)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   272
			txh->txh_space_towrite += 1ULL << max_ibs;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   273
		txh->txh_space_towrite += (end - start + 1) << max_ibs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   276
	ASSERT(txh->txh_space_towrite < 2 * DMU_MAX_ACCESS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   278
out:
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   279
	if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   280
		txh->txh_tx->tx_err = err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   284
dmu_tx_count_dnode(dmu_tx_hold_t *txh)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   286
	dnode_t *dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   287
	dnode_t *mdn = txh->txh_tx->tx_objset->os->os_meta_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   288
	uint64_t space = mdn->dn_datablksz +
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   289
	    ((mdn->dn_nlevels-1) << mdn->dn_indblkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
	if (dn && dn->dn_dbuf->db_blkptr &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
	    dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   293
	    dn->dn_dbuf->db_blkptr->blk_birth)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   294
		txh->txh_space_tooverwrite += space;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   295
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   296
		txh->txh_space_towrite += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   297
		if (dn && dn->dn_dbuf->db_blkptr)
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   298
			txh->txh_space_tounref += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
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
   304
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   305
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   306
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	ASSERT(tx->tx_txg == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   308
	ASSERT(len < DMU_MAX_ACCESS);
1819
570a79e4d798 6407842 zfs panic when closing a file
maybee
parents: 1793
diff changeset
   309
	ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   311
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   312
	    object, THT_WRITE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   313
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   314
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   315
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   316
	dmu_tx_count_write(txh, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   317
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   321
dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	uint64_t blkid, nblks;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   324
	uint64_t space = 0, unref = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   325
	dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   327
	spa_t *spa = txh->txh_tx->tx_pool->dp_spa;
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   328
	int dirty;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	/*
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   331
	 * We don't need to use any locking to check for dirtyness
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   332
	 * because it's OK if we get stale data -- the dnode may become
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1686
diff changeset
   333
	 * dirty immediately after our check anyway.  This is just a
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1686
diff changeset
   334
	 * means to avoid the expensive count when we aren't sure we
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   335
	 * need it.  We need to be able to deal with a dirty dnode.
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   336
	 */
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   337
	dirty = list_link_active(&dn->dn_dirty_link[0]) |
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   338
	    list_link_active(&dn->dn_dirty_link[1]) |
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   339
	    list_link_active(&dn->dn_dirty_link[2]) |
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   340
	    list_link_active(&dn->dn_dirty_link[3]);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   341
	if (dirty || dn->dn_assigned_txg || dn->dn_phys->dn_nlevels == 0)
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   342
		return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   343
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   344
	/*
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   345
	 * the struct_rwlock protects us against dn_phys->dn_nlevels
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   346
	 * changing, in case (against all odds) we manage to dirty &
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   347
	 * sync out the changes after we check for being dirty.
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   348
	 * also, dbuf_hold_impl() wants us to have the struct_rwlock.
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   349
	 *
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   350
	 * It's fine to use dn_datablkshift rather than the dn_phys
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   351
	 * equivalent because if it is changing, maxblkid==0 and we will
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   352
	 * bail.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   355
	if (dn->dn_phys->dn_maxblkid == 0) {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   356
		if (off == 0 && len >= dn->dn_datablksz) {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   357
			blkid = 0;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   358
			nblks = 1;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   359
		} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   360
			rw_exit(&dn->dn_struct_rwlock);
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   361
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   362
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   363
	} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   364
		blkid = off >> dn->dn_datablkshift;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   365
		nblks = (off + len) >> dn->dn_datablkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   367
		if (blkid >= dn->dn_phys->dn_maxblkid) {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   368
			rw_exit(&dn->dn_struct_rwlock);
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   369
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   370
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   371
		if (blkid + nblks > dn->dn_phys->dn_maxblkid)
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   372
			nblks = dn->dn_phys->dn_maxblkid - blkid;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   373
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   374
		/* don't bother after 128,000 blocks */
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   375
		nblks = MIN(nblks, 128*1024);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   376
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
	if (dn->dn_phys->dn_nlevels == 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
		for (i = 0; i < nblks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
			blkptr_t *bp = dn->dn_phys->dn_blkptr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
			ASSERT3U(blkid + i, <, dn->dn_phys->dn_nblkptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
			bp += blkid + i;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   384
			if (dsl_dataset_block_freeable(ds, bp->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
				dprintf_bp(bp, "can free old%s", "");
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   386
				space += bp_get_dasize(spa, bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
			}
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   388
			unref += BP_GET_ASIZE(bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   390
		nblks = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	while (nblks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		dmu_buf_impl_t *dbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
		int err, epbs, blkoff, tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
		epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
		blkoff = P2PHASE(blkid, 1<<epbs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
		tochk = MIN((1<<epbs) - blkoff, nblks);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
		err = dbuf_hold_impl(dn, 1, blkid >> epbs, TRUE, FTAG, &dbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
			int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
			blkptr_t *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   406
			err = dbuf_read(dbuf, NULL,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   407
			    DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   408
			if (err != 0) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   409
				txh->txh_tx->tx_err = err;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   410
				dbuf_rele(dbuf, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   411
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   412
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
			bp = dbuf->db.db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
			bp += blkoff;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
			for (i = 0; i < tochk; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
				if (dsl_dataset_block_freeable(ds,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   419
				    bp[i].blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
					dprintf_bp(&bp[i],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
					    "can free old%s", "");
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   422
					space += bp_get_dasize(spa, &bp[i]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
				}
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   424
				unref += BP_GET_ASIZE(bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
			}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   426
			dbuf_rele(dbuf, FTAG);
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   427
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   428
		if (err && err != ENOENT) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   429
			txh->txh_tx->tx_err = err;
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   430
			break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
		blkid += tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
		nblks -= tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
	rw_exit(&dn->dn_struct_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   438
	txh->txh_space_tofree += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   439
	txh->txh_space_tounref += unref;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   442
void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   443
dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   445
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   446
	dnode_t *dn;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   447
	uint64_t start, end, i;
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   448
	int err, shift;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   449
	zio_t *zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   451
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   452
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   453
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   454
	    object, THT_FREE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   455
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   456
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   457
	dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   458
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	/* first block */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   460
	if (off != 0)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   461
		dmu_tx_count_write(txh, off, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	/* last block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
	if (len != DMU_OBJECT_END)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   464
		dmu_tx_count_write(txh, off+len, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	if (len == DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   471
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   472
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   473
	 * blocks, and all the level-1 blocks.  The above count_write's
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   474
	 * will take care of the level-0 blocks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   475
	 */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   476
	if (dn->dn_nlevels > 1) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   477
		shift = dn->dn_datablkshift + dn->dn_indblkshift -
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   478
		    SPA_BLKPTRSHIFT;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   479
		start = off >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   480
		end = dn->dn_datablkshift ? ((off+len) >> shift) : 0;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   481
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   482
		zio = zio_root(tx->tx_pool->dp_spa,
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   483
		    NULL, NULL, ZIO_FLAG_CANFAIL);
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   484
		for (i = start; i <= end; i++) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   485
			uint64_t ibyte = i << shift;
3025
4e5ee8301d84 6424466 "panic: data after EOF" when unmounting abused pool
ahrens
parents: 2199
diff changeset
   486
			err = dnode_next_offset(dn, FALSE, &ibyte, 2, 1, 0);
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   487
			i = ibyte >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   488
			if (err == ESRCH)
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   489
				break;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   490
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   491
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   492
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   493
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   494
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   495
			err = dmu_tx_check_ioerr(zio, dn, 1, i);
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   496
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   497
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   498
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   499
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   500
		}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   501
		err = zio_wait(zio);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   502
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   503
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   504
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   505
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   506
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   507
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   508
	dmu_tx_count_dnode(txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   509
	dmu_tx_count_free(txh, off, len);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   513
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
   514
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   515
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   516
	dnode_t *dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   517
	uint64_t nblocks;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   518
	int epbs, err;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   519
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   522
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   523
	    object, THT_ZAP, add, (uintptr_t)name);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   524
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   525
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   526
	dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   528
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	if (dn == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   532
		 * We will be able to fit a new object's entries into one leaf
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
		 * block.  So there will be at most 2 blocks total,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
		 * including the header block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
		 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   536
		dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   542
	if (dn->dn_maxblkid == 0 && !add) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
		 * 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
   545
		 * and we are not adding anything, the accounting is simple.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   547
		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   548
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   549
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   550
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   551
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   552
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   553
		/*
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   554
		 * Use max block size here, since we don't know how much
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   555
		 * the size will change between now and the dbuf dirty call.
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   556
		 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   558
		    dn->dn_phys->dn_blkptr[0].blk_birth)) {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   559
			txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   560
		} else {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   561
			txh->txh_space_towrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   562
			txh->txh_space_tounref +=
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   563
			    BP_GET_ASIZE(dn->dn_phys->dn_blkptr);
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   564
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   568
	if (dn->dn_maxblkid > 0 && name) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   569
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   570
		 * access the name in this fat-zap so that we'll check
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   571
		 * for i/o errors to the leaf blocks, etc.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   572
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   573
		err = zap_lookup(&dn->dn_objset->os, dn->dn_object, name,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   574
		    8, 0, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   575
		if (err == EIO) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   576
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   577
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   578
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   579
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   580
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   582
	 * 3 blocks overwritten: target leaf, ptrtbl block, header block
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   583
	 * 3 new blocks written if adding: new split leaf, 2 grown ptrtbl blocks
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
	 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   585
	dmu_tx_count_write(txh, dn->dn_maxblkid * dn->dn_datablksz,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   586
	    (3 + add ? 3 : 0) << dn->dn_datablkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
	 * If the modified blocks are scattered to the four winds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
	 * we'll have to modify an indirect twig for each.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	for (nblocks = dn->dn_maxblkid >> epbs; nblocks != 0; nblocks >>= epbs)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   594
		txh->txh_space_towrite += 3 << dn->dn_indblkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   600
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   601
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   604
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   605
	    object, THT_BONUS, 0, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   606
	if (txh)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   607
		dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   613
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   616
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   617
	    DMU_NEW_OBJECT, THT_SPACE, space, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   618
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   619
	txh->txh_space_towrite += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   625
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
	int holds = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	 * By asserting that the tx is assigned, we're counting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
	 * number of dn_tx_holds, which is the same as the number of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	 * dn_tx_holds could be 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
	/* if (tx->tx_anyobj == TRUE) */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
		/* return (0); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   639
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   640
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   641
		if (txh->txh_dnode && txh->txh_dnode->dn_object == object)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
			holds++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
	return (holds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   648
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   652
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
	int match_object = FALSE, match_offset = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	dnode_t *dn = db->db_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset->os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
	ASSERT3U(dn->dn_object, ==, db->db.db_object);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
	if (tx->tx_anyobj)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
	/* XXX No checking on the meta dnode for now */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   664
	if (db->db.db_object == DMU_META_DNODE_OBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   667
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   668
	    txh = list_next(&tx->tx_holds, txh)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
		ASSERT(dn == NULL || dn->dn_assigned_txg == tx->tx_txg);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   670
		if (txh->txh_dnode == dn && txh->txh_type != THT_NEWOBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
			match_object = TRUE;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   672
		if (txh->txh_dnode == NULL || txh->txh_dnode == dn) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
			int datablkshift = dn->dn_datablkshift ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
			int shift = datablkshift + epbs * db->db_level;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
			uint64_t beginblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   678
			    (txh->txh_arg1 >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
			uint64_t endblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   680
			    ((txh->txh_arg1 + txh->txh_arg2 - 1) >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
			uint64_t blkid = db->db_blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   683
			/* XXX txh_arg2 better not be zero... */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   685
			dprintf("found txh type %x beginblk=%llx endblk=%llx\n",
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   686
			    txh->txh_type, beginblk, endblk);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   688
			switch (txh->txh_type) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
			case THT_WRITE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
				if (blkid >= beginblk && blkid <= endblk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
				 * We will let this hold work for the bonus
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
				 * buffer so that we don't need to hold it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
				 * when creating a new object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
				 * They might have to increase nlevels,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
				 * thus dirtying the new TLIBs.  Or the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
				 * might have to change the block size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
				 * thus dirying the new lvl=0 blk=0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
				if (blkid == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
			case THT_FREE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
				if (blkid == beginblk &&
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   710
				    (txh->txh_arg1 != 0 ||
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
				    dn->dn_maxblkid == 0))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
				if (blkid == endblk &&
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   714
				    txh->txh_arg2 != DMU_OBJECT_END)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
			case THT_BONUS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
			case THT_ZAP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
				match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
			case THT_NEWOBJECT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
				match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
			default:
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   728
				ASSERT(!"bad txh_type");
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
		if (match_object && match_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
	    (u_longlong_t)db->db.db_object, db->db_level,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
	    (u_longlong_t)db->db_blkid);
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   737
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
static int
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   741
dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   743
	dmu_tx_hold_t *txh;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   744
	spa_t *spa = tx->tx_pool->dp_spa;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   745
	uint64_t lsize, asize, fsize, usize;
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   746
	uint64_t towrite, tofree, tooverwrite, tounref;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   748
	ASSERT3U(tx->tx_txg, ==, 0);
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   749
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   750
	if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   751
		return (tx->tx_err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   753
	if (spa_state(spa) == POOL_STATE_IO_FAILURE) {
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   754
		/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   755
		 * If the user has indicated a blocking failure mode
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   756
		 * then return ERESTART which will block in dmu_tx_wait().
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   757
		 * Otherwise, return EIO so that an error can get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   758
		 * propagated back to the VOP calls.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   759
		 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   760
		 * Note that we always honor the txg_how flag regardless
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   761
		 * of the failuremode setting.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   762
		 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   763
		if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE &&
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   764
		    txg_how != TXG_WAIT)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   765
			return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   766
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   767
		return (ERESTART);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   768
	}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   769
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   770
	tx->tx_txg = txg_hold_open(tx->tx_pool, &tx->tx_txgh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   771
	tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   772
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   773
	/*
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   774
	 * NB: No error returns are allowed after txg_hold_open, but
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   775
	 * before processing the dnode holds, due to the
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   776
	 * dmu_tx_unassign() logic.
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   777
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   778
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   779
	towrite = tofree = tooverwrite = tounref = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   780
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   781
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   782
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
		if (dn != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
			mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   785
			if (dn->dn_assigned_txg == tx->tx_txg - 1) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   786
				mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   787
				tx->tx_needassign_txh = txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   788
				return (ERESTART);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
			}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   790
			if (dn->dn_assigned_txg == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
				dn->dn_assigned_txg = tx->tx_txg;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   792
			ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   796
		towrite += txh->txh_space_towrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   797
		tofree += txh->txh_space_tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   798
		tooverwrite += txh->txh_space_tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   799
		tounref += txh->txh_space_tounref;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   800
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   801
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   802
	/*
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   803
	 * NB: This check must be after we've held the dnodes, so that
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   804
	 * the dmu_tx_unassign() logic will work properly
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   805
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   806
	if (txg_how >= TXG_INITIAL && txg_how != tx->tx_txg)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   807
		return (ERESTART);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   808
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   809
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   810
	 * If a snapshot has been taken since we made our estimates,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   811
	 * assume that we won't be able to free or overwrite anything.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   812
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   813
	if (tx->tx_objset &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   814
	    dsl_dataset_prev_snap_txg(tx->tx_objset->os->os_dsl_dataset) >
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   815
	    tx->tx_lastsnap_txg) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   816
		towrite += tooverwrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   817
		tooverwrite = tofree = 0;
789
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
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
	 * Convert logical size to worst-case allocated size.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
	 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   823
	fsize = spa_get_asize(tx->tx_pool->dp_spa, tooverwrite) + tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   824
	lsize = towrite + tooverwrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
	asize = spa_get_asize(tx->tx_pool->dp_spa, lsize);
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   826
	usize = spa_get_asize(tx->tx_pool->dp_spa, tounref);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   827
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   828
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
	tx->tx_space_towrite = asize;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   830
	tx->tx_space_tofree = tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   831
	tx->tx_space_tooverwrite = tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   832
	tx->tx_space_tounref = tounref;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   833
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
	if (tx->tx_dir && asize != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
		int err = dsl_dir_tempreserve_space(tx->tx_dir,
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   837
		    lsize, asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   838
		if (err)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   845
static void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   846
dmu_tx_unassign(dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   848
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   850
	if (tx->tx_txg == 0)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   851
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   855
	for (txh = list_head(&tx->tx_holds); txh != tx->tx_needassign_txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   856
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   857
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
		mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   862
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
	txg_rele_to_sync(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   873
	tx->tx_lasttried_txg = tx->tx_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
	tx->tx_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
 * Assign tx to a transaction group.  txg_how can be one of:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
 * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
 *	a new one.  This should be used when you're not holding locks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
 *	If will only fail if we're truly out of space (or over quota).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
 * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
 *	blocking, returns immediately with ERESTART.  This should be used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
 *	whenever you're holding locks.  On an ERESTART error, the caller
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   887
 *	should drop locks, do a dmu_tx_wait(tx), and try again.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
 * (3)	A specific txg.  Use this if you need to ensure that multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
 *	transactions all sync in the same txg.  Like TXG_NOWAIT, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
 *	returns ERESTART if it can't assign you into the requested txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
	ASSERT(txg_how != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   902
	while ((err = dmu_tx_try_assign(tx, txg_how)) != 0) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   903
		dmu_tx_unassign(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
		if (err != ERESTART || txg_how != TXG_WAIT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   908
		dmu_tx_wait(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   917
dmu_tx_wait(dmu_tx_t *tx)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   918
{
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   919
	spa_t *spa = tx->tx_pool->dp_spa;
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   920
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   921
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   922
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   923
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   924
	 * It's possible that the pool has become active after this thread
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   925
	 * has tried to obtain a tx. If that's the case then his
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   926
	 * tx_lasttried_txg would not have been assigned.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   927
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   928
	if (spa_state(spa) == POOL_STATE_IO_FAILURE ||
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   929
	    tx->tx_lasttried_txg == 0) {
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   930
		txg_wait_synced(tx->tx_pool, spa_last_synced_txg(spa) + 1);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   931
	} else if (tx->tx_needassign_txh) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   932
		dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   933
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   934
		mutex_enter(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   935
		while (dn->dn_assigned_txg == tx->tx_lasttried_txg - 1)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   936
			cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   937
		mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   938
		tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   939
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   940
		txg_wait_open(tx->tx_pool, tx->tx_lasttried_txg + 1);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   941
	}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   942
}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   943
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   944
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   947
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
	if (tx->tx_dir == NULL || delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
	if (delta > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   952
		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
		    tx->tx_space_towrite);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   955
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   957
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   958
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
dmu_tx_commit(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   964
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   968
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   969
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   971
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   972
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
		dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   986
	if (tx->tx_tempreserve_cookie)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
	if (tx->tx_anyobj == FALSE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
		txg_rele_to_sync(&tx->tx_txgh);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   991
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
dmu_tx_abort(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1006
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1010
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1011
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1013
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1014
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
		if (dn != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
			dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1018
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
dmu_tx_get_txg(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1031
	return (tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
}