usr/src/uts/common/fs/zfs/bplist.c
changeset 1544 938876158511
parent 789 b348f31ed315
child 2082 76b439ec3ac1
--- a/usr/src/uts/common/fs/zfs/bplist.c	Fri Mar 03 17:59:43 2006 -0800
+++ b/usr/src/uts/common/fs/zfs/bplist.c	Fri Mar 03 20:08:16 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,16 +28,18 @@
 #include <sys/bplist.h>
 #include <sys/zfs_context.h>
 
-static void
+static int
 bplist_hold(bplist_t *bpl)
 {
 	ASSERT(MUTEX_HELD(&bpl->bpl_lock));
 	if (bpl->bpl_dbuf == NULL) {
-		bpl->bpl_dbuf = dmu_bonus_hold_tag(bpl->bpl_mos,
-		    bpl->bpl_object, bpl);
-		dmu_buf_read(bpl->bpl_dbuf);
+		int err = dmu_bonus_hold(bpl->bpl_mos,
+		    bpl->bpl_object, bpl, &bpl->bpl_dbuf);
+		if (err)
+			return (err);
 		bpl->bpl_phys = bpl->bpl_dbuf->db_data;
 	}
+	return (0);
 }
 
 uint64_t
@@ -58,12 +59,15 @@
 	VERIFY(dmu_object_free(mos, object, tx) == 0);
 }
 
-void
+int
 bplist_open(bplist_t *bpl, objset_t *mos, uint64_t object)
 {
 	dmu_object_info_t doi;
+	int err;
 
-	VERIFY(dmu_object_info(mos, object, &doi) == 0);
+	err = dmu_object_info(mos, object, &doi);
+	if (err)
+		return (err);
 
 	mutex_enter(&bpl->bpl_lock);
 
@@ -79,6 +83,7 @@
 	bpl->bpl_bpshift = bpl->bpl_blockshift - SPA_BLKPTRSHIFT;
 
 	mutex_exit(&bpl->bpl_lock);
+	return (0);
 }
 
 void
@@ -89,11 +94,11 @@
 	ASSERT(bpl->bpl_queue == NULL);
 
 	if (bpl->bpl_cached_dbuf) {
-		dmu_buf_rele(bpl->bpl_cached_dbuf);
+		dmu_buf_rele(bpl->bpl_cached_dbuf, bpl);
 		bpl->bpl_cached_dbuf = NULL;
 	}
 	if (bpl->bpl_dbuf) {
-		dmu_buf_rele_tag(bpl->bpl_dbuf, bpl);
+		dmu_buf_rele(bpl->bpl_dbuf, bpl);
 		bpl->bpl_dbuf = NULL;
 		bpl->bpl_phys = NULL;
 	}
@@ -110,22 +115,45 @@
 		return (B_TRUE);
 
 	mutex_enter(&bpl->bpl_lock);
-	bplist_hold(bpl);
+	VERIFY(0 == bplist_hold(bpl)); /* XXX */
 	rv = (bpl->bpl_phys->bpl_entries == 0);
 	mutex_exit(&bpl->bpl_lock);
 
 	return (rv);
 }
 
