diff options
| author | ahrens <none@none> | 2006-11-10 11:24:28 -0800 |
|---|---|---|
| committer | ahrens <none@none> | 2006-11-10 11:24:28 -0800 |
| commit | 432f72fd2958c0d1ecc680b0573d8f65a22de385 (patch) | |
| tree | f4c8463d2524beb551efb0391b8edb7cea5cde2b /usr/src/uts/common/fs/zfs/dnode.c | |
| parent | 8ceba33e02de3517d5be4b514f5702e177ae5900 (diff) | |
| download | illumos-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.c | 21 |
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); } |
