usr/src/uts/common/fs/zfs/dmu_tx.c
author ahrens
Tue, 31 Oct 2006 19:07:59 -0800
changeset 3025 4e5ee8301d84
parent 2199 712a788c2dfd
child 3245 0c86ad4b2673
permissions -rw-r--r--
6424466 "panic: data after EOF" when unmounting abused pool 6484044 destroying a clone takes O(data)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
     5
 * Common Development and Distribution License (the "License").
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 873
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/dmu_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/dbuf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/dmu_objset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/dsl_pool.h>
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;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
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
   302
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   303
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   304
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	ASSERT(tx->tx_txg == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   306
	ASSERT(len < DMU_MAX_ACCESS);
1819
570a79e4d798 6407842 zfs panic when closing a file
maybee
parents: 1793
diff changeset
   307
	ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   309
	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
   310
	    object, THT_WRITE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   311
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   312
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   313
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   314
	dmu_tx_count_write(txh, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   315
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   319
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
   320
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	uint64_t blkid, nblks;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	uint64_t space = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   323
	dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	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
   325
	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
   326
	int dirty;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	/*
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   329
	 * 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
   330
	 * 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
   331
	 * 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
   332
	 * 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
   333
	 * 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
   334
	 */
1600
d1ef3e135d5a 6397264 zfs-s10-0311:assertion failed:((&dnp->dn_blkptr[0])->blk_birth == 0)
ahrens
parents: 1596
diff changeset
   335
	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
   336
	    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
   337
	    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
   338
	    list_link_active(&dn->dn_dirty_link[3]);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   339
	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
   340
		return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   341
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   342
	/*
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   343
	 * 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
   344
	 * 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
   345
	 * 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
   346
	 * 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
   347
	 *
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   348
	 * 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
   349
	 * 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
   350
	 * bail.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	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
   353
	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
   354
		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
   355
			blkid = 0;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   356
			nblks = 1;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   357
		} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   358
			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
   359
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   360
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   361
	} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   362
		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
   363
		nblks = (off + len) >> dn->dn_datablkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   365
		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
   366
			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
   367
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   368
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   369
		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
   370
			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
   371
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   372
		/* 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
   373
		nblks = MIN(nblks, 128*1024);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   374
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
	if (dn->dn_phys->dn_nlevels == 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
		for (i = 0; i < nblks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
			blkptr_t *bp = dn->dn_phys->dn_blkptr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
			ASSERT3U(blkid + i, <, dn->dn_phys->dn_nblkptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
			bp += blkid + i;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   382
			if (dsl_dataset_block_freeable(ds, bp->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
				dprintf_bp(bp, "can free old%s", "");
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   384
				space += bp_get_dasize(spa, bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   387
		nblks = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
	while (nblks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
		dmu_buf_impl_t *dbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
		int err, epbs, blkoff, tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
		blkoff = P2PHASE(blkid, 1<<epbs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
		tochk = MIN((1<<epbs) - blkoff, nblks);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
		err = dbuf_hold_impl(dn, 1, blkid >> epbs, TRUE, FTAG, &dbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
		if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
			int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
			blkptr_t *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   403
			err = dbuf_read(dbuf, NULL,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   404
			    DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   405
			if (err != 0) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   406
				txh->txh_tx->tx_err = err;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   407
				dbuf_rele(dbuf, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   408
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   409
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
			bp = dbuf->db.db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
			bp += blkoff;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
			for (i = 0; i < tochk; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
				if (dsl_dataset_block_freeable(ds,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   416
				    bp[i].blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
					dprintf_bp(&bp[i],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
					    "can free old%s", "");
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   419
					space += bp_get_dasize(spa, &bp[i]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
			}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   422
			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
   423
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   424
		if (err && err != ENOENT) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   425
			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
   426
			break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
		blkid += tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
		nblks -= tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
	rw_exit(&dn->dn_struct_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   434
	txh->txh_space_tofree += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   437
void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   438
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
   439
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   440
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   441
	dnode_t *dn;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   442
	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
   443
	int err, shift;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   444
	zio_t *zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   446
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   447
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   448
	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
   449
	    object, THT_FREE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   450
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   451
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   452
	dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   453
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
	/* first block */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   455
	if (off != 0)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   456
		dmu_tx_count_write(txh, off, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	/* last block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
	if (len != DMU_OBJECT_END)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   459
		dmu_tx_count_write(txh, off+len, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
	if (len == DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   466
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   467
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   468
	 * blocks, and all the level-1 blocks.  The above count_write's
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   469
	 * will take care of the level-0 blocks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   470
	 */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   471
	if (dn->dn_nlevels > 1) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   472
		shift = dn->dn_datablkshift + dn->dn_indblkshift -
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   473
		    SPA_BLKPTRSHIFT;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   474
		start = off >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   475
		end = dn->dn_datablkshift ? ((off+len) >> shift) : 0;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   476
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   477
		zio = zio_root(tx->tx_pool->dp_spa,
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   478
		    NULL, NULL, ZIO_FLAG_CANFAIL);
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   479
		for (i = start; i <= end; i++) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   480
			uint64_t ibyte = i << shift;
3025
4e5ee8301d84 6424466 "panic: data after EOF" when unmounting abused pool
ahrens
parents: 2199
diff changeset
   481
			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
   482
			i = ibyte >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   483
			if (err == ESRCH)
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   484
				break;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   485
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   486
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   487
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   488
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   489
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   490
			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
   491
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   492
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   493
				return;
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
		}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   496
		err = zio_wait(zio);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   497
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   498
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   499
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   500
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   501
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   502
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   503
	dmu_tx_count_dnode(txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   504
	dmu_tx_count_free(txh, off, len);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   508
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
   509
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   510
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   511
	dnode_t *dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   512
	uint64_t nblocks;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   513
	int epbs, err;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   514
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   517
	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
   518
	    object, THT_ZAP, add, (uintptr_t)name);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   519
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   520
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   521
	dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   523
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
	if (dn == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   527
		 * We will be able to fit a new object's entries into one leaf
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
		 * block.  So there will be at most 2 blocks total,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
		 * including the header block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
		 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   531
		dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   537
	if (dn->dn_maxblkid == 0 && !add) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
		 * 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
   540
		 * and we are not adding anything, the accounting is simple.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   542
		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   543
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   544
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   545
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   546
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   547
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   549
		    dn->dn_phys->dn_blkptr[0].blk_birth))
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   550
			txh->txh_space_tooverwrite += dn->dn_datablksz;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
		else
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   552
			txh->txh_space_towrite += dn->dn_datablksz;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   556
	if (dn->dn_maxblkid > 0 && name) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   557
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   558
		 * access the name in this fat-zap so that we'll check
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   559
		 * for i/o errors to the leaf blocks, etc.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   560
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   561
		err = zap_lookup(&dn->dn_objset->os, dn->dn_object, name,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   562
		    8, 0, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   563
		if (err == EIO) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   564
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   565
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   566
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   567
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   568
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   570
	 * 3 blocks overwritten: target leaf, ptrtbl block, header block
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   571
	 * 3 new blocks written if adding: new split leaf, 2 grown ptrtbl blocks
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
	 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   573
	dmu_tx_count_write(txh, dn->dn_maxblkid * dn->dn_datablksz,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   574
	    (3 + add ? 3 : 0) << dn->dn_datablkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	 * If the modified blocks are scattered to the four winds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	 * we'll have to modify an indirect twig for each.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	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
   582
		txh->txh_space_towrite += 3 << dn->dn_indblkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   588
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   589
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   592
	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
   593
	    object, THT_BONUS, 0, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   594
	if (txh)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   595
		dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   601
	dmu_tx_hold_t *txh;
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
	    DMU_NEW_OBJECT, THT_SPACE, space, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   606
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   607
	txh->txh_space_towrite += space;
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
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
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
	int holds = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	 * By asserting that the tx is assigned, we're counting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
	 * number of dn_tx_holds, which is the same as the number of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	 * dn_tx_holds could be 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	/* if (tx->tx_anyobj == TRUE) */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
		/* return (0); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   627
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   628
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   629
		if (txh->txh_dnode && txh->txh_dnode->dn_object == object)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
			holds++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	return (holds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   636
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   640
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
	int match_object = FALSE, match_offset = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
	dnode_t *dn = db->db_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset->os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
	ASSERT3U(dn->dn_object, ==, db->db.db_object);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	if (tx->tx_anyobj)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
	/* XXX No checking on the meta dnode for now */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   652
	if (db->db.db_object == DMU_META_DNODE_OBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   655
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   656
	    txh = list_next(&tx->tx_holds, txh)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
		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
   658
		if (txh->txh_dnode == dn && txh->txh_type != THT_NEWOBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
			match_object = TRUE;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   660
		if (txh->txh_dnode == NULL || txh->txh_dnode == dn) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
			int datablkshift = dn->dn_datablkshift ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
			int shift = datablkshift + epbs * db->db_level;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
			uint64_t beginblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   666
			    (txh->txh_arg1 >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
			uint64_t endblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   668
			    ((txh->txh_arg1 + txh->txh_arg2 - 1) >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
			uint64_t blkid = db->db_blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   671
			/* XXX txh_arg2 better not be zero... */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   673
			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
   674
			    txh->txh_type, beginblk, endblk);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   676
			switch (txh->txh_type) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
			case THT_WRITE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
				if (blkid >= beginblk && blkid <= endblk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
				 * We will let this hold work for the bonus
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
				 * buffer so that we don't need to hold it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
				 * when creating a new object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
				 * They might have to increase nlevels,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
				 * thus dirtying the new TLIBs.  Or the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
				 * might have to change the block size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
				 * thus dirying the new lvl=0 blk=0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
				if (blkid == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
			case THT_FREE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
				if (blkid == beginblk &&
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   698
				    (txh->txh_arg1 != 0 ||
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
				    dn->dn_maxblkid == 0))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
				if (blkid == endblk &&
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   702
				    txh->txh_arg2 != DMU_OBJECT_END)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
			case THT_BONUS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
			case THT_ZAP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
				match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
			case THT_NEWOBJECT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
				match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
			default:
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   716
				ASSERT(!"bad txh_type");
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
		if (match_object && match_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
	    (u_longlong_t)db->db.db_object, db->db_level,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
	    (u_longlong_t)db->db_blkid);
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   725
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
static int
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   729
dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   731
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   732
	uint64_t lsize, asize, fsize, towrite, tofree, tooverwrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   734
	ASSERT3U(tx->tx_txg, ==, 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   735
	if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   736
		return (tx->tx_err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   738
	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
   739
	tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   740
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   741
	/*
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   742
	 * 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
   743
	 * before processing the dnode holds, due to the
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   744
	 * dmu_tx_unassign() logic.
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   745
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   746
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   747
	towrite = tofree = tooverwrite = 0;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   748
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   749
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   750
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
		if (dn != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
			mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   753
			if (dn->dn_assigned_txg == tx->tx_txg - 1) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   754
				mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   755
				tx->tx_needassign_txh = txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   756
				return (ERESTART);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
			}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   758
			if (dn->dn_assigned_txg == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
				dn->dn_assigned_txg = tx->tx_txg;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   760
			ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   764
		towrite += txh->txh_space_towrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   765
		tofree += txh->txh_space_tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   766
		tooverwrite += txh->txh_space_tooverwrite;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   767
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   768
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   769
	/*
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   770
	 * 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
   771
	 * the dmu_tx_unassign() logic will work properly
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
	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
   774
		return (ERESTART);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   775
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   776
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   777
	 * If a snapshot has been taken since we made our estimates,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   778
	 * assume that we won't be able to free or overwrite anything.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   779
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   780
	if (tx->tx_objset &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   781
	    dsl_dataset_prev_snap_txg(tx->tx_objset->os->os_dsl_dataset) >
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   782
	    tx->tx_lastsnap_txg) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   783
		towrite += tooverwrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   784
		tooverwrite = tofree = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
	 * Convert logical size to worst-case allocated size.
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
	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
   791
	lsize = towrite + tooverwrite;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
	asize = spa_get_asize(tx->tx_pool->dp_spa, lsize);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   793
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   794
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
	tx->tx_space_towrite = asize;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   796
	tx->tx_space_tofree = tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   797
	tx->tx_space_tooverwrite = tooverwrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   798
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
	if (tx->tx_dir && asize != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
		int err = dsl_dir_tempreserve_space(tx->tx_dir,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
		    lsize, asize, fsize, &tx->tx_tempreserve_cookie, tx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   803
		if (err)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   810
static void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   811
dmu_tx_unassign(dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   813
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   815
	if (tx->tx_txg == 0)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   816
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   820
	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
   821
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   822
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
		mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   827
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
	txg_rele_to_sync(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   838
	tx->tx_lasttried_txg = tx->tx_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	tx->tx_txg = 0;
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
 * Assign tx to a transaction group.  txg_how can be one of:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
 * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
 *	a new one.  This should be used when you're not holding locks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
 *	If will only fail if we're truly out of space (or over quota).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
 * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
 *	blocking, returns immediately with ERESTART.  This should be used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
 *	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
   852
 *	should drop locks, do a dmu_tx_wait(tx), and try again.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
 * (3)	A specific txg.  Use this if you need to ensure that multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
 *	transactions all sync in the same txg.  Like TXG_NOWAIT, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
 *	returns ERESTART if it can't assign you into the requested txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
	ASSERT(txg_how != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   867
	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
   868
		dmu_tx_unassign(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
		if (err != ERESTART || txg_how != TXG_WAIT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
			return (err);
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
		dmu_tx_wait(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   882
dmu_tx_wait(dmu_tx_t *tx)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   883
{
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   884
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   885
	ASSERT(tx->tx_lasttried_txg != 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   886
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   887
	if (tx->tx_needassign_txh) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   888
		dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   889
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   890
		mutex_enter(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   891
		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
   892
			cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   893
		mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   894
		tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   895
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   896
		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
   897
	}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   898
}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   899
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   900
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   903
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
	if (tx->tx_dir == NULL || delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
	if (delta > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
		    tx->tx_space_towrite);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   914
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   917
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
dmu_tx_commit(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   920
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   924
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   925
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   927
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   928
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
		dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   942
	if (tx->tx_tempreserve_cookie)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
	if (tx->tx_anyobj == FALSE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
		txg_rele_to_sync(&tx->tx_txgh);
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
	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   952
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   955
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   957
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   958
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
dmu_tx_abort(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   962
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   966
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   967
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   969
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   970
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
		if (dn != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
			dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   974
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
dmu_tx_get_txg(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
	return (tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
}