summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/dnode.c
diff options
context:
space:
mode:
authorahrens <none@none>2006-11-10 11:24:28 -0800
committerahrens <none@none>2006-11-10 11:24:28 -0800
commit432f72fd2958c0d1ecc680b0573d8f65a22de385 (patch)
treef4c8463d2524beb551efb0391b8edb7cea5cde2b /usr/src/uts/common/fs/zfs/dnode.c
parent8ceba33e02de3517d5be4b514f5702e177ae5900 (diff)
downloadillumos-joyent-432f72fd2958c0d1ecc680b0573d8f65a22de385.tar.gz
6468748 assertion failure in dnode_sync
6490104 'zfs recv' can be very slow when processing large DRR_FREEOBJECTS record 6490105 assertion failure in dbuf_verify when doing zfs recv 6490829 panic in zfs_hash() while 'zfs recv' a zvol
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dnode.c')
-rw-r--r--usr/src/uts/common/fs/zfs/dnode.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/usr/src/uts/common/fs/zfs/dnode.c b/usr/src/uts/common/fs/zfs/dnode.c
index a2a985eb26..8fd083167b 100644
--- a/usr/src/uts/common/fs/zfs/dnode.c
+++ b/usr/src/uts/common/fs/zfs/dnode.c
@@ -395,6 +395,7 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
{
int i;
+ dmu_buf_impl_t *db = NULL;
ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
@@ -425,17 +426,25 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
/* change blocksize */
rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+ if (blocksize != dn->dn_datablksz &&
+ (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
+ list_head(&dn->dn_dbufs) != NULL)) {
+ db = dbuf_hold(dn, 0, FTAG);
+ dbuf_new_size(db, blocksize, tx);
+ }
dnode_setdblksz(dn, blocksize);
dnode_setdirty(dn, tx);
dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
rw_exit(&dn->dn_struct_rwlock);
+ if (db) {
+ dbuf_rele(db, FTAG);
+ db = NULL;
+ }
/* change type */
dn->dn_type = ot;
if (dn->dn_bonuslen != bonuslen) {
- dmu_buf_impl_t *db = NULL;
-
/* change bonus size */
if (bonuslen == 0)
bonuslen = 1; /* XXX */
@@ -453,7 +462,6 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
db->db.db_size = bonuslen;
mutex_exit(&db->db_mtx);
dbuf_dirty(db, tx);
- dbuf_rele(db, FTAG);
}
/* change bonus size and type */
@@ -465,6 +473,13 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
dn->dn_compress = ZIO_COMPRESS_INHERIT;
ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
+ /*
+ * NB: we have to do the dbuf_rele after we've changed the
+ * dn_bonuslen, for the sake of dbuf_verify().
+ */
+ if (db)
+ dbuf_rele(db, FTAG);
+
dn->dn_allocated_txg = tx->tx_txg;
mutex_exit(&dn->dn_mtx);
}