usr/src/uts/common/fs/zfs/dmu_tx.c
author Chris Kirby <Chris.Kirby@oracle.com>
Thu, 10 Jun 2010 15:46:47 -0600
changeset 12605 6790e683d5a5
parent 12450 c77e20e4e046
child 12684 397e44ebb8a9
permissions -rw-r--r--
6959846 DMU traverse prefetch size should be a global tunable
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
/*
12411
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
    22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#include <sys/dmu_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#include <sys/dbuf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/dmu_objset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/dsl_pool.h>
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    33
#include <sys/zap_impl.h> /* for fzap_default_block_shift */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/spa.h>
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
    35
#include <sys/sa.h>
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
    36
#include <sys/sa_impl.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/zfs_context.h>
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
    38
#include <sys/varargs.h>
789
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));
10612
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
    53
	list_create(&tx->tx_callbacks, sizeof (dmu_tx_callback_t),
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
    54
	    offsetof(dmu_tx_callback_t, dcb_node));
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    55
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	refcount_create(&tx->tx_space_written);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	refcount_create(&tx->tx_space_freed);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    58
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
dmu_tx_create(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
{
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
    65
	dmu_tx_t *tx = dmu_tx_create_dd(os->os_dsl_dataset->ds_dir);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	tx->tx_objset = os;
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
    67
	tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os_dsl_dataset);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
{
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    74
	dmu_tx_t *tx = dmu_tx_create_dd(NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	tx->tx_pool = dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
	tx->tx_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
	tx->tx_anyobj = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
dmu_tx_is_syncing(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	return (tx->tx_anyobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
dmu_tx_private_ok(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    93
	return (tx->tx_anyobj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    96
static dmu_tx_hold_t *
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
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
    98
    enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   100
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	dnode_t *dn = NULL;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   102
	int err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	if (object != DMU_NEW_OBJECT) {
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   105
		err = dnode_hold(os, object, tx, &dn);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   106
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   107
			tx->tx_err = err;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   108
			return (NULL);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   109
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   111
		if (err == 0 && tx->tx_txg != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
			mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			 * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			 * problem, but there's no way for it to happen (for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			 * now, at least).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
			ASSERT(dn->dn_assigned_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
			dn->dn_assigned_txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   125
	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
   126
	txh->txh_tx = tx;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   127
	txh->txh_dnode = dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   128
#ifdef ZFS_DEBUG
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   129
	txh->txh_type = type;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   130
	txh->txh_arg1 = arg1;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   131
	txh->txh_arg2 = arg2;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   132
#endif
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   133
	list_insert_tail(&tx->tx_holds, txh);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   134
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   135
	return (txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	 * If we're syncing, they can manipulate any object anyhow, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	 * the hold on the dnode_t can cause problems.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	if (!dmu_tx_is_syncing(tx)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   146
		(void) dmu_tx_hold_object_impl(tx, os,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   147
		    object, THT_NEWOBJECT, 0, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   151
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   152
dmu_tx_check_ioerr(zio_t *zio, dnode_t *dn, int level, uint64_t blkid)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   153
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   154
	int err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   155
	dmu_buf_impl_t *db;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   156
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   157
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   158
	db = dbuf_hold_level(dn, level, blkid, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   159
	rw_exit(&dn->dn_struct_rwlock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   160
	if (db == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   161
		return (EIO);
6245
1a2a7cfb9f26 6429205 each zpool needs to monitor its throughput and throttle heavy writers
maybee
parents: 5765
diff changeset
   162
	err = dbuf_read(db, zio, DB_RF_CANFAIL | DB_RF_NOPREFETCH);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   163
	dbuf_rele(db, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   164
	return (err);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   165
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   166
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   167
static void
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   168
dmu_tx_count_twig(dmu_tx_hold_t *txh, dnode_t *dn, dmu_buf_impl_t *db,
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   169
    int level, uint64_t blkid, boolean_t freeable, uint64_t *history)
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   170
{
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   171
	objset_t *os = dn->dn_objset;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   172
	dsl_dataset_t *ds = os->os_dsl_dataset;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   173
	int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   174
	dmu_buf_impl_t *parent = NULL;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   175
	blkptr_t *bp = NULL;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   176
	uint64_t space;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   177
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   178
	if (level >= dn->dn_nlevels || history[level] == blkid)
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   179
		return;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   180
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   181
	history[level] = blkid;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   182
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   183
	space = (level == 0) ? dn->dn_datablksz : (1ULL << dn->dn_indblkshift);
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   184
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   185
	if (db == NULL || db == dn->dn_dbuf) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   186
		ASSERT(level != 0);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   187
		db = NULL;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   188
	} else {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   189
		ASSERT(db->db_dnode == dn);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   190
		ASSERT(db->db_level == level);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   191
		ASSERT(db->db.db_size == space);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   192
		ASSERT(db->db_blkid == blkid);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   193
		bp = db->db_blkptr;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   194
		parent = db->db_parent;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   195
	}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   196
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   197
	freeable = (bp && (freeable ||
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   198
	    dsl_dataset_block_freeable(ds, bp, bp->blk_birth)));
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   199
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   200
	if (freeable)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   201
		txh->txh_space_tooverwrite += space;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   202
	else
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   203
		txh->txh_space_towrite += space;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   204
	if (bp)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   205
		txh->txh_space_tounref += bp_get_dsize(os->os_spa, bp);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   206
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   207
	dmu_tx_count_twig(txh, dn, parent, level + 1,
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   208
	    blkid >> epbs, freeable, history);
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   209
}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   210
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   213
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
   214
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   215
	dnode_t *dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   216
	uint64_t start, end, i;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	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
   218
	int err = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	if (len == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	min_bs = SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	max_bs = SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	min_ibs = DN_MIN_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	max_ibs = DN_MAX_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   228
	if (dn) {
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   229
		uint64_t history[DN_MAX_LEVELS];
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   230
		int nlvls = dn->dn_nlevels;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   231
		int delta;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   232
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   233
		/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   234
		 * For i/o error checking, read the first and last level-0
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   235
		 * blocks (if they are not aligned), and all the level-1 blocks.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   236
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   237
		if (dn->dn_maxblkid == 0) {
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   238
			delta = dn->dn_datablksz;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   239
			start = (off < dn->dn_datablksz) ? 0 : 1;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   240
			end = (off+len <= dn->dn_datablksz) ? 0 : 1;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   241
			if (start == 0 && (off > 0 || len < dn->dn_datablksz)) {
7872
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   242
				err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   243
				if (err)
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   244
					goto out;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   245
				delta -= off;
7872
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   246
			}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   247
		} else {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   248
			zio_t *zio = zio_root(dn->dn_objset->os_spa,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   249
			    NULL, NULL, ZIO_FLAG_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   250
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   251
			/* first level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   252
			start = off >> dn->dn_datablkshift;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   253
			if (P2PHASE(off, dn->dn_datablksz) ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   254
			    len < dn->dn_datablksz) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   255
				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
   256
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   257
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   258
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   259
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   260
			/* last level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   261
			end = (off+len-1) >> dn->dn_datablkshift;
7872
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   262
			if (end != start && end <= dn->dn_maxblkid &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   263
			    P2PHASE(off+len, dn->dn_datablksz)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   264
				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
   265
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   266
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   267
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   268
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   269
			/* level-1 blocks */
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   270
			if (nlvls > 1) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   271
				int shft = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   272
				for (i = (start>>shft)+1; i < end>>shft; i++) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   273
					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
   274
					if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   275
						goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   276
				}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   277
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   278
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   279
			err = zio_wait(zio);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   280
			if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   281
				goto out;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   282
			delta = P2NPHASE(off, dn->dn_datablksz);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   283
		}
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   284
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   285
		if (dn->dn_maxblkid > 0) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   286
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   287
			 * The blocksize can't change,
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   288
			 * so we can make a more precise estimate.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   289
			 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   290
			ASSERT(dn->dn_datablkshift != 0);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   291
			min_bs = max_bs = dn->dn_datablkshift;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   292
			min_ibs = max_ibs = dn->dn_indblkshift;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   293
		} else if (dn->dn_indblkshift > max_ibs) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   294
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   295
			 * This ensures that if we reduce DN_MAX_INDBLKSHIFT,
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   296
			 * the code will still work correctly on older pools.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   297
			 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   298
			min_ibs = max_ibs = dn->dn_indblkshift;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   299
		}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   300
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   301
		/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   302
		 * If this write is not off the end of the file
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   303
		 * we need to account for overwrites/unref.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   304
		 */
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   305
		if (start <= dn->dn_maxblkid) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   306
			for (int l = 0; l < DN_MAX_LEVELS; l++)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   307
				history[l] = -1ULL;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   308
		}
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   309
		while (start <= dn->dn_maxblkid) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   310
			dmu_buf_impl_t *db;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   311
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   312
			rw_enter(&dn->dn_struct_rwlock, RW_READER);
12411
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   313
			err = dbuf_hold_impl(dn, 0, start, FALSE, FTAG, &db);
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   314
			rw_exit(&dn->dn_struct_rwlock);
12411
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   315
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   316
			if (err) {
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   317
				txh->txh_tx->tx_err = err;
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   318
				return;
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   319
			}
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   320
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   321
			dmu_tx_count_twig(txh, dn, db, 0, start, B_FALSE,
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   322
			    history);
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   323
			dbuf_rele(db, FTAG);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   324
			if (++start > end) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   325
				/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   326
				 * Account for new indirects appearing
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   327
				 * before this IO gets assigned into a txg.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   328
				 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   329
				bits = 64 - min_bs;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   330
				epbs = min_ibs - SPA_BLKPTRSHIFT;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   331
				for (bits -= epbs * (nlvls - 1);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   332
				    bits >= 0; bits -= epbs)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   333
					txh->txh_fudge += 1ULL << max_ibs;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   334
				goto out;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   335
			}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   336
			off += delta;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   337
			if (len >= delta)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   338
				len -= delta;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   339
			delta = dn->dn_datablksz;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   340
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	 * 'end' is the last thing we will access, not one past.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	 * This way we won't overflow when accessing the last byte.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
	start = P2ALIGN(off, 1ULL << max_bs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   349
	txh->txh_space_towrite += end - start + 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	start >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	end >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	epbs = min_ibs - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	 * The object contains at most 2^(64 - min_bs) blocks,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	 * and each indirect level maps 2^epbs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
		start >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
		end >>= epbs;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   363
		ASSERT3U(end, >=, start);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   364
		txh->txh_space_towrite += (end - start + 1) << max_ibs;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   365
		if (start != 0) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   366
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   367
			 * We also need a new blkid=0 indirect block
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   368
			 * to reference any existing file data.
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   369
			 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   370
			txh->txh_space_towrite += 1ULL << max_ibs;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   371
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   374
out:
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   375
	if (txh->txh_space_towrite + txh->txh_space_tooverwrite >
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   376
	    2 * DMU_MAX_ACCESS)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   377
		err = EFBIG;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   379
	if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   380
		txh->txh_tx->tx_err = err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   384
dmu_tx_count_dnode(dmu_tx_hold_t *txh)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   386
	dnode_t *dn = txh->txh_dnode;
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   387
	dnode_t *mdn = txh->txh_tx->tx_objset->os_meta_dnode;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   388
	uint64_t space = mdn->dn_datablksz +
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   389
	    ((mdn->dn_nlevels-1) << mdn->dn_indblkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	if (dn && dn->dn_dbuf->db_blkptr &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
	    dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   393
	    dn->dn_dbuf->db_blkptr, dn->dn_dbuf->db_blkptr->blk_birth)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   394
		txh->txh_space_tooverwrite += space;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   395
		txh->txh_space_tounref += space;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   396
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   397
		txh->txh_space_towrite += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   398
		if (dn && dn->dn_dbuf->db_blkptr)
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   399
			txh->txh_space_tounref += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
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
   405
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   406
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   407
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
	ASSERT(tx->tx_txg == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   409
	ASSERT(len < DMU_MAX_ACCESS);
1819
570a79e4d798 6407842 zfs panic when closing a file
maybee
parents: 1793
diff changeset
   410
	ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   412
	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
   413
	    object, THT_WRITE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   414
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   415
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   416
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   417
	dmu_tx_count_write(txh, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   418
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   422
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
   423
{
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   424
	uint64_t blkid, nblks, lastblk;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   425
	uint64_t space = 0, unref = 0, skipped = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   426
	dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
	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
   428
	spa_t *spa = txh->txh_tx->tx_pool->dp_spa;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   429
	int epbs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   431
	if (dn->dn_nlevels == 0)
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   432
		return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   433
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   434
	/*
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   435
	 * The struct_rwlock protects us against dn_nlevels
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   436
	 * 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
   437
	 * sync out the changes after we check for being dirty.
12411
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   438
	 * Also, dbuf_hold_impl() wants us to have the struct_rwlock.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   441
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   442
	if (dn->dn_maxblkid == 0) {
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   443
		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
   444
			blkid = 0;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   445
			nblks = 1;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   446
		} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   447
			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
   448
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   449
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   450
	} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   451
		blkid = off >> dn->dn_datablkshift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   452
		nblks = (len + dn->dn_datablksz - 1) >> dn->dn_datablkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   454
		if (blkid >= dn->dn_maxblkid) {
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   455
			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
   456
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   457
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   458
		if (blkid + nblks > dn->dn_maxblkid)
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   459
			nblks = dn->dn_maxblkid - blkid;
1596
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   460
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   461
	}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   462
	if (dn->dn_nlevels == 1) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
		for (i = 0; i < nblks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
			blkptr_t *bp = dn->dn_phys->dn_blkptr;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   466
			ASSERT3U(blkid + i, <, dn->dn_nblkptr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
			bp += blkid + i;
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   468
			if (dsl_dataset_block_freeable(ds, bp, bp->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
				dprintf_bp(bp, "can free old%s", "");
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   470
				space += bp_get_dsize(spa, bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
			}
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   472
			unref += BP_GET_ASIZE(bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   474
		nblks = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   477
	/*
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   478
	 * Add in memory requirements of higher-level indirects.
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   479
	 * This assumes a worst-possible scenario for dn_nlevels.
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   480
	 */
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   481
	{
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   482
		uint64_t blkcnt = 1 + ((nblks >> epbs) >> epbs);
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   483
		int level = (dn->dn_nlevels > 1) ? 2 : 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   484
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   485
		while (level++ < DN_MAX_LEVELS) {
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   486
			txh->txh_memory_tohold += blkcnt << dn->dn_indblkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   487
			blkcnt = 1 + (blkcnt >> epbs);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   488
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   489
		ASSERT(blkcnt <= dn->dn_nblkptr);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   490
	}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   491
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   492
	lastblk = blkid + nblks - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
	while (nblks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
		dmu_buf_impl_t *dbuf;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   495
		uint64_t ibyte, new_blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   496
		int epb = 1 << epbs;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   497
		int err, i, blkoff, tochk;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   498
		blkptr_t *bp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   500
		ibyte = blkid << dn->dn_datablkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   501
		err = dnode_next_offset(dn,
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   502
		    DNODE_FIND_HAVELOCK, &ibyte, 2, 1, 0);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   503
		new_blkid = ibyte >> dn->dn_datablkshift;
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   504
		if (err == ESRCH) {
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   505
			skipped += (lastblk >> epbs) - (blkid >> epbs) + 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   506
			break;
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   507
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   508
		if (err) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   509
			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
   510
			break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
		}
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   512
		if (new_blkid > lastblk) {
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   513
			skipped += (lastblk >> epbs) - (blkid >> epbs) + 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   514
			break;
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   515
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   516
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   517
		if (new_blkid > blkid) {
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   518
			ASSERT((new_blkid >> epbs) > (blkid >> epbs));
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   519
			skipped += (new_blkid >> epbs) - (blkid >> epbs) - 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   520
			nblks -= new_blkid - blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   521
			blkid = new_blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   522
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   523
		blkoff = P2PHASE(blkid, epb);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   524
		tochk = MIN(epb - blkoff, nblks);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   525
12411
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   526
		err = dbuf_hold_impl(dn, 1, blkid >> epbs, FALSE, FTAG, &dbuf);
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   527
		if (err) {
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   528
			txh->txh_tx->tx_err = err;
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   529
			break;
3e9af067a727 6911391 panic in dmu_tx_count_write()
John Harres <John.Harres@Sun.COM>
parents: 11935
diff changeset
   530
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   531
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   532
		txh->txh_memory_tohold += dbuf->db.db_size;
11550
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   533
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   534
		/*
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   535
		 * We don't check memory_tohold against DMU_MAX_ACCESS because
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   536
		 * memory_tohold is an over-estimation (especially the >L1
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   537
		 * indirect blocks), so it could fail.  Callers should have
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   538
		 * already verified that they will not be holding too much
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   539
		 * memory.
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   540
		 */
e63888bb788a 6910767 deleting large holey objects hangs other I/Os
Lori Alt <Lori.Alt@Sun.COM>
parents: 10922
diff changeset
   541
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   542
		err = dbuf_read(dbuf, NULL, DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   543
		if (err != 0) {
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   544
			txh->txh_tx->tx_err = err;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   545
			dbuf_rele(dbuf, FTAG);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   546
			break;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   547
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   548
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   549
		bp = dbuf->db.db_data;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   550
		bp += blkoff;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   551
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   552
		for (i = 0; i < tochk; i++) {
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   553
			if (dsl_dataset_block_freeable(ds, &bp[i],
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   554
			    bp[i].blk_birth)) {
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   555
				dprintf_bp(&bp[i], "can free old%s", "");
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   556
				space += bp_get_dsize(spa, &bp[i]);
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   557
			}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   558
			unref += BP_GET_ASIZE(bp);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   559
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   560
		dbuf_rele(dbuf, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
		blkid += tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
		nblks -= tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
	rw_exit(&dn->dn_struct_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   567
	/* account for new level 1 indirect blocks that might show up */
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   568
	if (skipped > 0) {
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   569
		txh->txh_fudge += skipped << dn->dn_indblkshift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   570
		skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   571
		txh->txh_memory_tohold += skipped << dn->dn_indblkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   572
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   573
	txh->txh_space_tofree += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   574
	txh->txh_space_tounref += unref;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   577
void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   578
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
   579
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   580
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   581
	dnode_t *dn;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   582
	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
   583
	int err, shift;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   584
	zio_t *zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   586
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   587
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   588
	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
   589
	    object, THT_FREE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   590
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   591
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   592
	dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   593
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
	/* first block */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   595
	if (off != 0)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   596
		dmu_tx_count_write(txh, off, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
	/* last block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	if (len != DMU_OBJECT_END)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   599
		dmu_tx_count_write(txh, off+len, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   601
	dmu_tx_count_dnode(txh);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10612
diff changeset
   602
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	if (len == DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   608
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   609
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   610
	 * blocks, and all the level-1 blocks.  The above count_write's
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   611
	 * have already taken care of the level-0 blocks.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   612
	 */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   613
	if (dn->dn_nlevels > 1) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   614
		shift = dn->dn_datablkshift + dn->dn_indblkshift -
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   615
		    SPA_BLKPTRSHIFT;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   616
		start = off >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   617
		end = dn->dn_datablkshift ? ((off+len) >> shift) : 0;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   618
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   619
		zio = zio_root(tx->tx_pool->dp_spa,
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   620
		    NULL, NULL, ZIO_FLAG_CANFAIL);
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   621
		for (i = start; i <= end; i++) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   622
			uint64_t ibyte = i << shift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   623
			err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0);
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   624
			i = ibyte >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   625
			if (err == ESRCH)
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   626
				break;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   627
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   628
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   629
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   630
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   631
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   632
			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
   633
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   634
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   635
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   636
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   637
		}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   638
		err = zio_wait(zio);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   639
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   640
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   641
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   642
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   643
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   644
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   645
	dmu_tx_count_free(txh, off, len);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
void
9396
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8890
diff changeset
   649
dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   651
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   652
	dnode_t *dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   653
	uint64_t nblocks;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   654
	int epbs, err;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   655
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   658
	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
   659
	    object, THT_ZAP, add, (uintptr_t)name);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   660
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   661
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   662
	dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   664
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	if (dn == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   668
		 * We will be able to fit a new object's entries into one leaf
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
		 * block.  So there will be at most 2 blocks total,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
		 * including the header block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
		 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   672
		dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
	ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   678
	if (dn->dn_maxblkid == 0 && !add) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
		 * 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
   681
		 * and we are not adding anything, the accounting is simple.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   683
		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   684
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   685
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   686
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   687
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   688
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   689
		/*
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   690
		 * Use max block size here, since we don't know how much
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   691
		 * the size will change between now and the dbuf dirty call.
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   692
		 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
   694
		    &dn->dn_phys->dn_blkptr[0],
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   695
		    dn->dn_phys->dn_blkptr[0].blk_birth)) {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   696
			txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   697
		} else {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   698
			txh->txh_space_towrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   699
		}
8890
8c2bd5f17bf2 6798878 Unable to remove a file over NFS after hitting refquota limit
Chris Kirby <chris.kirby@sun.com>
parents: 8768
diff changeset
   700
		if (dn->dn_phys->dn_blkptr[0].blk_birth)
8c2bd5f17bf2 6798878 Unable to remove a file over NFS after hitting refquota limit
Chris Kirby <chris.kirby@sun.com>
parents: 8768
diff changeset
   701
			txh->txh_space_tounref += SPA_MAXBLOCKSIZE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   705
	if (dn->dn_maxblkid > 0 && name) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   706
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   707
		 * access the name in this fat-zap so that we'll check
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   708
		 * for i/o errors to the leaf blocks, etc.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   709
		 */
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   710
		err = zap_lookup(dn->dn_objset, dn->dn_object, name,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   711
		    8, 0, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   712
		if (err == EIO) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   713
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   714
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   715
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   716
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   717
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   718
	err = zap_count_write(dn->dn_objset, dn->dn_object, name, add,
9873
8ddc892eca6e 6847229 assertion failed: refcount_count(&tx->tx_space_written) + delta <= tx->tx_space_towrite in dmu_tx.c
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9653
diff changeset
   719
	    &txh->txh_space_towrite, &txh->txh_space_tooverwrite);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
	 * If the modified blocks are scattered to the four winds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
	 * we'll have to modify an indirect twig for each.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
	for (nblocks = dn->dn_maxblkid >> epbs; nblocks != 0; nblocks >>= epbs)
9653
a70048a304d1 6664765 Unable to remove files when using fat-zap and quota exceeded on ZFS filesystem
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
   727
		if (dn->dn_objset->os_dsl_dataset->ds_phys->ds_prev_snap_obj)
a70048a304d1 6664765 Unable to remove files when using fat-zap and quota exceeded on ZFS filesystem
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
   728
			txh->txh_space_towrite += 3 << dn->dn_indblkshift;
a70048a304d1 6664765 Unable to remove files when using fat-zap and quota exceeded on ZFS filesystem
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
   729
		else
a70048a304d1 6664765 Unable to remove files when using fat-zap and quota exceeded on ZFS filesystem
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
   730
			txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   736
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   737
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   740
	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
   741
	    object, THT_BONUS, 0, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   742
	if (txh)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   743
		dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   749
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   752
	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
   753
	    DMU_NEW_OBJECT, THT_SPACE, space, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   754
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   755
	txh->txh_space_towrite += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   761
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
	int holds = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	 * By asserting that the tx is assigned, we're counting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	 * number of dn_tx_holds, which is the same as the number of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	 * dn_tx_holds could be 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
	/* if (tx->tx_anyobj == TRUE) */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
		/* return (0); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   775
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   776
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   777
		if (txh->txh_dnode && txh->txh_dnode->dn_object == object)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
			holds++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
	return (holds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   784
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   788
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
	int match_object = FALSE, match_offset = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
	dnode_t *dn = db->db_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
	ASSERT(tx->tx_txg != 0);
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   793
	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
	ASSERT3U(dn->dn_object, ==, db->db.db_object);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
	if (tx->tx_anyobj)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
	/* XXX No checking on the meta dnode for now */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   800
	if (db->db.db_object == DMU_META_DNODE_OBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   803
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   804
	    txh = list_next(&tx->tx_holds, txh)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
		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
   806
		if (txh->txh_dnode == dn && txh->txh_type != THT_NEWOBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
			match_object = TRUE;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   808
		if (txh->txh_dnode == NULL || txh->txh_dnode == dn) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
			int datablkshift = dn->dn_datablkshift ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
			int shift = datablkshift + epbs * db->db_level;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
			uint64_t beginblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   814
			    (txh->txh_arg1 >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
			uint64_t endblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   816
			    ((txh->txh_arg1 + txh->txh_arg2 - 1) >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
			uint64_t blkid = db->db_blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   819
			/* XXX txh_arg2 better not be zero... */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   821
			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
   822
			    txh->txh_type, beginblk, endblk);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   824
			switch (txh->txh_type) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
			case THT_WRITE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
				if (blkid >= beginblk && blkid <= endblk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
				 * We will let this hold work for the bonus
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   830
				 * or spill buffer so that we don't need to
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   831
				 * hold it when creating a new object.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
				 */
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   833
				if (blkid == DMU_BONUS_BLKID ||
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   834
				    blkid == DMU_SPILL_BLKID)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
				 * They might have to increase nlevels,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
				 * thus dirtying the new TLIBs.  Or the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
				 * might have to change the block size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
				 * thus dirying the new lvl=0 blk=0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
				if (blkid == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
			case THT_FREE:
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   846
				/*
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   847
				 * We will dirty all the level 1 blocks in
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   848
				 * the free range and perhaps the first and
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   849
				 * last level 0 block.
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   850
				 */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   851
				if (blkid >= beginblk && (blkid <= endblk ||
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   852
				    txh->txh_arg2 == DMU_OBJECT_END))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
				break;
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   855
			case THT_SPILL:
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   856
				if (blkid == DMU_SPILL_BLKID)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   857
					match_offset = TRUE;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   858
				break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
			case THT_BONUS:
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
   860
				if (blkid == DMU_BONUS_BLKID)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
			case THT_ZAP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
				match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
			case THT_NEWOBJECT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
				match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
			default:
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   870
				ASSERT(!"bad txh_type");
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
		if (match_object && match_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
	    (u_longlong_t)db->db.db_object, db->db_level,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
	    (u_longlong_t)db->db_blkid);
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   879
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
static int
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   883
dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   885
	dmu_tx_hold_t *txh;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   886
	spa_t *spa = tx->tx_pool->dp_spa;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   887
	uint64_t memory, asize, fsize, usize;
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   888
	uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   890
	ASSERT3U(tx->tx_txg, ==, 0);
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   891
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   892
	if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   893
		return (tx->tx_err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
7754
b80e4842ad54 6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 7161
diff changeset
   895
	if (spa_suspended(spa)) {
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   896
		/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   897
		 * If the user has indicated a blocking failure mode
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   898
		 * then return ERESTART which will block in dmu_tx_wait().
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   899
		 * Otherwise, return EIO so that an error can get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   900
		 * propagated back to the VOP calls.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   901
		 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   902
		 * Note that we always honor the txg_how flag regardless
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   903
		 * of the failuremode setting.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   904
		 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   905
		if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE &&
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   906
		    txg_how != TXG_WAIT)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   907
			return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   908
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   909
		return (ERESTART);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   910
	}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   911
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   912
	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
   913
	tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   914
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   915
	/*
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   916
	 * 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
   917
	 * before processing the dnode holds, due to the
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   918
	 * dmu_tx_unassign() logic.
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   919
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   920
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   921
	towrite = tofree = tooverwrite = tounref = tohold = fudge = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   922
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   923
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   924
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
		if (dn != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
			mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   927
			if (dn->dn_assigned_txg == tx->tx_txg - 1) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   928
				mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   929
				tx->tx_needassign_txh = txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   930
				return (ERESTART);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
			}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   932
			if (dn->dn_assigned_txg == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
				dn->dn_assigned_txg = tx->tx_txg;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   934
			ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   938
		towrite += txh->txh_space_towrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   939
		tofree += txh->txh_space_tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   940
		tooverwrite += txh->txh_space_tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   941
		tounref += txh->txh_space_tounref;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   942
		tohold += txh->txh_memory_tohold;
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   943
		fudge += txh->txh_fudge;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   944
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   945
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   946
	/*
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   947
	 * 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
   948
	 * the dmu_tx_unassign() logic will work properly
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   949
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   950
	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
   951
		return (ERESTART);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   952
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   953
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   954
	 * If a snapshot has been taken since we made our estimates,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   955
	 * assume that we won't be able to free or overwrite anything.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   956
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   957
	if (tx->tx_objset &&
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9873
diff changeset
   958
	    dsl_dataset_prev_snap_txg(tx->tx_objset->os_dsl_dataset) >
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   959
	    tx->tx_lastsnap_txg) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   960
		towrite += tooverwrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   961
		tooverwrite = tofree = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   964
	/* needed allocation: worst-case estimate of write space */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   965
	asize = spa_get_asize(tx->tx_pool->dp_spa, towrite + tooverwrite);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   966
	/* freed space estimate: worst-case overwrite + free estimate */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   967
	fsize = spa_get_asize(tx->tx_pool->dp_spa, tooverwrite) + tofree;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   968
	/* convert unrefd space to worst-case estimate */
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   969
	usize = spa_get_asize(tx->tx_pool->dp_spa, tounref);
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   970
	/* calculate memory footprint estimate */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   971
	memory = towrite + tooverwrite + tohold;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   972
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   973
#ifdef ZFS_DEBUG
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   974
	/*
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   975
	 * Add in 'tohold' to account for our dirty holds on this memory
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   976
	 * XXX - the "fudge" factor is to account for skipped blocks that
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   977
	 * we missed because dnode_next_offset() misses in-core-only blocks.
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   978
	 */
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   979
	tx->tx_space_towrite = asize +
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   980
	    spa_get_asize(tx->tx_pool->dp_spa, tohold + fudge);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   981
	tx->tx_space_tofree = tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   982
	tx->tx_space_tooverwrite = tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   983
	tx->tx_space_tounref = tounref;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   984
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
	if (tx->tx_dir && asize != 0) {
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   987
		int err = dsl_dir_tempreserve_space(tx->tx_dir, memory,
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   988
		    asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   989
		if (err)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   996
static void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   997
dmu_tx_unassign(dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   999
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1001
	if (tx->tx_txg == 0)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1002
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1006
	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
  1007
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1008
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
		mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1013
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
	txg_rele_to_sync(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1024
	tx->tx_lasttried_txg = tx->tx_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
	tx->tx_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
 * Assign tx to a transaction group.  txg_how can be one of:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1031
 * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
 *	a new one.  This should be used when you're not holding locks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
 *	If will only fail if we're truly out of space (or over quota).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
 * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
 *	blocking, returns immediately with ERESTART.  This should be used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
 *	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
  1038
 *	should drop locks, do a dmu_tx_wait(tx), and try again.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
 * (3)	A specific txg.  Use this if you need to ensure that multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
 *	transactions all sync in the same txg.  Like TXG_NOWAIT, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
 *	returns ERESTART if it can't assign you into the requested txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1046
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1049
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
	ASSERT(txg_how != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1053
	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
  1054
		dmu_tx_unassign(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
		if (err != ERESTART || txg_how != TXG_WAIT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1059
		dmu_tx_wait(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1063
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1064
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1066
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1068
dmu_tx_wait(dmu_tx_t *tx)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1069
{
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1070
	spa_t *spa = tx->tx_pool->dp_spa;
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1071
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1072
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1073
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1074
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1075
	 * It's possible that the pool has become active after this thread
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1076
	 * has tried to obtain a tx. If that's the case then his
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1077
	 * tx_lasttried_txg would not have been assigned.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1078
	 */
7754
b80e4842ad54 6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 7161
diff changeset
  1079
	if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) {
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1080
		txg_wait_synced(tx->tx_pool, spa_last_synced_txg(spa) + 1);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1081
	} else if (tx->tx_needassign_txh) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1082
		dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1083
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1084
		mutex_enter(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1085
		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
  1086
			cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1087
		mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1088
		tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1089
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1090
		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
  1091
	}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1092
}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1093
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1094
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1095
dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1097
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
	if (tx->tx_dir == NULL || delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
	if (delta > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
		    tx->tx_space_towrite);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1108
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
dmu_tx_commit(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1114
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1118
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1119
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1121
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1122
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
		dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1136
	if (tx->tx_tempreserve_cookie)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
10612
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1139
	if (!list_is_empty(&tx->tx_callbacks))
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1140
		txg_register_callbacks(&tx->tx_txgh, &tx->tx_callbacks);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1141
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
	if (tx->tx_anyobj == FALSE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
		txg_rele_to_sync(&tx->tx_txgh);
10612
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1144
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1145
	list_destroy(&tx->tx_callbacks);
5765
86c482ef4a34 6646545 Condvars in tx_cpu aren't being initialized/destroyed
ek110237
parents: 5378
diff changeset
  1146
	list_destroy(&tx->tx_holds);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1147
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
dmu_tx_abort(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1162
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1166
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1167
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1169
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1170
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
		if (dn != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
			dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
	}
10612
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1174
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1175
	/*
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1176
	 * Call any registered callbacks with an error code.
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1177
	 */
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1178
	if (!list_is_empty(&tx->tx_callbacks))
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1179
		dmu_tx_do_callbacks(&tx->tx_callbacks, ECANCELED);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1180
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1181
	list_destroy(&tx->tx_callbacks);
5765
86c482ef4a34 6646545 Condvars in tx_cpu aren't being initialized/destroyed
ek110237
parents: 5378
diff changeset
  1182
	list_destroy(&tx->tx_holds);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1183
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
dmu_tx_get_txg(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
	return (tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
}
10612
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1198
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1199
void
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1200
dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *func, void *data)
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1201
{
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1202
	dmu_tx_callback_t *dcb;
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1203
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1204
	dcb = kmem_alloc(sizeof (dmu_tx_callback_t), KM_SLEEP);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1205
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1206
	dcb->dcb_func = func;
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1207
	dcb->dcb_data = data;
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1208
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1209
	list_insert_tail(&tx->tx_callbacks, dcb);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1210
}
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1211
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1212
/*
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1213
 * Call all the commit callbacks on a list, with a given error code.
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1214
 */
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1215
void
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1216
dmu_tx_do_callbacks(list_t *cb_list, int error)
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1217
{
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1218
	dmu_tx_callback_t *dcb;
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1219
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1220
	while (dcb = list_head(cb_list)) {
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1221
		list_remove(cb_list, dcb);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1222
		dcb->dcb_func(dcb->dcb_data, error);
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1223
		kmem_free(dcb, sizeof (dmu_tx_callback_t));
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1224
	}
89423355fa6f 6650218 Commit callbacks API for the DMU
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 10298
diff changeset
  1225
}
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1226
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1227
/*
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1228
 * Interface to hold a bunch of attributes.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1229
 * used for creating new files.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1230
 * attrsize is the total size of all attributes
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1231
 * to be added during object creation
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1232
 *
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1233
 * For updating/adding a single attribute dmu_tx_hold_sa() should be used.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1234
 */
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1235
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1236
/*
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1237
 * hold necessary attribute name for attribute registration.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1238
 * should be a very rare case where this is needed.  If it does
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1239
 * happen it would only happen on the first write to the file system.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1240
 */
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1241
static void
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1242
dmu_tx_sa_registration_hold(sa_os_t *sa, dmu_tx_t *tx)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1243
{
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1244
	int i;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1245
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1246
	if (!sa->sa_need_attr_registration)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1247
		return;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1248
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1249
	for (i = 0; i != sa->sa_num_attrs; i++) {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1250
		if (!sa->sa_attr_table[i].sa_registered) {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1251
			if (sa->sa_reg_attr_obj)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1252
				dmu_tx_hold_zap(tx, sa->sa_reg_attr_obj,
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1253
				    B_TRUE, sa->sa_attr_table[i].sa_name);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1254
			else
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1255
				dmu_tx_hold_zap(tx, DMU_NEW_OBJECT,
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1256
				    B_TRUE, sa->sa_attr_table[i].sa_name);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1257
		}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1258
	}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1259
}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1260
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1261
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1262
void
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1263
dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1264
{
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1265
	dnode_t *dn;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1266
	dmu_tx_hold_t *txh;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1267
	blkptr_t *bp;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1268
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1269
	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset, object,
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1270
	    THT_SPILL, 0, 0);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1271
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1272
	dn = txh->txh_dnode;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1273
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1274
	if (dn == NULL)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1275
		return;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1276
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1277
	/* If blkptr doesn't exist then add space to towrite */
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1278
	bp = &dn->dn_phys->dn_spill;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1279
	if (BP_IS_HOLE(bp)) {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1280
		txh->txh_space_towrite += SPA_MAXBLOCKSIZE;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1281
		txh->txh_space_tounref = 0;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1282
	} else {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1283
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
12450
c77e20e4e046 6938089 dedup-induced latency causes FC initiator logouts/FC port resets
George Wilson <George.Wilson@Sun.COM>
parents: 12411
diff changeset
  1284
		    bp, bp->blk_birth))
11935
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1285
			txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1286
		else
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1287
			txh->txh_space_towrite += SPA_MAXBLOCKSIZE;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1288
		if (bp->blk_birth)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1289
			txh->txh_space_tounref += SPA_MAXBLOCKSIZE;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1290
	}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1291
}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1292
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1293
void
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1294
dmu_tx_hold_sa_create(dmu_tx_t *tx, int attrsize)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1295
{
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1296
	sa_os_t *sa = tx->tx_objset->os_sa;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1297
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1298
	dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1299
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1300
	if (tx->tx_objset->os_sa->sa_master_obj == 0)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1301
		return;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1302
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1303
	if (tx->tx_objset->os_sa->sa_layout_attr_obj)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1304
		dmu_tx_hold_zap(tx, sa->sa_layout_attr_obj, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1305
	else {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1306
		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_LAYOUTS);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1307
		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_REGISTRY);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1308
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1309
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1310
	}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1311
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1312
	dmu_tx_sa_registration_hold(sa, tx);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1313
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1314
	if (attrsize <= DN_MAX_BONUSLEN && !sa->sa_force_spill)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1315
		return;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1316
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1317
	(void) dmu_tx_hold_object_impl(tx, tx->tx_objset, DMU_NEW_OBJECT,
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1318
	    THT_SPILL, 0, 0);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1319
}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1320
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1321
/*
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1322
 * Hold SA attribute
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1323
 *
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1324
 * dmu_tx_hold_sa(dmu_tx_t *tx, sa_handle_t *, attribute, add, size)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1325
 *
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1326
 * variable_size is the total size of all variable sized attributes
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1327
 * passed to this function.  It is not the total size of all
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1328
 * variable size attributes that *may* exist on this object.
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1329
 */
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1330
void
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1331
dmu_tx_hold_sa(dmu_tx_t *tx, sa_handle_t *hdl, boolean_t may_grow)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1332
{
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1333
	uint64_t object;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1334
	sa_os_t *sa = tx->tx_objset->os_sa;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1335
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1336
	ASSERT(hdl != NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1337
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1338
	object = sa_handle_object(hdl);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1339
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1340
	dmu_tx_hold_bonus(tx, object);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1341
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1342
	if (tx->tx_objset->os_sa->sa_master_obj == 0)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1343
		return;
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1344
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1345
	if (tx->tx_objset->os_sa->sa_reg_attr_obj == 0 ||
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1346
	    tx->tx_objset->os_sa->sa_layout_attr_obj == 0) {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1347
		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_LAYOUTS);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1348
		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_REGISTRY);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1349
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1350
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1351
	}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1352
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1353
	dmu_tx_sa_registration_hold(sa, tx);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1354
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1355
	if (may_grow && tx->tx_objset->os_sa->sa_layout_attr_obj)
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1356
		dmu_tx_hold_zap(tx, sa->sa_layout_attr_obj, B_TRUE, NULL);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1357
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1358
	if (sa->sa_force_spill || may_grow || hdl->sa_spill ||
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1359
	    ((dmu_buf_impl_t *)hdl->sa_bonus)->db_dnode->dn_have_spill) {
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1360
		ASSERT(tx->tx_txg == 0);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1361
		dmu_tx_hold_spill(tx, object);
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1362
	}
538c866aaac6 6716117 ZFS needs native system attribute infrastructure
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 11550
diff changeset
  1363
}