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, 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); |
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))); |
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 |
1333 dsl_pool_undirty_space(dmu_objset_pool(dn->dn_objset), 1334 dr->dr_accounted, txg); |
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 || |
1349 db->db_level + 1 == dn->dn_nlevels) { |
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 |
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); |
2323 dbuf_sync_list(&dr->dt.di.dr_children, db->db_level - 1, tx); |
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 |
2469dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx) |
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 } |
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 --- |