Mercurial > illumos > illumos-gate
changeset 13780:6da32a929222
3100 zvol rename fails with EBUSY when dirty
3103 zfs mdb module may get wrong refcount struct
Reviewed by: Christopher Siden <chris.siden@delphix.com>
Reviewed by: Adam H. Leventhal <ahl@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Eric Schrock <eric.schrock@delphix.com>
author | Matthew Ahrens <mahrens@delphix.com> |
---|---|
date | Fri, 24 Aug 2012 07:12:46 -0700 |
parents | bf40125f4b37 |
children | 64a1ab954737 |
files | usr/src/cmd/mdb/common/modules/zfs/zfs.c usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/uts/common/fs/zfs/dmu_objset.c usr/src/uts/common/fs/zfs/dsl_dataset.c usr/src/uts/common/fs/zfs/dsl_dir.c usr/src/uts/common/fs/zfs/dsl_pool.c usr/src/uts/common/fs/zfs/sys/dmu_objset.h usr/src/uts/common/fs/zfs/sys/dsl_dataset.h usr/src/uts/common/fs/zfs/zfs_vfsops.c usr/src/uts/common/fs/zfs/zvol.c |
diffstat | 10 files changed, 34 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c Fri Aug 24 07:12:46 2012 -0700 @@ -2338,7 +2338,14 @@ return (DCMD_USAGE); if (!gotid) { - if (mdb_ctf_lookup_by_name("struct refcount", &rc_id) == -1) { + /* + * The refcount structure is different when compiled debug + * vs nondebug. Therefore, we want to make sure we get the + * refcount definition from the ZFS module, in case it has + * been compiled debug but genunix is nondebug. + */ + if (mdb_ctf_lookup_by_name("struct " ZFS_OBJ_NAME "`refcount", + &rc_id) == -1) { mdb_warn("couldn't find struct refcount"); return (DCMD_ERR); }
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Fri Aug 24 07:12:46 2012 -0700 @@ -3511,7 +3511,7 @@ zhp->zfs_type == ZFS_TYPE_VOLUME); /* - * Destroy all recent snapshots and its dependends. + * Destroy all recent snapshots and their dependents. */ cb.cb_force = force; cb.cb_target = snap->zfs_name;
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c Fri Aug 24 07:12:46 2012 -0700 @@ -1236,15 +1236,6 @@ !list_is_empty(&os->os_free_dnodes[txg & TXG_MASK])); } -boolean_t -dmu_objset_is_dirty_anywhere(objset_t *os) -{ - for (int t = 0; t < TXG_SIZE; t++) - if (dmu_objset_is_dirty(os, t)) - return (B_TRUE); - return (B_FALSE); -} - static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES]; void
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Fri Aug 24 07:12:46 2012 -0700 @@ -1210,6 +1210,17 @@ } } +boolean_t +dsl_dataset_is_dirty(dsl_dataset_t *ds) +{ + for (int t = 0; t < TXG_SIZE; t++) { + if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets, + ds, t)) + return (B_TRUE); + } + return (B_FALSE); +} + /* * The unique space in the head dataset can be calculated by subtracting * the space used in the most recent snapshot, that is still being used @@ -3432,9 +3443,6 @@ if (ds->ds_quota != effective_value) { dmu_buf_will_dirty(ds->ds_dbuf, tx); ds->ds_quota = effective_value; - - spa_history_log_internal_ds(ds, "set refquota", tx, - "refquota=%lld", (longlong_t)ds->ds_quota); } } @@ -3538,9 +3546,6 @@ dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx); mutex_exit(&ds->ds_dir->dd_lock); - - spa_history_log_internal_ds(ds, "set refreservation", tx, - "refreservation=%lld", (longlong_t)effective_value); } int
--- a/usr/src/uts/common/fs/zfs/dsl_dir.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/dsl_dir.c Fri Aug 24 07:12:46 2012 -0700 @@ -1050,9 +1050,6 @@ mutex_enter(&dd->dd_lock); dd->dd_phys->dd_quota = effective_value; mutex_exit(&dd->dd_lock); - - spa_history_log_internal_dd(dd, "set quota", tx, - "quota=%lld", (longlong_t)effective_value); } int @@ -1172,9 +1169,6 @@ DSL_PROP_CHECK_PREDICTION(dd, psa); dsl_dir_set_reservation_sync_impl(dd, value, tx); - - spa_history_log_internal_dd(dd, "set reservation", tx, - "reservation=%lld", (longlong_t)value); } int
--- a/usr/src/uts/common/fs/zfs/dsl_pool.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c Fri Aug 24 07:12:46 2012 -0700 @@ -126,8 +126,6 @@ dsl_dataset_t *ds; uint64_t obj; - ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset)); - rw_enter(&dp->dp_config_rwlock, RW_WRITER); err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
--- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Fri Aug 24 07:12:46 2012 -0700 @@ -152,7 +152,6 @@ /* called from dsl */ void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx); boolean_t dmu_objset_is_dirty(objset_t *os, uint64_t txg); -boolean_t dmu_objset_is_dirty_anywhere(objset_t *os); objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx); int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h Fri Aug 24 07:12:46 2012 -0700 @@ -262,6 +262,7 @@ uint64_t *usedp, uint64_t *compp, uint64_t *uncompp); int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp); +boolean_t dsl_dataset_is_dirty(dsl_dataset_t *ds); int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c Fri Aug 24 07:12:46 2012 -0700 @@ -1831,9 +1831,9 @@ /* * Evict cached data */ - if (dmu_objset_is_dirty_anywhere(zfsvfs->z_os)) - if (!(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY)) - txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0); + if (dsl_dataset_is_dirty(dmu_objset_ds(zfsvfs->z_os)) && + !(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY)) + txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0); (void) dmu_objset_evict_dbufs(zfsvfs->z_os); return (0);
--- a/usr/src/uts/common/fs/zfs/zvol.c Sun Jul 08 03:19:56 2012 +0100 +++ b/usr/src/uts/common/fs/zfs/zvol.c Fri Aug 24 07:12:46 2012 -0700 @@ -641,8 +641,18 @@ { zil_close(zv->zv_zilog); zv->zv_zilog = NULL; + dmu_buf_rele(zv->zv_dbuf, zvol_tag); zv->zv_dbuf = NULL; + + /* + * Evict cached data + */ + if (dsl_dataset_is_dirty(dmu_objset_ds(zv->zv_objset)) && + !(zv->zv_flags & ZVOL_RDONLY)) + txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0); + (void) dmu_objset_evict_dbufs(zv->zv_objset); + dmu_objset_disown(zv->zv_objset, zvol_tag); zv->zv_objset = NULL; }