+static int
+bplist_cache(bplist_t *bpl, uint64_t blkid)
+{
+	int err = 0;
+
+	if (bpl->bpl_cached_dbuf == NULL ||
+	    bpl->bpl_cached_dbuf->db_offset != (blkid << bpl->bpl_blockshift)) {
+		if (bpl->bpl_cached_dbuf != NULL)
+			dmu_buf_rele(bpl->bpl_cached_dbuf, bpl);
+		err = dmu_buf_hold(bpl->bpl_mos,
+		    bpl->bpl_object, blkid << bpl->bpl_blockshift,
+		    bpl, &bpl->bpl_cached_dbuf);
+		ASSERT(err || bpl->bpl_cached_dbuf->db_size ==
+		    1ULL << bpl->bpl_blockshift);
+	}
+	return (err);
+}
+
 int
 bplist_iterate(bplist_t *bpl, uint64_t *itorp, blkptr_t *bp)
 {
 	uint64_t blk, off;
 	blkptr_t *bparray;
-	dmu_buf_t *db;
+	int err;
 
 	mutex_enter(&bpl->bpl_lock);
-	bplist_hold(bpl);
+
+	err = bplist_hold(bpl);
+	if (err) {
+		mutex_exit(&bpl->bpl_lock);
+		return (err);
+	}
 
 	if (*itorp >= bpl->bpl_phys->bpl_entries) {
 		mutex_exit(&bpl->bpl_lock);
@@ -134,51 +162,44 @@
 
 	blk = *itorp >> bpl->bpl_bpshift;
 	off = P2PHASE(*itorp, 1ULL << bpl->bpl_bpshift);
-	db = bpl->bpl_cached_dbuf;
 
-	if (db == NULL || db->db_offset != (blk << bpl->bpl_blockshift)) {
-		if (db != NULL)
-			dmu_buf_rele(db);
-		bpl->bpl_cached_dbuf = db = dmu_buf_hold(bpl->bpl_mos,
-		    bpl->bpl_object, blk << bpl->bpl_blockshift);
+	err = bplist_cache(bpl, blk);
+	if (err) {
+		mutex_exit(&bpl->bpl_lock);
+		return (err);
 	}
 
-	ASSERT3U(db->db_size, ==, 1ULL << bpl->bpl_blockshift);
-
-	dmu_buf_read(db);
-	bparray = db->db_data;
+	bparray = bpl->bpl_cached_dbuf->db_data;
 	*bp = bparray[off];
 	(*itorp)++;
 	mutex_exit(&bpl->bpl_lock);
 	return (0);
 }
 
-void
+int
 bplist_enqueue(bplist_t *bpl, blkptr_t *bp, dmu_tx_t *tx)
 {
 	uint64_t blk, off;
 	blkptr_t *bparray;
-	dmu_buf_t *db;
+	int err;
 
 	ASSERT(!BP_IS_HOLE(bp));
 	mutex_enter(&bpl->bpl_lock);
-	bplist_hold(bpl);
+	err = bplist_hold(bpl);
+	if (err)
+		return (err);
 
 	blk = bpl->bpl_phys->bpl_entries >> bpl->bpl_bpshift;
 	off = P2PHASE(bpl->bpl_phys->bpl_entries, 1ULL << bpl->bpl_bpshift);
-	db = bpl->bpl_cached_dbuf;
 
-	if (db == NULL || db->db_offset != (blk << bpl->bpl_blockshift)) {
-		if (db != NULL)
-			dmu_buf_rele(db);
-		bpl->bpl_cached_dbuf = db = dmu_buf_hold(bpl->bpl_mos,
-		    bpl->bpl_object, blk << bpl->bpl_blockshift);
+	err = bplist_cache(bpl, blk);
+	if (err) {
+		mutex_exit(&bpl->bpl_lock);
+		return (err);
 	}
 
-	ASSERT3U(db->db_size, ==, 1ULL << bpl->bpl_blockshift);
-
-	dmu_buf_will_dirty(db, tx);
-	bparray = db->db_data;
+	dmu_buf_will_dirty(bpl->bpl_cached_dbuf, tx);
+	bparray = bpl->bpl_cached_dbuf->db_data;
 	bparray[off] = *bp;
 
 	/* We never need the fill count. */
@@ -191,6 +212,8 @@
 	bpl->bpl_phys->bpl_entries++;
 	bpl->bpl_phys->bpl_bytes += BP_GET_ASIZE(bp);
 	mutex_exit(&bpl->bpl_lock);
+
+	return (0);
 }
 
 /*
@@ -218,7 +241,7 @@
 	while ((bpq = bpl->bpl_queue) != NULL) {
 		bpl->bpl_queue = bpq->bpq_next;
 		mutex_exit(&bpl->bpl_lock);
-		bplist_enqueue(bpl, &bpq->bpq_blk, tx);
+		VERIFY(0 == bplist_enqueue(bpl, &bpq->bpq_blk, tx));
 		kmem_free(bpq, sizeof (*bpq));
 		mutex_enter(&bpl->bpl_lock);
 	}
@@ -230,9 +253,10 @@
 {
 	mutex_enter(&bpl->bpl_lock);
 	ASSERT3P(bpl->bpl_queue, ==, NULL);
-	bplist_hold(bpl);
+	VERIFY(0 == bplist_hold(bpl));
 	dmu_buf_will_dirty(bpl->bpl_dbuf, tx);
-	dmu_free_range(bpl->bpl_mos, bpl->bpl_object, 0, -1ULL, tx);
+	VERIFY(0 == dmu_free_range(bpl->bpl_mos,
+	    bpl->bpl_object, 0, -1ULL, tx));
 	bpl->bpl_phys->bpl_entries = 0;
 	bpl->bpl_phys->bpl_bytes = 0;
 	mutex_exit(&bpl->bpl_lock);