diff options
author | Matthew Ahrens <Matthew.Ahrens@Sun.COM> | 2009-10-15 13:10:06 -0700 |
---|---|---|
committer | Matthew Ahrens <Matthew.Ahrens@Sun.COM> | 2009-10-15 13:10:06 -0700 |
commit | c33e334fd3eb2b3d91c4b9667d7a465b6924e8d3 (patch) | |
tree | fe5efee3002c1a9ffdf0a4fe1f2e6e1e0fee5608 /usr/src | |
parent | 975c32a05c38c6fa808592dd35fa6dba183ca077 (diff) | |
download | illumos-gate-c33e334fd3eb2b3d91c4b9667d7a465b6924e8d3.tar.gz |
6822816 assertion failed: zap_remove_int(ds_next_clones_obj) returns ENOENT
6891731 zfs_vdev_max_pending should be 10
6891726 ztest_fzap runs too much
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ztest/ztest.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dmu_objset.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_dataset.c | 38 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_pool.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_scrub.c | 27 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/vdev_queue.c | 2 |
6 files changed, 60 insertions, 18 deletions
diff --git a/usr/src/cmd/ztest/ztest.c b/usr/src/cmd/ztest/ztest.c index 730ad3eb2e..c1594c79e9 100644 --- a/usr/src/cmd/ztest/ztest.c +++ b/usr/src/cmd/ztest/ztest.c @@ -208,7 +208,7 @@ ztest_info_t ztest_info[] = { { ztest_dmu_object_alloc_free, 1, &zopt_always }, { ztest_dmu_commit_callbacks, 10, &zopt_always }, { ztest_zap, 30, &zopt_always }, - { ztest_fzap, 30, &zopt_always }, + { ztest_fzap, 1, &zopt_always }, { ztest_zap_parallel, 100, &zopt_always }, { ztest_dmu_read_write_zcopy, 1, &zopt_sometimes }, { ztest_dsl_prop_get_set, 1, &zopt_sometimes }, diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c index 55c122d6db..e59bae8d26 100644 --- a/usr/src/uts/common/fs/zfs/dmu_objset.c +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c @@ -1035,9 +1035,9 @@ do_userquota_callback(objset_t *os, dnode_phys_t *dnp, int64_t delta = DNODE_SIZE + DN_USED_BYTES(dnp); if (subtract) delta = -delta; - VERIFY(0 == zap_increment_int(os, DMU_USERUSED_OBJECT, + VERIFY3U(0, ==, zap_increment_int(os, DMU_USERUSED_OBJECT, user, delta, tx)); - VERIFY(0 == zap_increment_int(os, DMU_GROUPUSED_OBJECT, + VERIFY3U(0, ==, zap_increment_int(os, DMU_GROUPUSED_OBJECT, group, delta, tx)); } } diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c index aadf4cb051..59162d78d5 100644 --- a/usr/src/uts/common/fs/zfs/dsl_dataset.c +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c @@ -1458,6 +1458,33 @@ dsl_dataset_drain_refs(dsl_dataset_t *ds, void *tag) cv_destroy(&arg.cv); } +static void +remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj, dmu_tx_t *tx) +{ + objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; + uint64_t count; + int err; + + ASSERT(ds->ds_phys->ds_num_children >= 2); + err = zap_remove_int(mos, ds->ds_phys->ds_next_clones_obj, obj, tx); + /* + * The err should not be ENOENT, but a bug in a previous version + * of the code could cause upgrade_clones_cb() to not set + * ds_next_snap_obj when it should, leading to a missing entry. + * If we knew that the pool was created after + * SPA_VERSION_NEXT_CLONES, we could assert that it isn't + * ENOENT. However, at least we can check that we don't have + * too many entries in the next_clones_obj even after failing to + * remove this one. + */ + if (err != ENOENT) { + VERIFY3U(err, ==, 0); + } + ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj, + &count)); + ASSERT3U(count, <=, ds->ds_phys->ds_num_children - 2); +} + void dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) { @@ -1518,8 +1545,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) dmu_buf_will_dirty(ds_prev->ds_dbuf, tx); if (after_branch_point && ds_prev->ds_phys->ds_next_clones_obj != 0) { - VERIFY3U(0, ==, zap_remove_int(mos, - ds_prev->ds_phys->ds_next_clones_obj, obj, tx)); + remove_from_next_clones(ds_prev, obj, tx); if (ds->ds_phys->ds_next_snap_obj != 0) { VERIFY(0 == zap_add_int(mos, ds_prev->ds_phys->ds_next_clones_obj, @@ -1906,8 +1932,8 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ds->ds_prev->ds_phys->ds_creation_txg); ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj; } else if (next_clones_obj != 0) { - VERIFY3U(0, ==, zap_remove_int(mos, - next_clones_obj, dsphys->ds_next_snap_obj, tx)); + remove_from_next_clones(ds->ds_prev, + dsphys->ds_next_snap_obj, tx); VERIFY3U(0, ==, zap_add_int(mos, next_clones_obj, dsobj, tx)); } @@ -2513,9 +2539,7 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) /* change the origin's next clone */ if (origin_ds->ds_phys->ds_next_clones_obj) { - VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset, - origin_ds->ds_phys->ds_next_clones_obj, - origin_ds->ds_phys->ds_next_snap_obj, tx)); + remove_from_next_clones(origin_ds, snap->ds->ds_object, tx); VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset, origin_ds->ds_phys->ds_next_clones_obj, oldnext_obj, tx)); diff --git a/usr/src/uts/common/fs/zfs/dsl_pool.c b/usr/src/uts/common/fs/zfs/dsl_pool.c index 3ff8a9f5ae..f003ebe6f8 100644 --- a/usr/src/uts/common/fs/zfs/dsl_pool.c +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c @@ -608,6 +608,7 @@ upgrade_clones_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) ASSERT(ds->ds_phys->ds_prev_snap_obj == prev->ds_object); if (prev->ds_phys->ds_next_clones_obj == 0) { + dmu_buf_will_dirty(prev->ds_dbuf, tx); prev->ds_phys->ds_next_clones_obj = zap_create(dp->dp_meta_objset, DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx); @@ -627,8 +628,8 @@ dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx) ASSERT(dmu_tx_is_syncing(tx)); ASSERT(dp->dp_origin_snap != NULL); - (void) dmu_objset_find_spa(dp->dp_spa, NULL, upgrade_clones_cb, - tx, DS_FIND_CHILDREN); + VERIFY3U(0, ==, dmu_objset_find_spa(dp->dp_spa, NULL, upgrade_clones_cb, + tx, DS_FIND_CHILDREN)); } void diff --git a/usr/src/uts/common/fs/zfs/dsl_scrub.c b/usr/src/uts/common/fs/zfs/dsl_scrub.c index d3b11a7643..5ec5630cb4 100644 --- a/usr/src/uts/common/fs/zfs/dsl_scrub.c +++ b/usr/src/uts/common/fs/zfs/dsl_scrub.c @@ -698,17 +698,34 @@ scrub_visitds(dsl_pool_t *dp, uint64_t dsobj, dmu_tx_t *tx) ds->ds_phys->ds_next_snap_obj, tx) == 0); } if (ds->ds_phys->ds_num_children > 1) { - if (spa_version(dp->dp_spa) < SPA_VERSION_DSL_SCRUB) { + boolean_t usenext = B_FALSE; + if (ds->ds_phys->ds_next_clones_obj != 0) { + uint64_t count; + /* + * A bug in a previous version of the code could + * cause upgrade_clones_cb() to not set + * ds_next_snap_obj when it should, leading to a + * missing entry. Therefore we can only use the + * next_clones_obj when its count is correct. + */ + int err = zap_count(dp->dp_meta_objset, + ds->ds_phys->ds_next_clones_obj, &count); + if (err == 0 && + count == ds->ds_phys->ds_num_children - 1) + usenext = B_TRUE; + } + + if (usenext) { + VERIFY(zap_join(dp->dp_meta_objset, + ds->ds_phys->ds_next_clones_obj, + dp->dp_scrub_queue_obj, tx) == 0); + } else { struct enqueue_clones_arg eca; eca.tx = tx; eca.originobj = ds->ds_object; (void) dmu_objset_find_spa(ds->ds_dir->dd_pool->dp_spa, NULL, enqueue_clones_cb, &eca, DS_FIND_CHILDREN); - } else { - VERIFY(zap_join(dp->dp_meta_objset, - ds->ds_phys->ds_next_clones_obj, - dp->dp_scrub_queue_obj, tx) == 0); } } diff --git a/usr/src/uts/common/fs/zfs/vdev_queue.c b/usr/src/uts/common/fs/zfs/vdev_queue.c index 9867d09704..2f07284d4d 100644 --- a/usr/src/uts/common/fs/zfs/vdev_queue.c +++ b/usr/src/uts/common/fs/zfs/vdev_queue.c @@ -38,7 +38,7 @@ * of i/os pending to each device (before it starts ramping up to * max_pending). */ -int zfs_vdev_max_pending = 35; +int zfs_vdev_max_pending = 10; int zfs_vdev_min_pending = 4; /* deadline = pri + (lbolt >> time_shift) */ |