18 * |
18 * |
19 * CDDL HEADER END |
19 * CDDL HEADER END |
20 */ |
20 */ |
21 /* |
21 /* |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
|
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. |
23 */ |
24 */ |
24 |
25 |
25 #include <sys/zfs_context.h> |
26 #include <sys/zfs_context.h> |
26 #include <sys/dmu.h> |
27 #include <sys/dmu.h> |
27 #include <sys/dmu_impl.h> |
28 #include <sys/dmu_impl.h> |
1298 /* |
1299 /* |
1299 * If this buffer is currently held, we cannot undirty |
1300 * If this buffer is currently held, we cannot undirty |
1300 * it, since one of the current holders may be in the |
1301 * it, since one of the current holders may be in the |
1301 * middle of an update. Note that users of dbuf_undirty() |
1302 * middle of an update. Note that users of dbuf_undirty() |
1302 * should not place a hold on the dbuf before the call. |
1303 * should not place a hold on the dbuf before the call. |
|
1304 * Also note: we can get here with a spill block, so |
|
1305 * test for that similar to how dbuf_dirty does. |
1303 */ |
1306 */ |
1304 if (refcount_count(&db->db_holds) > db->db_dirtycnt) { |
1307 if (refcount_count(&db->db_holds) > db->db_dirtycnt) { |
1305 mutex_exit(&db->db_mtx); |
1308 mutex_exit(&db->db_mtx); |
1306 /* Make sure we don't toss this buffer at sync phase */ |
1309 /* Make sure we don't toss this buffer at sync phase */ |
1307 mutex_enter(&dn->dn_mtx); |
1310 if (db->db_blkid != DMU_SPILL_BLKID) { |
1308 dnode_clear_range(dn, db->db_blkid, 1, tx); |
1311 mutex_enter(&dn->dn_mtx); |
1309 mutex_exit(&dn->dn_mtx); |
1312 dnode_clear_range(dn, db->db_blkid, 1, tx); |
|
1313 mutex_exit(&dn->dn_mtx); |
|
1314 } |
1310 DB_DNODE_EXIT(db); |
1315 DB_DNODE_EXIT(db); |
1311 return (0); |
1316 return (0); |
1312 } |
1317 } |
1313 |
1318 |
1314 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size); |
1319 dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size); |
1317 |
1322 |
1318 /* XXX would be nice to fix up dn_towrite_space[] */ |
1323 /* XXX would be nice to fix up dn_towrite_space[] */ |
1319 |
1324 |
1320 *drp = dr->dr_next; |
1325 *drp = dr->dr_next; |
1321 |
1326 |
|
1327 /* |
|
1328 * Note that there are three places in dbuf_dirty() |
|
1329 * where this dirty record may be put on a list. |
|
1330 * Make sure to do a list_remove corresponding to |
|
1331 * every one of those list_insert calls. |
|
1332 */ |
1322 if (dr->dr_parent) { |
1333 if (dr->dr_parent) { |
1323 mutex_enter(&dr->dr_parent->dt.di.dr_mtx); |
1334 mutex_enter(&dr->dr_parent->dt.di.dr_mtx); |
1324 list_remove(&dr->dr_parent->dt.di.dr_children, dr); |
1335 list_remove(&dr->dr_parent->dt.di.dr_children, dr); |
1325 mutex_exit(&dr->dr_parent->dt.di.dr_mtx); |
1336 mutex_exit(&dr->dr_parent->dt.di.dr_mtx); |
1326 } else if (db->db_level+1 == dn->dn_nlevels) { |
1337 } else if (db->db_blkid == DMU_SPILL_BLKID || |
|
1338 db->db_level+1 == dn->dn_nlevels) { |
1327 ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf); |
1339 ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf); |
1328 mutex_enter(&dn->dn_mtx); |
1340 mutex_enter(&dn->dn_mtx); |
1329 list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr); |
1341 list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr); |
1330 mutex_exit(&dn->dn_mtx); |
1342 mutex_exit(&dn->dn_mtx); |
1331 } |
1343 } |