Deleted Added
full compact
dbuf.c (321541) dbuf.c (321547)
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

--- 1332 unchanged lines hidden (view full) ---

1341 arc_buf_freeze(db->db_buf);
1342 }
1343
1344 mutex_exit(&db->db_mtx);
1345 }
1346 mutex_exit(&dn->dn_dbufs_mtx);
1347}
1348
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

--- 1332 unchanged lines hidden (view full) ---

1341 arc_buf_freeze(db->db_buf);
1342 }
1343
1344 mutex_exit(&db->db_mtx);
1345 }
1346 mutex_exit(&dn->dn_dbufs_mtx);
1347}
1348
1349static int
1350dbuf_block_freeable(dmu_buf_impl_t *db)
1351{
1352 dsl_dataset_t *ds = db->db_objset->os_dsl_dataset;
1353 uint64_t birth_txg = 0;
1354
1355 /*
1356 * We don't need any locking to protect db_blkptr:
1357 * If it's syncing, then db_last_dirty will be set
1358 * so we'll ignore db_blkptr.
1359 *
1360 * This logic ensures that only block births for
1361 * filled blocks are considered.
1362 */
1363 ASSERT(MUTEX_HELD(&db->db_mtx));
1364 if (db->db_last_dirty && (db->db_blkptr == NULL ||
1365 !BP_IS_HOLE(db->db_blkptr))) {
1366 birth_txg = db->db_last_dirty->dr_txg;
1367 } else if (db->db_blkptr != NULL && !BP_IS_HOLE(db->db_blkptr)) {
1368 birth_txg = db->db_blkptr->blk_birth;
1369 }
1370
1371 /*
1372 * If this block don't exist or is in a snapshot, it can't be freed.
1373 * Don't pass the bp to dsl_dataset_block_freeable() since we
1374 * are holding the db_mtx lock and might deadlock if we are
1375 * prefetching a dedup-ed block.
1376 */
1377 if (birth_txg != 0)
1378 return (ds == NULL ||
1379 dsl_dataset_block_freeable(ds, NULL, birth_txg));
1380 else
1381 return (B_FALSE);
1382}
1383
1384void
1385dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx)
1386{
1387 arc_buf_t *buf, *obuf;
1388 int osize = db->db.db_size;
1389 arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
1390 dnode_t *dn;
1391

--- 33 unchanged lines hidden (view full) ---

1425 db->db.db_size = size;
1426
1427 if (db->db_level == 0) {
1428 ASSERT3U(db->db_last_dirty->dr_txg, ==, tx->tx_txg);
1429 db->db_last_dirty->dt.dl.dr_data = buf;
1430 }
1431 mutex_exit(&db->db_mtx);
1432
1349void
1350dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx)
1351{
1352 arc_buf_t *buf, *obuf;
1353 int osize = db->db.db_size;
1354 arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
1355 dnode_t *dn;
1356

--- 33 unchanged lines hidden (view full) ---

1390 db->db.db_size = size;
1391
1392 if (db->db_level == 0) {
1393 ASSERT3U(db->db_last_dirty->dr_txg, ==, tx->tx_txg);
1394 db->db_last_dirty->dt.dl.dr_data = buf;
1395 }
1396 mutex_exit(&db->db_mtx);
1397
1433 dnode_willuse_space(dn, size-osize, tx);
1398 dmu_objset_willuse_space(dn->dn_objset, size - osize, tx);
1434 DB_DNODE_EXIT(db);
1435}
1436
1437void
1438dbuf_release_bp(dmu_buf_impl_t *db)
1439{
1440 objset_t *os = db->db_objset;
1441

--- 33 unchanged lines hidden (view full) ---

1475
1476dbuf_dirty_record_t *
1477dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
1478{
1479 dnode_t *dn;
1480 objset_t *os;
1481 dbuf_dirty_record_t **drp, *dr;
1482 int drop_struct_lock = FALSE;
1399 DB_DNODE_EXIT(db);
1400}
1401
1402void
1403dbuf_release_bp(dmu_buf_impl_t *db)
1404{
1405 objset_t *os = db->db_objset;
1406

--- 33 unchanged lines hidden (view full) ---

1440
1441dbuf_dirty_record_t *
1442dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
1443{
1444 dnode_t *dn;
1445 objset_t *os;
1446 dbuf_dirty_record_t **drp, *dr;
1447 int drop_struct_lock = FALSE;
1483 boolean_t do_free_accounting = B_FALSE;
1484 int txgoff = tx->tx_txg & TXG_MASK;
1485
1486 ASSERT(tx->tx_txg != 0);
1487 ASSERT(!refcount_is_zero(&db->db_holds));
1488 DMU_TX_DIRTY_BUF(tx, db);
1489
1490 DB_DNODE_ENTER(db);
1491 dn = DB_DNODE(db);

--- 105 unchanged lines hidden (view full) ---

1597 if (dn->dn_objset->os_dsl_dataset != NULL)
1598 rrw_exit(&os->os_dsl_dataset->ds_bp_rwlock, FTAG);
1599#endif
1600 ASSERT(db->db.db_size != 0);
1601
1602 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
1603
1604 if (db->db_blkid != DMU_BONUS_BLKID) {
1448 int txgoff = tx->tx_txg & TXG_MASK;
1449
1450 ASSERT(tx->tx_txg != 0);
1451 ASSERT(!refcount_is_zero(&db->db_holds));
1452 DMU_TX_DIRTY_BUF(tx, db);
1453
1454 DB_DNODE_ENTER(db);
1455 dn = DB_DNODE(db);

--- 105 unchanged lines hidden (view full) ---

1561 if (dn->dn_objset->os_dsl_dataset != NULL)
1562 rrw_exit(&os->os_dsl_dataset->ds_bp_rwlock, FTAG);
1563#endif
1564 ASSERT(db->db.db_size != 0);
1565
1566 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
1567
1568 if (db->db_blkid != DMU_BONUS_BLKID) {
1605 /*
1606 * Update the accounting.
1607 * Note: we delay "free accounting" until after we drop
1608 * the db_mtx. This keeps us from grabbing other locks
1609 * (and possibly deadlocking) in bp_get_dsize() while
1610 * also holding the db_mtx.
1611 */
1612 dnode_willuse_space(dn, db->db.db_size, tx);
1613 do_free_accounting = dbuf_block_freeable(db);
1569 dmu_objset_willuse_space(os, db->db.db_size, tx);
1614 }
1615
1616 /*
1617 * If this buffer is dirty in an old transaction group we need
1618 * to make a copy of it so that the changes we make in this
1619 * transaction group won't leak out when we sync the older txg.
1620 */
1621 dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_SLEEP);

--- 76 unchanged lines hidden (view full) ---

1698 * while we are running, so we want to acquire it before
1699 * looking at db_blkptr.
1700 */
1701 if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
1702 rw_enter(&dn->dn_struct_rwlock, RW_READER);
1703 drop_struct_lock = TRUE;
1704 }
1705
1570 }
1571
1572 /*
1573 * If this buffer is dirty in an old transaction group we need
1574 * to make a copy of it so that the changes we make in this
1575 * transaction group won't leak out when we sync the older txg.
1576 */
1577 dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_SLEEP);

