summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMatthew Ahrens <Matthew.Ahrens@Sun.COM>2009-10-15 13:10:06 -0700
committerMatthew Ahrens <Matthew.Ahrens@Sun.COM>2009-10-15 13:10:06 -0700
commitc33e334fd3eb2b3d91c4b9667d7a465b6924e8d3 (patch)
treefe5efee3002c1a9ffdf0a4fe1f2e6e1e0fee5608 /usr/src
parent975c32a05c38c6fa808592dd35fa6dba183ca077 (diff)
downloadillumos-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.c2
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_objset.c4
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_dataset.c38
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_pool.c5
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_scrub.c27
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_queue.c2
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) */