usr/src/uts/common/fs/zfs/dbuf.c
changeset 9412 4aefd8704ce0
parent 9396 f41cf682d0d3
child 9653 a70048a304d1
equal deleted inserted replaced
9411:aa9f143d2a60 9412:4aefd8704ce0
  1305 	}
  1305 	}
  1306 	mutex_exit(&db->db_mtx);
  1306 	mutex_exit(&db->db_mtx);
  1307 }
  1307 }
  1308 
  1308 
  1309 /*
  1309 /*
       
  1310  * Directly assign a provided arc buf to a given dbuf if it's not referenced
       
  1311  * by anybody except our caller. Otherwise copy arcbuf's contents to dbuf.
       
  1312  */
       
  1313 void
       
  1314 dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx)
       
  1315 {
       
  1316 	ASSERT(!refcount_is_zero(&db->db_holds));
       
  1317 	ASSERT(db->db_dnode->dn_object != DMU_META_DNODE_OBJECT);
       
  1318 	ASSERT(db->db_blkid != DB_BONUS_BLKID);
       
  1319 	ASSERT(db->db_level == 0);
       
  1320 	ASSERT(DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA);
       
  1321 	ASSERT(buf != NULL);
       
  1322 	ASSERT(arc_buf_size(buf) == db->db.db_size);
       
  1323 	ASSERT(tx->tx_txg != 0);
       
  1324 
       
  1325 	arc_return_buf(buf, db);
       
  1326 	ASSERT(arc_released(buf));
       
  1327 
       
  1328 	mutex_enter(&db->db_mtx);
       
  1329 
       
  1330 	while (db->db_state == DB_READ || db->db_state == DB_FILL)
       
  1331 		cv_wait(&db->db_changed, &db->db_mtx);
       
  1332 
       
  1333 	ASSERT(db->db_state == DB_CACHED || db->db_state == DB_UNCACHED);
       
  1334 
       
  1335 	if (db->db_state == DB_CACHED &&
       
  1336 	    refcount_count(&db->db_holds) - 1 > db->db_dirtycnt) {
       
  1337 		mutex_exit(&db->db_mtx);
       
  1338 		(void) dbuf_dirty(db, tx);
       
  1339 		bcopy(buf->b_data, db->db.db_data, db->db.db_size);
       
  1340 		VERIFY(arc_buf_remove_ref(buf, db) == 1);
       
  1341 		return;
       
  1342 	}
       
  1343 
       
  1344 	if (db->db_state == DB_CACHED) {
       
  1345 		dbuf_dirty_record_t *dr = db->db_last_dirty;
       
  1346 
       
  1347 		ASSERT(db->db_buf != NULL);
       
  1348 		if (dr != NULL && dr->dr_txg == tx->tx_txg) {
       
  1349 			ASSERT(dr->dt.dl.dr_data == db->db_buf);
       
  1350 			if (!arc_released(db->db_buf)) {
       
  1351 				ASSERT(dr->dt.dl.dr_override_state ==
       
  1352 				    DR_OVERRIDDEN);
       
  1353 				arc_release(db->db_buf, db);
       
  1354 			}
       
  1355 			dr->dt.dl.dr_data = buf;
       
  1356 			VERIFY(arc_buf_remove_ref(db->db_buf, db) == 1);
       
  1357 		} else if (dr == NULL || dr->dt.dl.dr_data != db->db_buf) {
       
  1358 			arc_release(db->db_buf, db);
       
  1359 			VERIFY(arc_buf_remove_ref(db->db_buf, db) == 1);
       
  1360 		}
       
  1361 		db->db_buf = NULL;
       
  1362 	}
       
  1363 	ASSERT(db->db_buf == NULL);
       
  1364 	dbuf_set_data(db, buf);
       
  1365 	db->db_state = DB_FILL;
       
  1366 	mutex_exit(&db->db_mtx);
       
  1367 	(void) dbuf_dirty(db, tx);
       
  1368 	dbuf_fill_done(db, tx);
       
  1369 }
       
  1370 
       
  1371 /*
  1310  * "Clear" the contents of this dbuf.  This will mark the dbuf
  1372  * "Clear" the contents of this dbuf.  This will mark the dbuf
  1311  * EVICTING and clear *most* of its references.  Unfortunetely,
  1373  * EVICTING and clear *most* of its references.  Unfortunetely,
  1312  * when we are not holding the dn_dbufs_mtx, we can't clear the
  1374  * when we are not holding the dn_dbufs_mtx, we can't clear the
  1313  * entry in the dn_dbufs list.  We have to wait until dbuf_destroy()
  1375  * entry in the dn_dbufs list.  We have to wait until dbuf_destroy()
  1314  * in this case.  For callers from the DMU we will usually see:
  1376  * in this case.  For callers from the DMU we will usually see: