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

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

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 2011 Nexenta Systems, Inc. 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

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

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 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
24 * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
25 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 */
28
29#include <sys/zfs_context.h>
30#include <sys/dmu.h>
31#include <sys/dmu_send.h>
32#include <sys/dmu_impl.h>

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

1293static boolean_t
1294dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
1295{
1296 dnode_t *dn;
1297 uint64_t txg = tx->tx_txg;
1298 dbuf_dirty_record_t *dr, **drp;
1299
1300 ASSERT(txg != 0);
25 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 */
28
29#include <sys/zfs_context.h>
30#include <sys/dmu.h>
31#include <sys/dmu_send.h>
32#include <sys/dmu_impl.h>

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

1293static boolean_t
1294dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
1295{
1296 dnode_t *dn;
1297 uint64_t txg = tx->tx_txg;
1298 dbuf_dirty_record_t *dr, **drp;
1299
1300 ASSERT(txg != 0);
1301
1302 /*
1303 * Due to our use of dn_nlevels below, this can only be called
1304 * in open context, unless we are operating on the MOS.
1305 * From syncing context, dn_nlevels may be different from the
1306 * dn_nlevels used when dbuf was dirtied.
1307 */
1308 ASSERT(db->db_objset ==
1309 dmu_objset_pool(db->db_objset)->dp_meta_objset ||
1310 txg != spa_syncing_txg(dmu_objset_spa(db->db_objset)));
1301 ASSERT(db->db_blkid != DMU_BONUS_BLKID);
1302 ASSERT0(db->db_level);
1303 ASSERT(MUTEX_HELD(&db->db_mtx));
1304
1305 /*
1306 * If this buffer is not dirty, we're done.
1307 */
1308 for (drp = &db->db_last_dirty; (dr = *drp) != NULL; drp = &dr->dr_next)

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

1315
1316 DB_DNODE_ENTER(db);
1317 dn = DB_DNODE(db);
1318
1319 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
1320
1321 ASSERT(db->db.db_size != 0);
1322
1311 ASSERT(db->db_blkid != DMU_BONUS_BLKID);
1312 ASSERT0(db->db_level);
1313 ASSERT(MUTEX_HELD(&db->db_mtx));
1314
1315 /*
1316 * If this buffer is not dirty, we're done.
1317 */
1318 for (drp = &db->db_last_dirty; (dr = *drp) != NULL; drp = &dr->dr_next)

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

1325
1326 DB_DNODE_ENTER(db);
1327 dn = DB_DNODE(db);
1328
1329 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
1330
1331 ASSERT(db->db.db_size != 0);
1332
1323 /*
1324 * Any space we accounted for in dp_dirty_* will be cleaned up by
1325 * dsl_pool_sync(). This is relatively rare so the discrepancy
1326 * is not a big deal.
1327 */
1333 dsl_pool_undirty_space(dmu_objset_pool(dn->dn_objset),
1334 dr->dr_accounted, txg);
1328
1329 *drp = dr->dr_next;
1330
1331 /*
1332 * Note that there are three places in dbuf_dirty()
1333 * where this dirty record may be put on a list.
1334 * Make sure to do a list_remove corresponding to
1335 * every one of those list_insert calls.
1336 */
1337 if (dr->dr_parent) {
1338 mutex_enter(&dr->dr_parent->dt.di.dr_mtx);
1339 list_remove(&dr->dr_parent->dt.di.dr_children, dr);
1340 mutex_exit(&dr->dr_parent->dt.di.dr_mtx);
1341 } else if (db->db_blkid == DMU_SPILL_BLKID ||
1335
1336 *drp = dr->dr_next;
1337
1338 /*
1339 * Note that there are three places in dbuf_dirty()
1340 * where this dirty record may be put on a list.
1341 * Make sure to do a list_remove corresponding to
1342 * every one of those list_insert calls.
1343 */
1344 if (dr->dr_parent) {
1345 mutex_enter(&dr->dr_parent->dt.di.dr_mtx);
1346 list_remove(&dr->dr_parent->dt.di.dr_children, dr);
1347 mutex_exit(&dr->dr_parent->dt.di.dr_mtx);
1348 } else if (db->db_blkid == DMU_SPILL_BLKID ||
1342 db->db_level+1 == dn->dn_nlevels) {
1349 db->db_level + 1 == dn->dn_nlevels) {
1343 ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf);
1344 mutex_enter(&dn->dn_mtx);
1345 list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr);
1346 mutex_exit(&dn->dn_mtx);
1347 }
1348 DB_DNODE_EXIT(db);
1349
1350 if (db->db_state != DB_NOFILL) {
1351 dbuf_unoverride(dr);
1352
1353 ASSERT(db->db_buf != NULL);
1354 ASSERT(dr->dt.dl.dr_data != NULL);
1355 if (dr->dt.dl.dr_data != db->db_buf)
1356 VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db));
1357 }
1358
1350 ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf);
1351 mutex_enter(&dn->dn_mtx);
1352 list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr);
1353 mutex_exit(&dn->dn_mtx);
1354 }
1355 DB_DNODE_EXIT(db);
1356
1357 if (db->db_state != DB_NOFILL) {
1358 dbuf_unoverride(dr);
1359
1360 ASSERT(db->db_buf != NULL);
1361 ASSERT(dr->dt.dl.dr_data != NULL);
1362 if (dr->dt.dl.dr_data != db->db_buf)
1363 VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db));
1364 }
1365
1359 if (db->db_level != 0) {
1360 mutex_destroy(&dr->dt.di.dr_mtx);
1361 list_destroy(&dr->dt.di.dr_children);
1362 }
1363
1364 kmem_free(dr, sizeof (dbuf_dirty_record_t));
1365
1366 ASSERT(db->db_dirtycnt > 0);
1367 db->db_dirtycnt -= 1;
1368
1369 if (refcount_remove(&db->db_holds, (void *)(uintptr_t)txg) == 0) {
1370 arc_buf_t *buf = db->db_buf;
1371

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

2313 /* Provide the pending dirty record to child dbufs */
2314 db->db_data_pending = dr;
2315
2316 mutex_exit(&db->db_mtx);
2317 dbuf_write(dr, db->db_buf, tx);
2318
2319 zio = dr->dr_zio;
2320 mutex_enter(&dr->dt.di.dr_mtx);
1366 kmem_free(dr, sizeof (dbuf_dirty_record_t));
1367
1368 ASSERT(db->db_dirtycnt > 0);
1369 db->db_dirtycnt -= 1;
1370
1371 if (refcount_remove(&db->db_holds, (void *)(uintptr_t)txg) == 0) {
1372 arc_buf_t *buf = db->db_buf;
1373

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

2315 /* Provide the pending dirty record to child dbufs */
2316 db->db_data_pending = dr;
2317
2318 mutex_exit(&db->db_mtx);
2319 dbuf_write(dr, db->db_buf, tx);
2320
2321 zio = dr->dr_zio;
2322 mutex_enter(&dr->dt.di.dr_mtx);
2321 dbuf_sync_list(&dr->dt.di.dr_children, tx);
2323 dbuf_sync_list(&dr->dt.di.dr_children, db->db_level - 1, tx);
2322 ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
2323 mutex_exit(&dr->dt.di.dr_mtx);
2324 zio_nowait(zio);
2325}
2326
2327static void
2328dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
2329{

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

2459 * zio_nowait() invalidates the dbuf.
2460 */
2461 DB_DNODE_EXIT(db);
2462 zio_nowait(dr->dr_zio);
2463 }
2464}
2465
2466void
2324 ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
2325 mutex_exit(&dr->dt.di.dr_mtx);
2326 zio_nowait(zio);
2327}
2328
2329static void
2330dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
2331{

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

2461 * zio_nowait() invalidates the dbuf.
2462 */
2463 DB_DNODE_EXIT(db);
2464 zio_nowait(dr->dr_zio);
2465 }
2466}
2467
2468void
2467dbuf_sync_list(list_t *list, dmu_tx_t *tx)
2469dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx)
2468{
2469 dbuf_dirty_record_t *dr;
2470
2471 while (dr = list_head(list)) {
2472 if (dr->dr_zio != NULL) {
2473 /*
2474 * If we find an already initialized zio then we
2475 * are processing the meta-dnode, and we have finished.
2476 * The dbufs for all dnodes are put back on the list
2477 * during processing, so that we can zio_wait()
2478 * these IOs after initiating all child IOs.
2479 */
2480 ASSERT3U(dr->dr_dbuf->db.db_object, ==,
2481 DMU_META_DNODE_OBJECT);
2482 break;
2483 }
2470{
2471 dbuf_dirty_record_t *dr;
2472
2473 while (dr = list_head(list)) {
2474 if (dr->dr_zio != NULL) {
2475 /*
2476 * If we find an already initialized zio then we
2477 * are processing the meta-dnode, and we have finished.
2478 * The dbufs for all dnodes are put back on the list
2479 * during processing, so that we can zio_wait()
2480 * these IOs after initiating all child IOs.
2481 */
2482 ASSERT3U(dr->dr_dbuf->db.db_object, ==,
2483 DMU_META_DNODE_OBJECT);
2484 break;
2485 }
2486 if (dr->dr_dbuf->db_blkid != DMU_BONUS_BLKID &&
2487 dr->dr_dbuf->db_blkid != DMU_SPILL_BLKID) {
2488 VERIFY3U(dr->dr_dbuf->db_level, ==, level);
2489 }
2484 list_remove(list, dr);
2485 if (dr->dr_dbuf->db_level > 0)
2486 dbuf_sync_indirect(dr, tx);
2487 else
2488 dbuf_sync_leaf(dr, tx);
2489 }
2490}
2491

--- 346 unchanged lines hidden ---
2490 list_remove(list, dr);
2491 if (dr->dr_dbuf->db_level > 0)
2492 dbuf_sync_indirect(dr, tx);
2493 else
2494 dbuf_sync_leaf(dr, tx);
2495 }
2496}
2497

--- 346 unchanged lines hidden ---