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