dmu_tx.c (226944) | dmu_tx.c (243674) |
---|---|
1/* 2 * CDDL HEADER START 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 --- 6 unchanged lines hidden (view full) --- 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. | 1/* 2 * CDDL HEADER START 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 --- 6 unchanged lines hidden (view full) --- 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 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. | 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. |
24 * Copyright (c) 2012 by Delphix. All rights reserved. |
|
26 */ 27 28#include <sys/dmu.h> 29#include <sys/dmu_impl.h> 30#include <sys/dbuf.h> 31#include <sys/dmu_tx.h> 32#include <sys/dmu_objset.h> 33#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */ --- 391 unchanged lines hidden (view full) --- 425dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) 426{ 427 uint64_t blkid, nblks, lastblk; 428 uint64_t space = 0, unref = 0, skipped = 0; 429 dnode_t *dn = txh->txh_dnode; 430 dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; 431 spa_t *spa = txh->txh_tx->tx_pool->dp_spa; 432 int epbs; | 25 */ 26 27#include <sys/dmu.h> 28#include <sys/dmu_impl.h> 29#include <sys/dbuf.h> 30#include <sys/dmu_tx.h> 31#include <sys/dmu_objset.h> 32#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */ --- 391 unchanged lines hidden (view full) --- 424dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) 425{ 426 uint64_t blkid, nblks, lastblk; 427 uint64_t space = 0, unref = 0, skipped = 0; 428 dnode_t *dn = txh->txh_dnode; 429 dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; 430 spa_t *spa = txh->txh_tx->tx_pool->dp_spa; 431 int epbs; |
432 uint64_t l0span = 0, nl1blks = 0; |
|
433 434 if (dn->dn_nlevels == 0) 435 return; 436 437 /* 438 * The struct_rwlock protects us against dn_nlevels 439 * changing, in case (against all odds) we manage to dirty & 440 * sync out the changes after we check for being dirty. --- 16 unchanged lines hidden (view full) --- 457 if (blkid >= dn->dn_maxblkid) { 458 rw_exit(&dn->dn_struct_rwlock); 459 return; 460 } 461 if (blkid + nblks > dn->dn_maxblkid) 462 nblks = dn->dn_maxblkid - blkid; 463 464 } | 433 434 if (dn->dn_nlevels == 0) 435 return; 436 437 /* 438 * The struct_rwlock protects us against dn_nlevels 439 * changing, in case (against all odds) we manage to dirty & 440 * sync out the changes after we check for being dirty. --- 16 unchanged lines hidden (view full) --- 457 if (blkid >= dn->dn_maxblkid) { 458 rw_exit(&dn->dn_struct_rwlock); 459 return; 460 } 461 if (blkid + nblks > dn->dn_maxblkid) 462 nblks = dn->dn_maxblkid - blkid; 463 464 } |
465 l0span = nblks; /* save for later use to calc level > 1 overhead */ |
|
465 if (dn->dn_nlevels == 1) { 466 int i; 467 for (i = 0; i < nblks; i++) { 468 blkptr_t *bp = dn->dn_phys->dn_blkptr; 469 ASSERT3U(blkid + i, <, dn->dn_nblkptr); 470 bp += blkid + i; 471 if (dsl_dataset_block_freeable(ds, bp, bp->blk_birth)) { 472 dprintf_bp(bp, "can free old%s", ""); 473 space += bp_get_dsize(spa, bp); 474 } 475 unref += BP_GET_ASIZE(bp); 476 } | 466 if (dn->dn_nlevels == 1) { 467 int i; 468 for (i = 0; i < nblks; i++) { 469 blkptr_t *bp = dn->dn_phys->dn_blkptr; 470 ASSERT3U(blkid + i, <, dn->dn_nblkptr); 471 bp += blkid + i; 472 if (dsl_dataset_block_freeable(ds, bp, bp->blk_birth)) { 473 dprintf_bp(bp, "can free old%s", ""); 474 space += bp_get_dsize(spa, bp); 475 } 476 unref += BP_GET_ASIZE(bp); 477 } |
478 nl1blks = 1; |
|
477 nblks = 0; 478 } 479 | 479 nblks = 0; 480 } 481 |
480 /* 481 * Add in memory requirements of higher-level indirects. 482 * This assumes a worst-possible scenario for dn_nlevels. 483 */ 484 { 485 uint64_t blkcnt = 1 + ((nblks >> epbs) >> epbs); 486 int level = (dn->dn_nlevels > 1) ? 2 : 1; 487 488 while (level++ < DN_MAX_LEVELS) { 489 txh->txh_memory_tohold += blkcnt << dn->dn_indblkshift; 490 blkcnt = 1 + (blkcnt >> epbs); 491 } 492 ASSERT(blkcnt <= dn->dn_nblkptr); 493 } 494 | |
495 lastblk = blkid + nblks - 1; 496 while (nblks) { 497 dmu_buf_impl_t *dbuf; 498 uint64_t ibyte, new_blkid; 499 int epb = 1 << epbs; 500 int err, i, blkoff, tochk; 501 blkptr_t *bp; 502 --- 54 unchanged lines hidden (view full) --- 557 bp[i].blk_birth)) { 558 dprintf_bp(&bp[i], "can free old%s", ""); 559 space += bp_get_dsize(spa, &bp[i]); 560 } 561 unref += BP_GET_ASIZE(bp); 562 } 563 dbuf_rele(dbuf, FTAG); 564 | 482 lastblk = blkid + nblks - 1; 483 while (nblks) { 484 dmu_buf_impl_t *dbuf; 485 uint64_t ibyte, new_blkid; 486 int epb = 1 << epbs; 487 int err, i, blkoff, tochk; 488 blkptr_t *bp; 489 --- 54 unchanged lines hidden (view full) --- 544 bp[i].blk_birth)) { 545 dprintf_bp(&bp[i], "can free old%s", ""); 546 space += bp_get_dsize(spa, &bp[i]); 547 } 548 unref += BP_GET_ASIZE(bp); 549 } 550 dbuf_rele(dbuf, FTAG); 551 |
552 ++nl1blks; |
|
565 blkid += tochk; 566 nblks -= tochk; 567 } 568 rw_exit(&dn->dn_struct_rwlock); 569 | 553 blkid += tochk; 554 nblks -= tochk; 555 } 556 rw_exit(&dn->dn_struct_rwlock); 557 |
558 /* 559 * Add in memory requirements of higher-level indirects. 560 * This assumes a worst-possible scenario for dn_nlevels and a 561 * worst-possible distribution of l1-blocks over the region to free. 562 */ 563 { 564 uint64_t blkcnt = 1 + ((l0span >> epbs) >> epbs); 565 int level = 2; 566 /* 567 * Here we don't use DN_MAX_LEVEL, but calculate it with the 568 * given datablkshift and indblkshift. This makes the 569 * difference between 19 and 8 on large files. 570 */ 571 int maxlevel = 2 + (DN_MAX_OFFSET_SHIFT - dn->dn_datablkshift) / 572 (dn->dn_indblkshift - SPA_BLKPTRSHIFT); 573 574 while (level++ < maxlevel) { 575 txh->txh_memory_tohold += MAX(MIN(blkcnt, nl1blks), 1) 576 << dn->dn_indblkshift; 577 blkcnt = 1 + (blkcnt >> epbs); 578 } 579 } 580 |
|
570 /* account for new level 1 indirect blocks that might show up */ 571 if (skipped > 0) { 572 txh->txh_fudge += skipped << dn->dn_indblkshift; 573 skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs); 574 txh->txh_memory_tohold += skipped << dn->dn_indblkshift; 575 } 576 txh->txh_space_tofree += space; 577 txh->txh_space_tounref += unref; --- 93 unchanged lines hidden (view full) --- 671 * We will be able to fit a new object's entries into one leaf 672 * block. So there will be at most 2 blocks total, 673 * including the header block. 674 */ 675 dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift); 676 return; 677 } 678 | 581 /* account for new level 1 indirect blocks that might show up */ 582 if (skipped > 0) { 583 txh->txh_fudge += skipped << dn->dn_indblkshift; 584 skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs); 585 txh->txh_memory_tohold += skipped << dn->dn_indblkshift; 586 } 587 txh->txh_space_tofree += space; 588 txh->txh_space_tounref += unref; --- 93 unchanged lines hidden (view full) --- 682 * We will be able to fit a new object's entries into one leaf 683 * block. So there will be at most 2 blocks total, 684 * including the header block. 685 */ 686 dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift); 687 return; 688 } 689 |
679 ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap); | 690 ASSERT3P(DMU_OT_BYTESWAP(dn->dn_type), ==, DMU_BSWAP_ZAP); |
680 681 if (dn->dn_maxblkid == 0 && !add) { 682 blkptr_t *bp; 683 684 /* 685 * If there is only one block (i.e. this is a micro-zap) 686 * and we are not adding anything, the accounting is simple. 687 */ --- 207 unchanged lines hidden (view full) --- 895static int 896dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) 897{ 898 dmu_tx_hold_t *txh; 899 spa_t *spa = tx->tx_pool->dp_spa; 900 uint64_t memory, asize, fsize, usize; 901 uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge; 902 | 691 692 if (dn->dn_maxblkid == 0 && !add) { 693 blkptr_t *bp; 694 695 /* 696 * If there is only one block (i.e. this is a micro-zap) 697 * and we are not adding anything, the accounting is simple. 698 */ --- 207 unchanged lines hidden (view full) --- 906static int 907dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) 908{ 909 dmu_tx_hold_t *txh; 910 spa_t *spa = tx->tx_pool->dp_spa; 911 uint64_t memory, asize, fsize, usize; 912 uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge; 913 |
903 ASSERT3U(tx->tx_txg, ==, 0); | 914 ASSERT0(tx->tx_txg); |
904 905 if (tx->tx_err) 906 return (tx->tx_err); 907 908 if (spa_suspended(spa)) { 909 /* 910 * If the user has indicated a blocking failure mode 911 * then return ERESTART which will block in dmu_tx_wait(). --- 475 unchanged lines hidden --- | 915 916 if (tx->tx_err) 917 return (tx->tx_err); 918 919 if (spa_suspended(spa)) { 920 /* 921 * If the user has indicated a blocking failure mode 922 * then return ERESTART which will block in dmu_tx_wait(). --- 475 unchanged lines hidden --- |