usr/src/uts/common/fs/zfs/dmu_tx.c
author Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
Tue, 19 May 2009 11:19:21 +0530
changeset 9653 a70048a304d1
parent 9396 f41cf682d0d3
child 9873 8ddc892eca6e
permissions -rw-r--r--
6664765 Unable to remove files when using fat-zap and quota exceeded on ZFS filesystem
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
/*
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
    22
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#include <sys/dmu_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/dbuf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/dmu_objset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/dsl_pool.h>
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    34
#include <sys/zap_impl.h> /* for fzap_default_block_shift */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    38
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
    39
    uint64_t arg1, uint64_t arg2);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    40
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
dmu_tx_t *
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    43
dmu_tx_create_dd(dsl_dir_t *dd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
	dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
	tx->tx_dir = dd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	if (dd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
		tx->tx_pool = dd->dd_pool;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	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
    50
	    offsetof(dmu_tx_hold_t, txh_node));
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    51
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	refcount_create(&tx->tx_space_written);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	refcount_create(&tx->tx_space_freed);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    54
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
dmu_tx_create(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
{
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    61
	dmu_tx_t *tx = dmu_tx_create_dd(os->os->os_dsl_dataset->ds_dir);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
	tx->tx_objset = os;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    63
	tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os->os_dsl_dataset);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
dmu_tx_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
{
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2113
diff changeset
    70
	dmu_tx_t *tx = dmu_tx_create_dd(NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
	tx->tx_pool = dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	tx->tx_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	tx->tx_anyobj = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	return (tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
dmu_tx_is_syncing(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	return (tx->tx_anyobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
dmu_tx_private_ok(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    89
	return (tx->tx_anyobj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
    92
static dmu_tx_hold_t *
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
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
    94
    enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
789
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
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	dnode_t *dn = NULL;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    98
	int err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	if (object != DMU_NEW_OBJECT) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   101
		err = dnode_hold(os->os, object, tx, &dn);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   102
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   103
			tx->tx_err = err;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   104
			return (NULL);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   105
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   107
		if (err == 0 && tx->tx_txg != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
			mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
			 * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
			 * problem, but there's no way for it to happen (for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
			 * now, at least).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			ASSERT(dn->dn_assigned_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			dn->dn_assigned_txg = tx->tx_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   121
	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
   122
	txh->txh_tx = tx;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   123
	txh->txh_dnode = dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   124
#ifdef ZFS_DEBUG
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   125
	txh->txh_type = type;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   126
	txh->txh_arg1 = arg1;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   127
	txh->txh_arg2 = arg2;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   128
#endif
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   129
	list_insert_tail(&tx->tx_holds, txh);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   130
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   131
	return (txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
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
	 * If we're syncing, they can manipulate any object anyhow, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	 * the hold on the dnode_t can cause problems.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	if (!dmu_tx_is_syncing(tx)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   142
		(void) dmu_tx_hold_object_impl(tx, os,
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   143
		    object, THT_NEWOBJECT, 0, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   147
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   148
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
   149
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   150
	int err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   151
	dmu_buf_impl_t *db;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   152
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   153
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   154
	db = dbuf_hold_level(dn, level, blkid, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   155
	rw_exit(&dn->dn_struct_rwlock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   156
	if (db == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   157
		return (EIO);
6245
1a2a7cfb9f26 6429205 each zpool needs to monitor its throughput and throttle heavy writers
maybee
parents: 5765
diff changeset
   158
	err = dbuf_read(db, zio, DB_RF_CANFAIL | DB_RF_NOPREFETCH);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   159
	dbuf_rele(db, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   160
	return (err);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   161
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   162
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   163
static void
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   164
dmu_tx_count_indirects(dmu_tx_hold_t *txh, dmu_buf_impl_t *db,
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   165
    boolean_t freeable, dmu_buf_impl_t **history)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   166
{
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   167
	int i = db->db_level + 1;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   168
	dnode_t *dn = db->db_dnode;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   169
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   170
	if (i >= dn->dn_nlevels)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   171
		return;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   172
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   173
	db = db->db_parent;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   174
	if (db == NULL) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   175
		uint64_t lvls = dn->dn_nlevels - i;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   176
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   177
		txh->txh_space_towrite += lvls << dn->dn_indblkshift;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   178
		return;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   179
	}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   180
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   181
	if (db != history[i]) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   182
		dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   183
		uint64_t space = 1ULL << dn->dn_indblkshift;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   184
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   185
		freeable = (db->db_blkptr && (freeable ||
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   186
		    dsl_dataset_block_freeable(ds, db->db_blkptr->blk_birth)));
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   187
		if (freeable)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   188
			txh->txh_space_tooverwrite += space;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   189
		else
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   190
			txh->txh_space_towrite += space;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   191
		if (db->db_blkptr)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   192
			txh->txh_space_tounref += space;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   193
		history[i] = db;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   194
		dmu_tx_count_indirects(txh, db, freeable, history);
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
}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   197
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   200
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
   201
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   202
	dnode_t *dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   203
	uint64_t start, end, i;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
	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
   205
	int err = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	if (len == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	min_bs = SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	max_bs = SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	min_ibs = DN_MIN_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	max_ibs = DN_MAX_INDBLKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   215
	if (dn) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   216
		dmu_buf_impl_t *last[DN_MAX_LEVELS];
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   217
		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
   218
		int delta;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   219
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   220
		/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   221
		 * 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
   222
		 * 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
   223
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   224
		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
   225
			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
   226
			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
   227
			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
   228
			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
   229
				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
   230
				if (err)
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   231
					goto out;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   232
				delta -= off;
7872
40a9434212f6 6646775 Speed up the dumpifying process for zvols
Tim Haley <Tim.Haley@Sun.COM>
parents: 7754
diff changeset
   233
			}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   234
		} else {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   235
			zio_t *zio = zio_root(dn->dn_objset->os_spa,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   236
			    NULL, NULL, ZIO_FLAG_CANFAIL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   237
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   238
			/* first level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   239
			start = off >> dn->dn_datablkshift;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   240
			if (P2PHASE(off, dn->dn_datablksz) ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   241
			    len < dn->dn_datablksz) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   242
				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
   243
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   244
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   245
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   246
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   247
			/* last level-0 block */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   248
			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
   249
			if (end != start && end <= dn->dn_maxblkid &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   250
			    P2PHASE(off+len, dn->dn_datablksz)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   251
				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
   252
				if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   253
					goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   254
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   255
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   256
			/* 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
   257
			if (nlvls > 1) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   258
				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
   259
				for (i = (start>>shft)+1; i < end>>shft; i++) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   260
					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
   261
					if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   262
						goto out;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   263
				}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   264
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   265
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   266
			err = zio_wait(zio);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   267
			if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   268
				goto out;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   269
			delta = P2NPHASE(off, dn->dn_datablksz);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   270
		}
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   271
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   272
		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
   273
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   274
			 * 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
   275
			 * 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
   276
			 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   277
			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
   278
			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
   279
			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
   280
		} 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
   281
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   282
			 * 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
   283
			 * 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
   284
			 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   285
			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
   286
		}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   287
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   288
		/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   289
		 * 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
   290
		 * 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
   291
		 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   292
		if (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
   293
			bzero(last, sizeof (dmu_buf_impl_t *) * DN_MAX_LEVELS);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   294
		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
   295
			spa_t *spa = txh->txh_tx->tx_pool->dp_spa;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   296
			dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   297
			dmu_buf_impl_t *db;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   298
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   299
			rw_enter(&dn->dn_struct_rwlock, RW_READER);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   300
			db = dbuf_hold_level(dn, 0, start, FTAG);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   301
			rw_exit(&dn->dn_struct_rwlock);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   302
			if (db->db_blkptr && dsl_dataset_block_freeable(ds,
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   303
			    db->db_blkptr->blk_birth)) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   304
				dprintf_bp(db->db_blkptr, "can free old%s", "");
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   305
				txh->txh_space_tooverwrite += dn->dn_datablksz;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   306
				txh->txh_space_tounref += dn->dn_datablksz;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   307
				dmu_tx_count_indirects(txh, db, TRUE, last);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   308
			} else {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   309
				txh->txh_space_towrite += dn->dn_datablksz;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   310
				if (db->db_blkptr)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   311
					txh->txh_space_tounref +=
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   312
					    bp_get_dasize(spa, db->db_blkptr);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   313
				dmu_tx_count_indirects(txh, db, FALSE, last);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   314
			}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   315
			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
   316
			if (++start > end) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   317
				/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   318
				 * 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
   319
				 * 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
   320
				 */
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   321
				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
   322
				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
   323
				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
   324
				    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
   325
					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
   326
				goto out;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   327
			}
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   328
			off += delta;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   329
			if (len >= delta)
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   330
				len -= delta;
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   331
			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
   332
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	 * 'end' is the last thing we will access, not one past.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	 * This way we won't overflow when accessing the last byte.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	start = P2ALIGN(off, 1ULL << max_bs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   341
	txh->txh_space_towrite += end - start + 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	start >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	end >>= min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	epbs = min_ibs - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	 * The object contains at most 2^(64 - min_bs) blocks,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
	 * and each indirect level maps 2^epbs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
		start >>= epbs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
		end >>= epbs;
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   355
		ASSERT3U(end, >=, start);
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   356
		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
   357
		if (start != 0) {
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   358
			/*
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   359
			 * 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
   360
			 * 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
   361
			 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   362
			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
   363
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
8768
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   366
out:
dfecfdbb27ed 6775697 oracle crashes when overwriting after hitting quota on zfs
Mark Maybee <Mark.Maybee@Sun.COM>
parents: 7872
diff changeset
   367
	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
   368
	    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
   369
		err = EFBIG;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   371
	if (err)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   372
		txh->txh_tx->tx_err = err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   376
dmu_tx_count_dnode(dmu_tx_hold_t *txh)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   378
	dnode_t *dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   379
	dnode_t *mdn = txh->txh_tx->tx_objset->os->os_meta_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   380
	uint64_t space = mdn->dn_datablksz +
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   381
	    ((mdn->dn_nlevels-1) << mdn->dn_indblkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	if (dn && dn->dn_dbuf->db_blkptr &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	    dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   385
	    dn->dn_dbuf->db_blkptr->blk_birth)) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   386
		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
   387
		txh->txh_space_tounref += space;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   388
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   389
		txh->txh_space_towrite += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   390
		if (dn && dn->dn_dbuf->db_blkptr)
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   391
			txh->txh_space_tounref += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
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
   397
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   398
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   399
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	ASSERT(tx->tx_txg == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   401
	ASSERT(len < DMU_MAX_ACCESS);
1819
570a79e4d798 6407842 zfs panic when closing a file
maybee
parents: 1793
diff changeset
   402
	ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   404
	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
   405
	    object, THT_WRITE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   406
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   407
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   408
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   409
	dmu_tx_count_write(txh, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   410
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
static void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   414
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
   415
{
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   416
	uint64_t blkid, nblks, lastblk;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   417
	uint64_t space = 0, unref = 0, skipped = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   418
	dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
	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
   420
	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
   421
	int epbs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   423
	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
   424
		return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   425
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   426
	/*
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   427
	 * 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
   428
	 * 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
   429
	 * sync out the changes after we check for being dirty.
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   430
	 * Also, dbuf_hold_level() wants us to have the struct_rwlock.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
	rw_enter(&dn->dn_struct_rwlock, RW_READER);
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   433
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   434
	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
   435
		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
   436
			blkid = 0;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   437
			nblks = 1;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   438
		} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   439
			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
   440
			return;
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   441
		}
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   442
	} else {
2e2377ccbf85 6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr
ahrens
parents: 1544
diff changeset
   443
		blkid = off >> dn->dn_datablkshift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   444
		nblks = (len + dn->dn_datablksz - 1) >> dn->dn_datablkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   446
		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
   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
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   450
		if (blkid + nblks > dn->dn_maxblkid)
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   451
			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
   452
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   453
	}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   454
	if (dn->dn_nlevels == 1) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
		for (i = 0; i < nblks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
			blkptr_t *bp = dn->dn_phys->dn_blkptr;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   458
			ASSERT3U(blkid + i, <, dn->dn_nblkptr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
			bp += blkid + i;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   460
			if (dsl_dataset_block_freeable(ds, bp->blk_birth)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
				dprintf_bp(bp, "can free old%s", "");
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1819
diff changeset
   462
				space += bp_get_dasize(spa, bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
			}
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   464
			unref += BP_GET_ASIZE(bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   466
		nblks = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   469
	/*
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   470
	 * 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
   471
	 * 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
   472
	 */
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   473
	{
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   474
		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
   475
		int level = (dn->dn_nlevels > 1) ? 2 : 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   476
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   477
		while (level++ < DN_MAX_LEVELS) {
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   478
			txh->txh_memory_tohold += blkcnt << dn->dn_indblkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   479
			blkcnt = 1 + (blkcnt >> epbs);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   480
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   481
		ASSERT(blkcnt <= dn->dn_nblkptr);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   482
	}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   483
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   484
	lastblk = blkid + nblks - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	while (nblks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
		dmu_buf_impl_t *dbuf;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   487
		uint64_t ibyte, new_blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   488
		int epb = 1 << epbs;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   489
		int err, i, blkoff, tochk;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   490
		blkptr_t *bp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   492
		ibyte = blkid << dn->dn_datablkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   493
		err = dnode_next_offset(dn,
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   494
		    DNODE_FIND_HAVELOCK, &ibyte, 2, 1, 0);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   495
		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
   496
		if (err == ESRCH) {
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   497
			skipped += (lastblk >> epbs) - (blkid >> epbs) + 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   498
			break;
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   499
		}
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   500
		if (err) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   501
			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
   502
			break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
		}
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   504
		if (new_blkid > lastblk) {
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
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   509
		if (new_blkid > blkid) {
7080
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   510
			ASSERT((new_blkid >> epbs) > (blkid >> epbs));
13a30a37ddc0 6724533 assertion failed: file: ../../common/fs/zfs/dmu_tx.c, line: 983
maybee
parents: 7016
diff changeset
   511
			skipped += (new_blkid >> epbs) - (blkid >> epbs) - 1;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   512
			nblks -= new_blkid - blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   513
			blkid = new_blkid;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   514
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   515
		blkoff = P2PHASE(blkid, epb);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   516
		tochk = MIN(epb - blkoff, nblks);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   517
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   518
		dbuf = dbuf_hold_level(dn, 1, blkid >> epbs, FTAG);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   519
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   520
		txh->txh_memory_tohold += dbuf->db.db_size;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   521
		if (txh->txh_memory_tohold > DMU_MAX_ACCESS) {
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   522
			txh->txh_tx->tx_err = E2BIG;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   523
			dbuf_rele(dbuf, FTAG);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   524
			break;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   525
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   526
		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
   527
		if (err != 0) {
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   528
			txh->txh_tx->tx_err = err;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   529
			dbuf_rele(dbuf, FTAG);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   530
			break;
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
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   533
		bp = dbuf->db.db_data;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   534
		bp += blkoff;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   535
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   536
		for (i = 0; i < tochk; i++) {
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   537
			if (dsl_dataset_block_freeable(ds, bp[i].blk_birth)) {
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   538
				dprintf_bp(&bp[i], "can free old%s", "");
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   539
				space += bp_get_dasize(spa, &bp[i]);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   540
			}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   541
			unref += BP_GET_ASIZE(bp);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   542
		}
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   543
		dbuf_rele(dbuf, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
		blkid += tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
		nblks -= tochk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	rw_exit(&dn->dn_struct_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   550
	/* 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
   551
	if (skipped > 0) {
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   552
		txh->txh_fudge += skipped << dn->dn_indblkshift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   553
		skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   554
		txh->txh_memory_tohold += skipped << dn->dn_indblkshift;
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   555
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   556
	txh->txh_space_tofree += space;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   557
	txh->txh_space_tounref += unref;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   560
void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   561
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
   562
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   563
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   564
	dnode_t *dn;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   565
	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
   566
	int err, shift;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   567
	zio_t *zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   569
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   570
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   571
	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
   572
	    object, THT_FREE, off, len);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   573
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   574
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   575
	dn = txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   576
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	/* first block */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   578
	if (off != 0)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   579
		dmu_tx_count_write(txh, off, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	/* last block */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	if (len != DMU_OBJECT_END)
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   582
		dmu_tx_count_write(txh, off+len, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
	if (len == DMU_OBJECT_END)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   589
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   590
	 * For i/o error checking, read the first and last level-0
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   591
	 * 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
   592
	 * have already taken care of the level-0 blocks.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   593
	 */
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   594
	if (dn->dn_nlevels > 1) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   595
		shift = dn->dn_datablkshift + dn->dn_indblkshift -
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   596
		    SPA_BLKPTRSHIFT;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   597
		start = off >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   598
		end = dn->dn_datablkshift ? ((off+len) >> shift) : 0;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   599
1793
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   600
		zio = zio_root(tx->tx_pool->dp_spa,
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   601
		    NULL, NULL, ZIO_FLAG_CANFAIL);
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   602
		for (i = start; i <= end; i++) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   603
			uint64_t ibyte = i << shift;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   604
			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
   605
			i = ibyte >> shift;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   606
			if (err == ESRCH)
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   607
				break;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   608
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   609
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   610
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   611
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   612
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   613
			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
   614
			if (err) {
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   615
				tx->tx_err = err;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   616
				return;
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   617
			}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   618
		}
d371fba21a3e 6407444 unhandled i/o error from dnode_next_offset_level()
ahrens
parents: 1758
diff changeset
   619
		err = zio_wait(zio);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   620
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   621
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   622
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   623
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   624
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   625
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   626
	dmu_tx_count_dnode(txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   627
	dmu_tx_count_free(txh, off, len);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
void
9396
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8890
diff changeset
   631
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
   632
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   633
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   634
	dnode_t *dn;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   635
	uint64_t nblocks;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   636
	int epbs, err;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   637
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   640
	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
   641
	    object, THT_ZAP, add, (uintptr_t)name);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   642
	if (txh == NULL)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   643
		return;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   644
	dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   646
	dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	if (dn == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   650
		 * We will be able to fit a new object's entries into one leaf
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
		 * block.  So there will be at most 2 blocks total,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
		 * including the header block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
		 */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   654
		dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
	ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   660
	if (dn->dn_maxblkid == 0 && !add) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
		 * 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
   663
		 * and we are not adding anything, the accounting is simple.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   665
		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   666
		if (err) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   667
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   668
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   669
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   670
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   671
		/*
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   672
		 * 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
   673
		 * 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
   674
		 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   676
		    dn->dn_phys->dn_blkptr[0].blk_birth)) {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   677
			txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   678
		} else {
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3025
diff changeset
   679
			txh->txh_space_towrite += SPA_MAXBLOCKSIZE;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   680
		}
8890
8c2bd5f17bf2 6798878 Unable to remove a file over NFS after hitting refquota limit
Chris Kirby <chris.kirby@sun.com>
parents: 8768
diff changeset
   681
		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
   682
			txh->txh_space_tounref += SPA_MAXBLOCKSIZE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   686
	if (dn->dn_maxblkid > 0 && name) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   687
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   688
		 * access the name in this fat-zap so that we'll check
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   689
		 * for i/o errors to the leaf blocks, etc.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   690
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   691
		err = zap_lookup(&dn->dn_objset->os, dn->dn_object, name,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   692
		    8, 0, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   693
		if (err == EIO) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   694
			tx->tx_err = err;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   695
			return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   696
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   697
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   698
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
   699
	err = zap_count_write(&dn->dn_objset->os, dn->dn_object, name, add,
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
   700
	    &txh->txh_space_towrite, &txh->txh_space_tooverwrite,
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
   701
	    txh->txh_dnode->dn_datablkshift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
	 * If the modified blocks are scattered to the four winds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	 * we'll have to modify an indirect twig for each.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
	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
   709
		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
   710
			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
   711
		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
   712
			txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   718
	dmu_tx_hold_t *txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   719
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   722
	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
   723
	    object, THT_BONUS, 0, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   724
	if (txh)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   725
		dmu_tx_count_dnode(txh);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   731
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   734
	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
   735
	    DMU_NEW_OBJECT, THT_SPACE, space, 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   736
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   737
	txh->txh_space_towrite += space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   743
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
	int holds = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
	 * By asserting that the tx is assigned, we're counting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
	 * number of dn_tx_holds, which is the same as the number of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
	 * dn_tx_holds could be 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
	/* if (tx->tx_anyobj == TRUE) */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
		/* return (0); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   757
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   758
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   759
		if (txh->txh_dnode && txh->txh_dnode->dn_object == object)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
			holds++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	return (holds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   766
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   770
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
	int match_object = FALSE, match_offset = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
	dnode_t *dn = db->db_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset->os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
	ASSERT3U(dn->dn_object, ==, db->db.db_object);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	if (tx->tx_anyobj)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
	/* XXX No checking on the meta dnode for now */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   782
	if (db->db.db_object == DMU_META_DNODE_OBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   785
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   786
	    txh = list_next(&tx->tx_holds, txh)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		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
   788
		if (txh->txh_dnode == dn && txh->txh_type != THT_NEWOBJECT)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
			match_object = TRUE;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   790
		if (txh->txh_dnode == NULL || txh->txh_dnode == dn) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
			int datablkshift = dn->dn_datablkshift ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
			int shift = datablkshift + epbs * db->db_level;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
			uint64_t beginblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   796
			    (txh->txh_arg1 >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
			uint64_t endblk = shift >= 64 ? 0 :
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   798
			    ((txh->txh_arg1 + txh->txh_arg2 - 1) >> shift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
			uint64_t blkid = db->db_blkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   801
			/* XXX txh_arg2 better not be zero... */
789
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
			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
   804
			    txh->txh_type, beginblk, endblk);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   806
			switch (txh->txh_type) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
			case THT_WRITE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
				if (blkid >= beginblk && blkid <= endblk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
				 * We will let this hold work for the bonus
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
				 * buffer so that we don't need to hold it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
				 * when creating a new object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
				 * They might have to increase nlevels,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
				 * thus dirtying the new TLIBs.  Or the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
				 * might have to change the block size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
				 * thus dirying the new lvl=0 blk=0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
				if (blkid == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
			case THT_FREE:
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   827
				/*
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   828
				 * We will dirty all the level 1 blocks in
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   829
				 * the free range and perhaps the first and
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   830
				 * last level 0 block.
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   831
				 */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   832
				if (blkid >= beginblk && (blkid <= endblk ||
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   833
				    txh->txh_arg2 == DMU_OBJECT_END))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
			case THT_BONUS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
				if (blkid == DB_BONUS_BLKID)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
					match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
			case THT_ZAP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
				match_offset = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
			case THT_NEWOBJECT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
				match_object = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
			default:
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   847
				ASSERT(!"bad txh_type");
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
		if (match_object && match_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
	    (u_longlong_t)db->db.db_object, db->db_level,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
	    (u_longlong_t)db->db_blkid);
873
adefbfa5f42d 6347448 non ZFS_DEBUG kernels shouldn't call empty verify functions
ek110237
parents: 789
diff changeset
   856
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
static int
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   860
dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   862
	dmu_tx_hold_t *txh;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   863
	spa_t *spa = tx->tx_pool->dp_spa;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   864
	uint64_t memory, asize, fsize, usize;
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   865
	uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   867
	ASSERT3U(tx->tx_txg, ==, 0);
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   868
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   869
	if (tx->tx_err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   870
		return (tx->tx_err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
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
   872
	if (spa_suspended(spa)) {
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   873
		/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   874
		 * If the user has indicated a blocking failure mode
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   875
		 * then return ERESTART which will block in dmu_tx_wait().
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   876
		 * Otherwise, return EIO so that an error can get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   877
		 * propagated back to the VOP calls.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   878
		 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   879
		 * Note that we always honor the txg_how flag regardless
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   880
		 * of the failuremode setting.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   881
		 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   882
		if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE &&
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   883
		    txg_how != TXG_WAIT)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   884
			return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   885
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   886
		return (ERESTART);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   887
	}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
   888
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   889
	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
   890
	tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   891
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   892
	/*
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   893
	 * 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
   894
	 * before processing the dnode holds, due to the
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   895
	 * dmu_tx_unassign() logic.
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   896
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   897
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   898
	towrite = tofree = tooverwrite = tounref = tohold = fudge = 0;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   899
	for (txh = list_head(&tx->tx_holds); txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   900
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   901
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
		if (dn != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
			mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   904
			if (dn->dn_assigned_txg == tx->tx_txg - 1) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   905
				mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   906
				tx->tx_needassign_txh = txh;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   907
				return (ERESTART);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
			}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   909
			if (dn->dn_assigned_txg == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
				dn->dn_assigned_txg = tx->tx_txg;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   911
			ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
			(void) refcount_add(&dn->dn_tx_holds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
			mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   915
		towrite += txh->txh_space_towrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   916
		tofree += txh->txh_space_tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   917
		tooverwrite += txh->txh_space_tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   918
		tounref += txh->txh_space_tounref;
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   919
		tohold += txh->txh_memory_tohold;
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   920
		fudge += txh->txh_fudge;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   921
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   922
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   923
	/*
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   924
	 * 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
   925
	 * the dmu_tx_unassign() logic will work properly
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   926
	 */
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   927
	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
   928
		return (ERESTART);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   929
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   930
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   931
	 * If a snapshot has been taken since we made our estimates,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   932
	 * assume that we won't be able to free or overwrite anything.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   933
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   934
	if (tx->tx_objset &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   935
	    dsl_dataset_prev_snap_txg(tx->tx_objset->os->os_dsl_dataset) >
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   936
	    tx->tx_lastsnap_txg) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   937
		towrite += tooverwrite;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   938
		tooverwrite = tofree = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   941
	/* needed allocation: worst-case estimate of write space */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   942
	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
   943
	/* freed space estimate: worst-case overwrite + free estimate */
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   944
	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
   945
	/* convert unrefd space to worst-case estimate */
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   946
	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
   947
	/* calculate memory footprint estimate */
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   948
	memory = towrite + tooverwrite + tohold;
2113
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
#ifdef ZFS_DEBUG
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   951
	/*
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   952
	 * 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
   953
	 * 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
   954
	 * 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
   955
	 */
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   956
	tx->tx_space_towrite = asize +
7016
8b85f8b0129c 6721941 dmu_tx_count_free() does not account for nlevels increasing
maybee
parents: 6992
diff changeset
   957
	    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
   958
	tx->tx_space_tofree = tofree;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   959
	tx->tx_space_tooverwrite = tooverwrite;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5329
diff changeset
   960
	tx->tx_space_tounref = tounref;
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   961
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
	if (tx->tx_dir && asize != 0) {
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6245
diff changeset
   964
		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
   965
		    asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   966
		if (err)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   973
static void
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   974
dmu_tx_unassign(dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   976
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   978
	if (tx->tx_txg == 0)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   979
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   983
	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
   984
	    txh = list_next(&tx->tx_holds, txh)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   985
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
		mutex_enter(&dn->dn_mtx);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
   990
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
	txg_rele_to_sync(&tx->tx_txgh);
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
	tx->tx_lasttried_txg = tx->tx_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
	tx->tx_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
 * Assign tx to a transaction group.  txg_how can be one of:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
 * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
 *	a new one.  This should be used when you're not holding locks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
 *	If will only fail if we're truly out of space (or over quota).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
 * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
 *	blocking, returns immediately with ERESTART.  This should be used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
 *	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
  1015
 *	should drop locks, do a dmu_tx_wait(tx), and try again.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
 * (3)	A specific txg.  Use this if you need to ensure that multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
 *	transactions all sync in the same txg.  Like TXG_NOWAIT, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
 *	returns ERESTART if it can't assign you into the requested txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
	ASSERT(txg_how != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1030
	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
  1031
		dmu_tx_unassign(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
		if (err != ERESTART || txg_how != TXG_WAIT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
			return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1036
		dmu_tx_wait(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
	txg_rele_to_quiesce(&tx->tx_txgh);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
void
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1045
dmu_tx_wait(dmu_tx_t *tx)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1046
{
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1047
	spa_t *spa = tx->tx_pool->dp_spa;
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1048
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1049
	ASSERT(tx->tx_txg == 0);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1050
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1051
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1052
	 * It's possible that the pool has become active after this thread
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1053
	 * 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
  1054
	 * tx_lasttried_txg would not have been assigned.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1055
	 */
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
  1056
	if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) {
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1057
		txg_wait_synced(tx->tx_pool, spa_last_synced_txg(spa) + 1);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3245
diff changeset
  1058
	} else if (tx->tx_needassign_txh) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1059
		dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1060
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1061
		mutex_enter(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1062
		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
  1063
			cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1064
		mutex_exit(&dn->dn_mtx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1065
		tx->tx_needassign_txh = NULL;
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1066
	} else {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1067
		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
  1068
	}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1069
}
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1070
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1071
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1074
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
	if (tx->tx_dir == NULL || delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1078
	if (delta > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
		    tx->tx_space_towrite);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
	}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1085
#endif
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1088
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
dmu_tx_commit(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1091
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1094
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1095
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1096
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1098
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1099
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
		if (dn == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
		mutex_enter(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
			dn->dn_assigned_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
			cv_broadcast(&dn->dn_notxholds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
		mutex_exit(&dn->dn_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
		dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1113
	if (tx->tx_tempreserve_cookie)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	if (tx->tx_anyobj == FALSE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
		txg_rele_to_sync(&tx->tx_txgh);
5765
86c482ef4a34 6646545 Condvars in tx_cpu aren't being initialized/destroyed
ek110237
parents: 5378
diff changeset
  1118
	list_destroy(&tx->tx_holds);
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1119
#ifdef ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
dmu_tx_abort(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
{
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1134
	dmu_tx_hold_t *txh;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1136
	ASSERT(tx->tx_txg == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1138
	while (txh = list_head(&tx->tx_holds)) {
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1139
		dnode_t *dn = txh->txh_dnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1141
		list_remove(&tx->tx_holds, txh);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2082
diff changeset
  1142
		kmem_free(txh, sizeof (dmu_tx_hold_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
		if (dn != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
			dnode_rele(dn, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
	}
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
	refcount_destroy_many(&tx->tx_space_written,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
	    refcount_count(&tx->tx_space_written));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	refcount_destroy_many(&tx->tx_space_freed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	    refcount_count(&tx->tx_space_freed));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	kmem_free(tx, sizeof (dmu_tx_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
dmu_tx_get_txg(dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
	ASSERT(tx->tx_txg != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
	return (tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
}