--- 76 unchanged lines hidden (view full) ---

1654 * while we are running, so we want to acquire it before
1655 * looking at db_blkptr.
1656 */
1657 if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
1658 rw_enter(&dn->dn_struct_rwlock, RW_READER);
1659 drop_struct_lock = TRUE;
1660 }
1661
1706 if (do_free_accounting) {
1707 blkptr_t *bp = db->db_blkptr;
1708 int64_t willfree = (bp && !BP_IS_HOLE(bp)) ?
1709 bp_get_dsize(os->os_spa, bp) : db->db.db_size;
1710 /*
1711 * This is only a guess -- if the dbuf is dirty
1712 * in a previous txg, we don't know how much
1713 * space it will use on disk yet. We should
1714 * really have the struct_rwlock to access
1715 * db_blkptr, but since this is just a guess,
1716 * it's OK if we get an odd answer.
1717 */
1718 ddt_prefetch(os->os_spa, bp);
1719 dnode_willuse_space(dn, -willfree, tx);
1720 }
1662 /*
1663 * If we are overwriting a dedup BP, then unless it is snapshotted,
1664 * when we get to syncing context we will need to decrement its
1665 * refcount in the DDT. Prefetch the relevant DDT block so that
1666 * syncing context won't have to wait for the i/o.
1667 */
1668 ddt_prefetch(os->os_spa, db->db_blkptr);
1721
1722 if (db->db_level == 0) {
1723 dnode_new_blkid(dn, db->db_blkid, tx, drop_struct_lock);
1724 ASSERT(dn->dn_maxblkid >= db->db_blkid);
1725 }
1726
1727 if (db->db_level+1 < dn->dn_nlevels) {
1728 dmu_buf_impl_t *parent = db->db_parent;

--- 1193 unchanged lines hidden (view full) ---

2922}
2923
2924void
2925dmu_buf_user_evict_wait()
2926{
2927 taskq_wait(dbu_evict_taskq);
2928}
2929
1669
1670 if (db->db_level == 0) {
1671 dnode_new_blkid(dn, db->db_blkid, tx, drop_struct_lock);
1672 ASSERT(dn->dn_maxblkid >= db->db_blkid);
1673 }
1674
1675 if (db->db_level+1 < dn->dn_nlevels) {
1676 dmu_buf_impl_t *parent = db->db_parent;

--- 1193 unchanged lines hidden (view full) ---

2870}
2871
2872void
2873dmu_buf_user_evict_wait()
2874{
2875 taskq_wait(dbu_evict_taskq);
2876}
2877
2930boolean_t
2931dmu_buf_freeable(dmu_buf_t *dbuf)
2932{
2933 boolean_t res = B_FALSE;
2934 dmu_buf_impl_t *db = (dmu_buf_impl_t *)dbuf;
2935
2936 if (db->db_blkptr)
2937 res = dsl_dataset_block_freeable(db->db_objset->os_dsl_dataset,
2938 db->db_blkptr, db->db_blkptr->blk_birth);
2939
2940 return (res);
2941}
2942
2943blkptr_t *
2944dmu_buf_get_blkptr(dmu_buf_t *db)
2945{
2946 dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
2947 return (dbi->db_blkptr);
2948}
2949
2950objset_t *

--- 705 unchanged lines hidden ---
2878blkptr_t *
2879dmu_buf_get_blkptr(dmu_buf_t *db)
2880{
2881 dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
2882 return (dbi->db_blkptr);
2883}
2884
2885objset_t *

--- 705 unchanged lines hidden ---