6584470 zdb needs to initialize the bpl_lock mutex
6583739 libzpool should check for properly initialized mutexes
6548010 unbalanced mutex_init/mutex_destroy issues in zfs
6502263 ZFS needs some more FreeBSD porting love
Contributed by Pawel Dawidek
6576827 multiple calls to spa_activate() can end up reinitializing all its mutexes
6576830 certain spa mutexes and condition variables need some love
--- a/usr/src/cmd/zdb/zdb.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/cmd/zdb/zdb.c Wed Aug 08 15:35:58 2007 -0700
@@ -812,9 +812,11 @@
if (dump_opt['d'] < 3)
return;
+ mutex_init(&bpl.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
VERIFY(0 == bplist_open(&bpl, mos, object));
if (bplist_empty(&bpl)) {
bplist_close(&bpl);
+ mutex_destroy(&bpl.bpl_lock);
return;
}
@@ -832,6 +834,7 @@
if (dump_opt['d'] < 5) {
bplist_close(&bpl);
+ mutex_destroy(&bpl.bpl_lock);
return;
}
@@ -847,6 +850,7 @@
}
bplist_close(&bpl);
+ mutex_destroy(&bpl.bpl_lock);
}
/*ARGSUSED*/
--- a/usr/src/lib/libzpool/common/kernel.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/lib/libzpool/common/kernel.c Wed Aug 08 15:35:58 2007 -0700
@@ -100,20 +100,24 @@
zmutex_init(kmutex_t *mp)
{
mp->m_owner = NULL;
+ mp->initialized = B_TRUE;
(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
}
void
zmutex_destroy(kmutex_t *mp)
{
+ ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner == NULL);
(void) _mutex_destroy(&(mp)->m_lock);
mp->m_owner = (void *)-1UL;
+ mp->initialized = B_FALSE;
}
void
mutex_enter(kmutex_t *mp)
{
+ ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
ASSERT(mp->m_owner != curthread);
VERIFY(mutex_lock(&mp->m_lock) == 0);
@@ -124,6 +128,7 @@
int
mutex_tryenter(kmutex_t *mp)
{
+ ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
if (0 == mutex_trylock(&mp->m_lock)) {
ASSERT(mp->m_owner == NULL);
@@ -137,6 +142,7 @@
void
mutex_exit(kmutex_t *mp)
{
+ ASSERT(mp->initialized == B_TRUE);
ASSERT(mutex_owner(mp) == curthread);
mp->m_owner = NULL;
VERIFY(mutex_unlock(&mp->m_lock) == 0);
@@ -145,6 +151,7 @@
void *
mutex_owner(kmutex_t *mp)
{
+ ASSERT(mp->initialized == B_TRUE);
return (mp->m_owner);
}
@@ -159,6 +166,7 @@
{
rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
rwlp->rw_owner = NULL;
+ rwlp->initialized = B_TRUE;
}
void
@@ -166,12 +174,14 @@
{
rwlock_destroy(&rwlp->rw_lock);
rwlp->rw_owner = (void *)-1UL;
+ rwlp->initialized = B_FALSE;
}
void
rw_enter(krwlock_t *rwlp, krw_t rw)
{
ASSERT(!RW_LOCK_HELD(rwlp));
+ ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
ASSERT(rwlp->rw_owner != curthread);
@@ -186,6 +196,7 @@
void
rw_exit(krwlock_t *rwlp)
{
+ ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
rwlp->rw_owner = NULL;
@@ -197,6 +208,7 @@
{
int rv;
+ ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
if (rw == RW_READER)
@@ -216,6 +228,7 @@
int
rw_tryupgrade(krwlock_t *rwlp)
{
+ ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
return (0);
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/lib/libzpool/common/sys/zfs_context.h Wed Aug 08 15:35:58 2007 -0700
@@ -198,8 +198,9 @@
* Mutexes
*/
typedef struct kmutex {
- void *m_owner;
- mutex_t m_lock;
+ void *m_owner;
+ boolean_t initialized;
+ mutex_t m_lock;
} kmutex_t;
#define MUTEX_DEFAULT USYNC_THREAD
@@ -228,6 +229,7 @@
*/
typedef struct krwlock {
void *rw_owner;
+ boolean_t initialized;
rwlock_t rw_lock;
} krwlock_t;
--- a/usr/src/lib/libzpool/common/taskq.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/lib/libzpool/common/taskq.c Wed Aug 08 15:35:58 2007 -0700
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -177,6 +176,9 @@
int t;
rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
+ mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
+ cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
tq->tq_flags = flags | TASKQ_ACTIVE;
tq->tq_active = nthreads;
tq->tq_nthreads = nthreads;
@@ -230,6 +232,9 @@
kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
rw_destroy(&tq->tq_threadlock);
+ mutex_destroy(&tq->tq_lock);
+ cv_destroy(&tq->tq_dispatch_cv);
+ cv_destroy(&tq->tq_wait_cv);
kmem_free(tq, sizeof (taskq_t));
}
--- a/usr/src/uts/common/fs/zfs/arc.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/arc.c Wed Aug 08 15:35:58 2007 -0700
@@ -584,6 +584,7 @@
bzero(buf, sizeof (arc_buf_hdr_t));
refcount_create(&buf->b_refcnt);
cv_init(&buf->b_cv, NULL, CV_DEFAULT, NULL);
+ mutex_init(&buf->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL);
return (0);
}
@@ -599,6 +600,7 @@
refcount_destroy(&buf->b_refcnt);
cv_destroy(&buf->b_cv);
+ mutex_destroy(&buf->b_freeze_lock);
}
/*
--- a/usr/src/uts/common/fs/zfs/dbuf.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dbuf.c Wed Aug 08 15:35:58 2007 -0700
@@ -1176,7 +1176,8 @@
} else {
ASSERT(db->db_buf != NULL);
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
- /* XXX - mutex and list destroy? */
+ mutex_destroy(&dr->dt.di.dr_mtx);
+ list_destroy(&dr->dt.di.dr_children);
}
kmem_free(dr, sizeof (dbuf_dirty_record_t));
@@ -2243,6 +2244,8 @@
>> (db->db_level * epbs), >=, db->db_blkid);
arc_set_callback(db->db_buf, dbuf_do_evict, db);
}
+ mutex_destroy(&dr->dt.di.dr_mtx);
+ list_destroy(&dr->dt.di.dr_children);
}
kmem_free(dr, sizeof (dbuf_dirty_record_t));
--- a/usr/src/uts/common/fs/zfs/spa.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/spa.c Wed Aug 08 15:35:58 2007 -0700
@@ -130,19 +130,6 @@
TASKQ_PREPOPULATE);
}
- rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL);
-
- rprw_init(&spa->spa_config_lock);
-
- mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_sync_bplist.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
-
list_create(&spa->spa_dirty_list, sizeof (vdev_t),
offsetof(vdev_t, vdev_dirty_node));
@@ -175,8 +162,6 @@
list_destroy(&spa->spa_dirty_list);
- rw_destroy(&spa->spa_traverse_lock);
-
for (t = 0; t < ZIO_TYPES; t++) {
taskq_destroy(spa->spa_zio_issue_taskq[t]);
taskq_destroy(spa->spa_zio_intr_taskq[t]);
--- a/usr/src/uts/common/fs/zfs/spa_misc.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c Wed Aug 08 15:35:58 2007 -0700
@@ -251,6 +251,22 @@
spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
+ rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL);
+
+ mutex_init(&spa->spa_uberblock_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_sync_bplist.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
+
+ cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&spa->spa_scrub_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&spa->spa_scrub_io_cv, NULL, CV_DEFAULT, NULL);
+
spa->spa_name = spa_strdup(name);
spa->spa_state = POOL_STATE_UNINITIALIZED;
spa->spa_freeze_txg = UINT64_MAX;
@@ -301,12 +317,19 @@
rprw_destroy(&spa->spa_config_lock);
- mutex_destroy(&spa->spa_sync_bplist.bpl_lock);
- mutex_destroy(&spa->spa_errlist_lock);
+ rw_destroy(&spa->spa_traverse_lock);
+
+ cv_destroy(&spa->spa_async_cv);
+ cv_destroy(&spa->spa_scrub_cv);
+ cv_destroy(&spa->spa_scrub_io_cv);
+
+ mutex_destroy(&spa->spa_uberblock_lock);
+ mutex_destroy(&spa->spa_async_lock);
+ mutex_destroy(&spa->spa_config_cache_lock);
+ mutex_destroy(&spa->spa_scrub_lock);
mutex_destroy(&spa->spa_errlog_lock);
- mutex_destroy(&spa->spa_scrub_lock);
- mutex_destroy(&spa->spa_config_cache_lock);
- mutex_destroy(&spa->spa_async_lock);
+ mutex_destroy(&spa->spa_errlist_lock);
+ mutex_destroy(&spa->spa_sync_bplist.bpl_lock);
mutex_destroy(&spa->spa_history_lock);
mutex_destroy(&spa->spa_props_lock);
@@ -1033,6 +1056,7 @@
spa_init(int mode)
{
mutex_init(&spa_namespace_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&spa_spare_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&spa_namespace_cv, NULL, CV_DEFAULT, NULL);
avl_create(&spa_namespace_avl, spa_name_compare, sizeof (spa_t),
@@ -1068,6 +1092,7 @@
cv_destroy(&spa_namespace_cv);
mutex_destroy(&spa_namespace_lock);
+ mutex_destroy(&spa_spare_lock);
}
/*
--- a/usr/src/uts/common/fs/zfs/zap_micro.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zap_micro.c Wed Aug 08 15:35:58 2007 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -208,6 +208,10 @@
winner = dmu_buf_set_user(db, zap, &zap->zap_m.zap_phys, zap_evict);
if (winner != NULL) {
+ rw_exit(&zap->zap_rwlock);
+ rw_destroy(&zap->zap_rwlock);
+ if (!zap->zap_ismicro)
+ mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
kmem_free(zap, sizeof (zap_t));
return (winner);
}
@@ -465,6 +469,8 @@
if (zap->zap_ismicro)
mze_destroy(zap);
+ else
+ mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
kmem_free(zap, sizeof (zap_t));
}
--- a/usr/src/uts/common/fs/zfs/zfs_fm.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zfs_fm.c Wed Aug 08 15:35:58 2007 -0700
@@ -223,7 +223,7 @@
if (pvd->vdev_path)
fm_payload_set(ereport,
FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH,
- DATA_TYPE_STRING, vd->vdev_path, NULL);
+ DATA_TYPE_STRING, pvd->vdev_path, NULL);
if (pvd->vdev_devid)
fm_payload_set(ereport,
FM_EREPORT_PAYLOAD_ZFS_PARENT_DEVID,
@@ -263,14 +263,11 @@
*/
if (zio->io_logical != NULL)
fm_payload_set(ereport,
- FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJSET,
- DATA_TYPE_UINT64,
- zio->io_logical->io_bookmark.zb_objset,
FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJECT,
DATA_TYPE_UINT64,
zio->io_logical->io_bookmark.zb_object,
FM_EREPORT_PAYLOAD_ZFS_ZIO_LEVEL,
- DATA_TYPE_INT32,
+ DATA_TYPE_INT64,
zio->io_logical->io_bookmark.zb_level,
FM_EREPORT_PAYLOAD_ZFS_ZIO_BLKID,
DATA_TYPE_UINT64,
--- a/usr/src/uts/common/fs/zfs/zfs_rlock.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zfs_rlock.c Wed Aug 08 15:35:58 2007 -0700
@@ -472,10 +472,14 @@
*/
if (remove->r_cnt == 1) {
avl_remove(tree, remove);
- if (remove->r_write_wanted)
+ if (remove->r_write_wanted) {
cv_broadcast(&remove->r_wr_cv);
- if (remove->r_read_wanted)
+ cv_destroy(&remove->r_wr_cv);
+ }
+ if (remove->r_read_wanted) {
cv_broadcast(&remove->r_rd_cv);
+ cv_destroy(&remove->r_rd_cv);
+ }
} else {
ASSERT3U(remove->r_cnt, ==, 0);
ASSERT3U(remove->r_write_wanted, ==, 0);
@@ -501,10 +505,14 @@
rl->r_cnt--;
if (rl->r_cnt == 0) {
avl_remove(tree, rl);
- if (rl->r_write_wanted)
+ if (rl->r_write_wanted) {
cv_broadcast(&rl->r_wr_cv);
- if (rl->r_read_wanted)
+ cv_destroy(&rl->r_wr_cv);
+ }
+ if (rl->r_read_wanted) {
cv_broadcast(&rl->r_rd_cv);
+ cv_destroy(&rl->r_rd_cv);
+ }
kmem_free(rl, sizeof (rl_t));
}
}
@@ -529,10 +537,14 @@
/* writer locks can't be shared or split */
avl_remove(&zp->z_range_avl, rl);
mutex_exit(&zp->z_range_lock);
- if (rl->r_write_wanted)
+ if (rl->r_write_wanted) {
cv_broadcast(&rl->r_wr_cv);
- if (rl->r_read_wanted)
+ cv_destroy(&rl->r_wr_cv);
+ }
+ if (rl->r_read_wanted) {
cv_broadcast(&rl->r_rd_cv);
+ cv_destroy(&rl->r_rd_cv);
+ }
kmem_free(rl, sizeof (rl_t));
} else {
/*
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c Wed Aug 08 15:35:58 2007 -0700
@@ -628,6 +628,10 @@
if (error) {
if (zfsvfs->z_os)
dmu_objset_close(zfsvfs->z_os);
+ mutex_destroy(&zfsvfs->z_znodes_lock);
+ list_destroy(&zfsvfs->z_all_znodes);
+ rw_destroy(&zfsvfs->z_unmount_lock);
+ rw_destroy(&zfsvfs->z_unmount_inactive_lock);
kmem_free(zfsvfs, sizeof (zfsvfs_t));
} else {
atomic_add_32(&zfs_active_fs_count, 1);
@@ -1226,8 +1230,13 @@
zfs_freevfs(vfs_t *vfsp)
{
zfsvfs_t *zfsvfs = vfsp->vfs_data;
+ int i;
+
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_destroy(&zfsvfs->z_hold_mtx[i]);
mutex_destroy(&zfsvfs->z_znodes_lock);
+ list_destroy(&zfsvfs->z_all_znodes);
rw_destroy(&zfsvfs->z_unmount_lock);
rw_destroy(&zfsvfs->z_unmount_inactive_lock);
kmem_free(zfsvfs, sizeof (zfsvfs_t));
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zfs_znode.c Wed Aug 08 15:35:58 2007 -0700
@@ -124,6 +124,7 @@
rw_destroy(&zp->z_name_lock);
mutex_destroy(&zp->z_acl_lock);
avl_destroy(&zp->z_range_avl);
+ mutex_destroy(&zp->z_range_lock);
ASSERT(zp->z_dbuf_held == 0);
ASSERT(ZTOV(zp)->v_count == 0);
@@ -304,6 +305,11 @@
return (error);
ASSERT(zfsvfs->z_root != 0);
+ error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
+ &zfsvfs->z_unlinkedobj);
+ if (error)
+ return (error);
+
/*
* Initialize zget mutex's
*/
@@ -311,15 +317,17 @@
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
error = zfs_zget(zfsvfs, zfsvfs->z_root, zpp);
- if (error)
+ if (error) {
+ /*
+ * On error, we destroy the mutexes here since it's not
+ * possible for the caller to determine if the mutexes were
+ * initialized properly.
+ */
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_destroy(&zfsvfs->z_hold_mtx[i]);
return (error);
+ }
ASSERT3U((*zpp)->z_id, ==, zfsvfs->z_root);
-
- error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
- &zfsvfs->z_unlinkedobj);
- if (error)
- return (error);
-
return (0);
}
--- a/usr/src/uts/common/fs/zfs/zio.c Wed Aug 08 12:41:08 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/zio.c Wed Aug 08 15:35:58 2007 -0700
@@ -334,6 +334,7 @@
if (pio != NULL)
zio->io_flags |= (pio->io_flags & ZIO_FLAG_METADATA);
mutex_init(&zio->io_lock, NULL, MUTEX_DEFAULT, NULL);
+ cv_init(&zio->io_cv, NULL, CV_DEFAULT, NULL);
zio_push_transform(zio, data, size, size);
/*
@@ -761,6 +762,7 @@
error = zio->io_error;
mutex_destroy(&zio->io_lock);
+ cv_destroy(&zio->io_cv);
kmem_cache_free(zio_cache, zio);
return (error);
@@ -954,6 +956,8 @@
cv_broadcast(&zio->io_cv);
mutex_exit(&zio->io_lock);
} else {
+ mutex_destroy(&zio->io_lock);
+ cv_destroy(&zio->io_cv);
kmem_cache_free(zio_cache, zio);
}
}