3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/zfs_context.h>
26 #include <sys/dbuf.h>
27 #include <sys/dnode.h>
28 #include <sys/dmu.h>
29 #include <sys/dmu_impl.h>
30 #include <sys/dmu_tx.h>
31 #include <sys/dmu_objset.h>
32 #include <sys/dsl_dir.h>
33 #include <sys/dsl_dataset.h>
34 #include <sys/spa.h>
35 #include <sys/zio.h>
36 #include <sys/dmu_zfetch.h>
37
38 static int free_range_compar(const void *node1, const void *node2);
39
40 static kmem_cache_t *dnode_cache;
41 /*
42 * Define DNODE_STATS to turn on statistic gathering. By default, it is only
176 }
177
178 void
179 dnode_fini(void)
180 {
181 kmem_cache_destroy(dnode_cache);
182 dnode_cache = NULL;
183 }
184
185
186 #ifdef ZFS_DEBUG
187 void
188 dnode_verify(dnode_t *dn)
189 {
190 int drop_struct_lock = FALSE;
191
192 ASSERT(dn->dn_phys);
193 ASSERT(dn->dn_objset);
194 ASSERT(dn->dn_handle->dnh_dnode == dn);
195
196 ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES);
197
198 if (!(zfs_flags & ZFS_DEBUG_DNODE_VERIFY))
199 return;
200
201 if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
202 rw_enter(&dn->dn_struct_rwlock, RW_READER);
203 drop_struct_lock = TRUE;
204 }
205 if (dn->dn_phys->dn_type != DMU_OT_NONE || dn->dn_allocated_txg != 0) {
206 int i;
207 ASSERT3U(dn->dn_indblkshift, >=, 0);
208 ASSERT3U(dn->dn_indblkshift, <=, SPA_MAXBLOCKSHIFT);
209 if (dn->dn_datablkshift) {
210 ASSERT3U(dn->dn_datablkshift, >=, SPA_MINBLOCKSHIFT);
211 ASSERT3U(dn->dn_datablkshift, <=, SPA_MAXBLOCKSHIFT);
212 ASSERT3U(1<<dn->dn_datablkshift, ==, dn->dn_datablksz);
213 }
214 ASSERT3U(dn->dn_nlevels, <=, 30);
215 ASSERT3U(dn->dn_type, <=, DMU_OT_NUMTYPES);
216 ASSERT3U(dn->dn_nblkptr, >=, 1);
217 ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
218 ASSERT3U(dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
219 ASSERT3U(dn->dn_datablksz, ==,
220 dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
221 ASSERT3U(ISP2(dn->dn_datablksz), ==, dn->dn_datablkshift != 0);
222 ASSERT3U((dn->dn_nblkptr - 1) * sizeof (blkptr_t) +
223 dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
224 for (i = 0; i < TXG_SIZE; i++) {
225 ASSERT3U(dn->dn_next_nlevels[i], <=, dn->dn_nlevels);
226 }
227 }
228 if (dn->dn_phys->dn_type != DMU_OT_NONE)
229 ASSERT3U(dn->dn_phys->dn_nlevels, <=, dn->dn_nlevels);
230 ASSERT(DMU_OBJECT_IS_SPECIAL(dn->dn_object) || dn->dn_dbuf != NULL);
231 if (dn->dn_dbuf != NULL) {
232 ASSERT3P(dn->dn_phys, ==,
233 (dnode_phys_t *)dn->dn_dbuf->db.db_data +
234 (dn->dn_object % (dn->dn_dbuf->db.db_size >> DNODE_SHIFT)));
235 }
261 ASSERT(dnp->dn_indblkshift <= SPA_MAXBLOCKSHIFT);
262 ASSERT(dnp->dn_nblkptr <= DN_MAX_NBLKPTR);
263 for (i = 0; i < dnp->dn_nblkptr * sizeof (blkptr_t)/8; i++)
264 buf64[i] = BSWAP_64(buf64[i]);
265
266 /*
267 * OK to check dn_bonuslen for zero, because it won't matter if
268 * we have the wrong byte order. This is necessary because the
269 * dnode dnode is smaller than a regular dnode.
270 */
271 if (dnp->dn_bonuslen != 0) {
272 /*
273 * Note that the bonus length calculated here may be
274 * longer than the actual bonus buffer. This is because
275 * we always put the bonus buffer after the last block
276 * pointer (instead of packing it against the end of the
277 * dnode buffer).
278 */
279 int off = (dnp->dn_nblkptr-1) * sizeof (blkptr_t);
280 size_t len = DN_MAX_BONUSLEN - off;
281 ASSERT3U(dnp->dn_bonustype, <, DMU_OT_NUMTYPES);
282 dmu_ot[dnp->dn_bonustype].ot_byteswap(dnp->dn_bonus + off, len);
283 }
284
285 /* Swap SPILL block if we have one */
286 if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
287 byteswap_uint64_array(&dnp->dn_spill, sizeof (blkptr_t));
288
289 }
290
291 void
292 dnode_buf_byteswap(void *vbuf, size_t size)
293 {
294 dnode_phys_t *buf = vbuf;
295 int i;
296
297 ASSERT3U(sizeof (dnode_phys_t), ==, (1<<DNODE_SHIFT));
298 ASSERT((size & (sizeof (dnode_phys_t)-1)) == 0);
299
300 size >>= DNODE_SHIFT;
301 for (i = 0; i < size; i++) {
302 dnode_byteswap(buf);
390 dnode_setdblksz(dn, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
391 } else {
392 dn->dn_datablksz = 0;
393 dn->dn_datablkszsec = 0;
394 dn->dn_datablkshift = 0;
395 }
396 dn->dn_indblkshift = dnp->dn_indblkshift;
397 dn->dn_nlevels = dnp->dn_nlevels;
398 dn->dn_type = dnp->dn_type;
399 dn->dn_nblkptr = dnp->dn_nblkptr;
400 dn->dn_checksum = dnp->dn_checksum;
401 dn->dn_compress = dnp->dn_compress;
402 dn->dn_bonustype = dnp->dn_bonustype;
403 dn->dn_bonuslen = dnp->dn_bonuslen;
404 dn->dn_maxblkid = dnp->dn_maxblkid;
405 dn->dn_have_spill = ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0);
406 dn->dn_id_flags = 0;
407
408 dmu_zfetch_init(&dn->dn_zfetch, dn);
409
410 ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES);
411
412 mutex_enter(&os->os_lock);
413 list_insert_head(&os->os_dnodes, dn);
414 membar_producer();
415 /*
416 * Everything else must be valid before assigning dn_objset makes the
417 * dnode eligible for dnode_move().
418 */
419 dn->dn_objset = os;
420 mutex_exit(&os->os_lock);
421
422 arc_space_consume(sizeof (dnode_t), ARC_SPACE_OTHER);
423 return (dn);
424 }
425
426 /*
427 * Caller must be holding the dnode handle, which is released upon return.
428 */
429 static void
430 dnode_destroy(dnode_t *dn)
479
480 if (blocksize == 0)
481 blocksize = 1 << zfs_default_bs;
482 else if (blocksize > SPA_MAXBLOCKSIZE)
483 blocksize = SPA_MAXBLOCKSIZE;
484 else
485 blocksize = P2ROUNDUP(blocksize, SPA_MINBLOCKSIZE);
486
487 if (ibs == 0)
488 ibs = zfs_default_ibs;
489
490 ibs = MIN(MAX(ibs, DN_MIN_INDBLKSHIFT), DN_MAX_INDBLKSHIFT);
491
492 dprintf("os=%p obj=%llu txg=%llu blocksize=%d ibs=%d\n", dn->dn_objset,
493 dn->dn_object, tx->tx_txg, blocksize, ibs);
494
495 ASSERT(dn->dn_type == DMU_OT_NONE);
496 ASSERT(bcmp(dn->dn_phys, &dnode_phys_zero, sizeof (dnode_phys_t)) == 0);
497 ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE);
498 ASSERT(ot != DMU_OT_NONE);
499 ASSERT3U(ot, <, DMU_OT_NUMTYPES);
500 ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
501 (bonustype == DMU_OT_SA && bonuslen == 0) ||
502 (bonustype != DMU_OT_NONE && bonuslen != 0));
503 ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
504 ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
505 ASSERT(dn->dn_type == DMU_OT_NONE);
506 ASSERT3U(dn->dn_maxblkid, ==, 0);
507 ASSERT3U(dn->dn_allocated_txg, ==, 0);
508 ASSERT3U(dn->dn_assigned_txg, ==, 0);
509 ASSERT(refcount_is_zero(&dn->dn_tx_holds));
510 ASSERT3U(refcount_count(&dn->dn_holds), <=, 1);
511 ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
512
513 for (i = 0; i < TXG_SIZE; i++) {
514 ASSERT3U(dn->dn_next_nblkptr[i], ==, 0);
515 ASSERT3U(dn->dn_next_nlevels[i], ==, 0);
516 ASSERT3U(dn->dn_next_indblkshift[i], ==, 0);
517 ASSERT3U(dn->dn_next_bonuslen[i], ==, 0);
518 ASSERT3U(dn->dn_next_bonustype[i], ==, 0);
519 ASSERT3U(dn->dn_rm_spillblk[i], ==, 0);
520 ASSERT3U(dn->dn_next_blksz[i], ==, 0);
521 ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
522 ASSERT3P(list_head(&dn->dn_dirty_records[i]), ==, NULL);
523 ASSERT3U(avl_numnodes(&dn->dn_ranges[i]), ==, 0);
551 dn->dn_next_indblkshift[tx->tx_txg & TXG_MASK] = ibs;
552 dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = dn->dn_bonuslen;
553 dn->dn_next_bonustype[tx->tx_txg & TXG_MASK] = dn->dn_bonustype;
554 dn->dn_next_blksz[tx->tx_txg & TXG_MASK] = dn->dn_datablksz;
555 }
556
557 void
558 dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
559 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
560 {
561 int nblkptr;
562
563 ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
564 ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
565 ASSERT3U(blocksize % SPA_MINBLOCKSIZE, ==, 0);
566 ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx));
567 ASSERT(tx->tx_txg != 0);
568 ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
569 (bonustype != DMU_OT_NONE && bonuslen != 0) ||
570 (bonustype == DMU_OT_SA && bonuslen == 0));
571 ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
572 ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
573
574 /* clean up any unreferenced dbufs */
575 dnode_evict_dbufs(dn);
576
577 dn->dn_id_flags = 0;
578
579 rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
580 dnode_setdirty(dn, tx);
581 if (dn->dn_datablksz != blocksize) {
582 /* change blocksize */
583 ASSERT(dn->dn_maxblkid == 0 &&
584 (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
585 dnode_block_freed(dn, 0)));
586 dnode_setdblksz(dn, blocksize);
587 dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
588 }
589 if (dn->dn_bonuslen != bonuslen)
590 dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
591
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012 by Delphix. All rights reserved.
24 */
25
26 #include <sys/zfs_context.h>
27 #include <sys/dbuf.h>
28 #include <sys/dnode.h>
29 #include <sys/dmu.h>
30 #include <sys/dmu_impl.h>
31 #include <sys/dmu_tx.h>
32 #include <sys/dmu_objset.h>
33 #include <sys/dsl_dir.h>
34 #include <sys/dsl_dataset.h>
35 #include <sys/spa.h>
36 #include <sys/zio.h>
37 #include <sys/dmu_zfetch.h>
38
39 static int free_range_compar(const void *node1, const void *node2);
40
41 static kmem_cache_t *dnode_cache;
42 /*
43 * Define DNODE_STATS to turn on statistic gathering. By default, it is only
177 }
178
179 void
180 dnode_fini(void)
181 {
182 kmem_cache_destroy(dnode_cache);
183 dnode_cache = NULL;
184 }
185
186
187 #ifdef ZFS_DEBUG
188 void
189 dnode_verify(dnode_t *dn)
190 {
191 int drop_struct_lock = FALSE;
192
193 ASSERT(dn->dn_phys);
194 ASSERT(dn->dn_objset);
195 ASSERT(dn->dn_handle->dnh_dnode == dn);
196
197 ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
198
199 if (!(zfs_flags & ZFS_DEBUG_DNODE_VERIFY))
200 return;
201
202 if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
203 rw_enter(&dn->dn_struct_rwlock, RW_READER);
204 drop_struct_lock = TRUE;
205 }
206 if (dn->dn_phys->dn_type != DMU_OT_NONE || dn->dn_allocated_txg != 0) {
207 int i;
208 ASSERT3U(dn->dn_indblkshift, >=, 0);
209 ASSERT3U(dn->dn_indblkshift, <=, SPA_MAXBLOCKSHIFT);
210 if (dn->dn_datablkshift) {
211 ASSERT3U(dn->dn_datablkshift, >=, SPA_MINBLOCKSHIFT);
212 ASSERT3U(dn->dn_datablkshift, <=, SPA_MAXBLOCKSHIFT);
213 ASSERT3U(1<<dn->dn_datablkshift, ==, dn->dn_datablksz);
214 }
215 ASSERT3U(dn->dn_nlevels, <=, 30);
216 ASSERT(DMU_OT_IS_VALID(dn->dn_type));
217 ASSERT3U(dn->dn_nblkptr, >=, 1);
218 ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
219 ASSERT3U(dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
220 ASSERT3U(dn->dn_datablksz, ==,
221 dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
222 ASSERT3U(ISP2(dn->dn_datablksz), ==, dn->dn_datablkshift != 0);
223 ASSERT3U((dn->dn_nblkptr - 1) * sizeof (blkptr_t) +
224 dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
225 for (i = 0; i < TXG_SIZE; i++) {
226 ASSERT3U(dn->dn_next_nlevels[i], <=, dn->dn_nlevels);
227 }
228 }
229 if (dn->dn_phys->dn_type != DMU_OT_NONE)
230 ASSERT3U(dn->dn_phys->dn_nlevels, <=, dn->dn_nlevels);
231 ASSERT(DMU_OBJECT_IS_SPECIAL(dn->dn_object) || dn->dn_dbuf != NULL);
232 if (dn->dn_dbuf != NULL) {
233 ASSERT3P(dn->dn_phys, ==,
234 (dnode_phys_t *)dn->dn_dbuf->db.db_data +
235 (dn->dn_object % (dn->dn_dbuf->db.db_size >> DNODE_SHIFT)));
236 }
262 ASSERT(dnp->dn_indblkshift <= SPA_MAXBLOCKSHIFT);
263 ASSERT(dnp->dn_nblkptr <= DN_MAX_NBLKPTR);
264 for (i = 0; i < dnp->dn_nblkptr * sizeof (blkptr_t)/8; i++)
265 buf64[i] = BSWAP_64(buf64[i]);
266
267 /*
268 * OK to check dn_bonuslen for zero, because it won't matter if
269 * we have the wrong byte order. This is necessary because the
270 * dnode dnode is smaller than a regular dnode.
271 */
272 if (dnp->dn_bonuslen != 0) {
273 /*
274 * Note that the bonus length calculated here may be
275 * longer than the actual bonus buffer. This is because
276 * we always put the bonus buffer after the last block
277 * pointer (instead of packing it against the end of the
278 * dnode buffer).
279 */
280 int off = (dnp->dn_nblkptr-1) * sizeof (blkptr_t);
281 size_t len = DN_MAX_BONUSLEN - off;
282 ASSERT(DMU_OT_IS_VALID(dnp->dn_bonustype));
283 dmu_object_byteswap_t byteswap =
284 DMU_OT_BYTESWAP(dnp->dn_bonustype);
285 dmu_ot_byteswap[byteswap].ob_func(dnp->dn_bonus + off, len);
286 }
287
288 /* Swap SPILL block if we have one */
289 if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
290 byteswap_uint64_array(&dnp->dn_spill, sizeof (blkptr_t));
291
292 }
293
294 void
295 dnode_buf_byteswap(void *vbuf, size_t size)
296 {
297 dnode_phys_t *buf = vbuf;
298 int i;
299
300 ASSERT3U(sizeof (dnode_phys_t), ==, (1<<DNODE_SHIFT));
301 ASSERT((size & (sizeof (dnode_phys_t)-1)) == 0);
302
303 size >>= DNODE_SHIFT;
304 for (i = 0; i < size; i++) {
305 dnode_byteswap(buf);
393 dnode_setdblksz(dn, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
394 } else {
395 dn->dn_datablksz = 0;
396 dn->dn_datablkszsec = 0;
397 dn->dn_datablkshift = 0;
398 }
399 dn->dn_indblkshift = dnp->dn_indblkshift;
400 dn->dn_nlevels = dnp->dn_nlevels;
401 dn->dn_type = dnp->dn_type;
402 dn->dn_nblkptr = dnp->dn_nblkptr;
403 dn->dn_checksum = dnp->dn_checksum;
404 dn->dn_compress = dnp->dn_compress;
405 dn->dn_bonustype = dnp->dn_bonustype;
406 dn->dn_bonuslen = dnp->dn_bonuslen;
407 dn->dn_maxblkid = dnp->dn_maxblkid;
408 dn->dn_have_spill = ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0);
409 dn->dn_id_flags = 0;
410
411 dmu_zfetch_init(&dn->dn_zfetch, dn);
412
413 ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
414
415 mutex_enter(&os->os_lock);
416 list_insert_head(&os->os_dnodes, dn);
417 membar_producer();
418 /*
419 * Everything else must be valid before assigning dn_objset makes the
420 * dnode eligible for dnode_move().
421 */
422 dn->dn_objset = os;
423 mutex_exit(&os->os_lock);
424
425 arc_space_consume(sizeof (dnode_t), ARC_SPACE_OTHER);
426 return (dn);
427 }
428
429 /*
430 * Caller must be holding the dnode handle, which is released upon return.
431 */
432 static void
433 dnode_destroy(dnode_t *dn)
482
483 if (blocksize == 0)
484 blocksize = 1 << zfs_default_bs;
485 else if (blocksize > SPA_MAXBLOCKSIZE)
486 blocksize = SPA_MAXBLOCKSIZE;
487 else
488 blocksize = P2ROUNDUP(blocksize, SPA_MINBLOCKSIZE);
489
490 if (ibs == 0)
491 ibs = zfs_default_ibs;
492
493 ibs = MIN(MAX(ibs, DN_MIN_INDBLKSHIFT), DN_MAX_INDBLKSHIFT);
494
495 dprintf("os=%p obj=%llu txg=%llu blocksize=%d ibs=%d\n", dn->dn_objset,
496 dn->dn_object, tx->tx_txg, blocksize, ibs);
497
498 ASSERT(dn->dn_type == DMU_OT_NONE);
499 ASSERT(bcmp(dn->dn_phys, &dnode_phys_zero, sizeof (dnode_phys_t)) == 0);
500 ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE);
501 ASSERT(ot != DMU_OT_NONE);
502 ASSERT(DMU_OT_IS_VALID(ot));
503 ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
504 (bonustype == DMU_OT_SA && bonuslen == 0) ||
505 (bonustype != DMU_OT_NONE && bonuslen != 0));
506 ASSERT(DMU_OT_IS_VALID(bonustype));
507 ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
508 ASSERT(dn->dn_type == DMU_OT_NONE);
509 ASSERT3U(dn->dn_maxblkid, ==, 0);
510 ASSERT3U(dn->dn_allocated_txg, ==, 0);
511 ASSERT3U(dn->dn_assigned_txg, ==, 0);
512 ASSERT(refcount_is_zero(&dn->dn_tx_holds));
513 ASSERT3U(refcount_count(&dn->dn_holds), <=, 1);
514 ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
515
516 for (i = 0; i < TXG_SIZE; i++) {
517 ASSERT3U(dn->dn_next_nblkptr[i], ==, 0);
518 ASSERT3U(dn->dn_next_nlevels[i], ==, 0);
519 ASSERT3U(dn->dn_next_indblkshift[i], ==, 0);
520 ASSERT3U(dn->dn_next_bonuslen[i], ==, 0);
521 ASSERT3U(dn->dn_next_bonustype[i], ==, 0);
522 ASSERT3U(dn->dn_rm_spillblk[i], ==, 0);
523 ASSERT3U(dn->dn_next_blksz[i], ==, 0);
524 ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
525 ASSERT3P(list_head(&dn->dn_dirty_records[i]), ==, NULL);
526 ASSERT3U(avl_numnodes(&dn->dn_ranges[i]), ==, 0);
554 dn->dn_next_indblkshift[tx->tx_txg & TXG_MASK] = ibs;
555 dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = dn->dn_bonuslen;
556 dn->dn_next_bonustype[tx->tx_txg & TXG_MASK] = dn->dn_bonustype;
557 dn->dn_next_blksz[tx->tx_txg & TXG_MASK] = dn->dn_datablksz;
558 }
559
560 void
561 dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
562 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
563 {
564 int nblkptr;
565
566 ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
567 ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
568 ASSERT3U(blocksize % SPA_MINBLOCKSIZE, ==, 0);
569 ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx));
570 ASSERT(tx->tx_txg != 0);
571 ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
572 (bonustype != DMU_OT_NONE && bonuslen != 0) ||
573 (bonustype == DMU_OT_SA && bonuslen == 0));
574 ASSERT(DMU_OT_IS_VALID(bonustype));
575 ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
576
577 /* clean up any unreferenced dbufs */
578 dnode_evict_dbufs(dn);
579
580 dn->dn_id_flags = 0;
581
582 rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
583 dnode_setdirty(dn, tx);
584 if (dn->dn_datablksz != blocksize) {
585 /* change blocksize */
586 ASSERT(dn->dn_maxblkid == 0 &&
587 (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
588 dnode_block_freed(dn, 0)));
589 dnode_setdblksz(dn, blocksize);
590 dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
591 }
592 if (dn->dn_bonuslen != bonuslen)
593 dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
594
|