# HG changeset patch # User gw25295 # Date 1186612558 25200 # Node ID 41ec732c6d9fc141be2c6cdccf2f6980f93bd061 # Parent 956da15b66108654feaa78d09f9d5b435824e569 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 diff -r 956da15b6610 -r 41ec732c6d9f usr/src/cmd/zdb/zdb.c --- 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*/ diff -r 956da15b6610 -r 41ec732c6d9f usr/src/lib/libzpool/common/kernel.c --- 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); diff -r 956da15b6610 -r 41ec732c6d9f usr/src/lib/libzpool/common/sys/zfs_context.h --- 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; diff -r 956da15b6610 -r 41ec732c6d9f usr/src/lib/libzpool/common/taskq.c --- 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)); } diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/arc.c --- 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); } /* diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/dbuf.c --- 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)); diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/spa.c --- 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]); diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/spa_misc.c --- 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); } /* diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zap_micro.c --- 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)); } diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zfs_fm.c --- 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, diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zfs_rlock.c --- 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 { /* diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zfs_vfsops.c --- 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)); diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zfs_znode.c --- 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); } diff -r 956da15b6610 -r 41ec732c6d9f usr/src/uts/common/fs/zfs/zio.c --- 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); } }