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 --- |