From d4a72f23863382bdf6d0ae33196f5b5decbc48fd Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Wed, 15 Nov 2017 20:27:01 -0500 Subject: Sequential scrub and resilvers Currently, scrubs and resilvers can take an extremely long time to complete. This is largely due to the fact that zfs scans process pools in logical order, as determined by each block's bookmark. This makes sense from a simplicity perspective, but blocks in zfs are often scattered randomly across disks, particularly due to zfs's copy-on-write mechanisms. This patch improves performance by splitting scrubs and resilvers into a metadata scanning phase and an IO issuing phase. The metadata scan reads through the structure of the pool and gathers an in-memory queue of I/Os, sorted by size and offset on disk. The issuing phase will then issue the scrub I/Os as sequentially as possible, greatly improving performance. This patch also updates and cleans up some of the scan code which has not been updated in several years. Reviewed-by: Brian Behlendorf Authored-by: Saso Kiselkov Authored-by: Alek Pinchuk Authored-by: Tom Caputi Signed-off-by: Tom Caputi Closes #3625 Closes #6256 --- cmd/zdb/zdb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'cmd/zdb/zdb.c') diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index e45b7743a..cc4f22a9e 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -2226,8 +2226,6 @@ dump_dir(objset_t *os) max_slot_used = object + dnode_slots - 1; } - ASSERT3U(object_count, ==, usedobjs); - (void) printf("\n"); (void) printf(" Dnode slots:\n"); @@ -2245,6 +2243,8 @@ dump_dir(objset_t *os) (void) fprintf(stderr, "dmu_object_next() = %d\n", error); abort(); } + + ASSERT3U(object_count, ==, usedobjs); } static void @@ -3089,7 +3089,7 @@ zdb_blkptr_done(zio_t *zio) abd_free(zio->io_abd); mutex_enter(&spa->spa_scrub_lock); - spa->spa_scrub_inflight--; + spa->spa_load_verify_ios--; cv_broadcast(&spa->spa_scrub_io_cv); if (ioerr && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { @@ -3160,9 +3160,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, flags |= ZIO_FLAG_SPECULATIVE; mutex_enter(&spa->spa_scrub_lock); - while (spa->spa_scrub_inflight > max_inflight) + while (spa->spa_load_verify_ios > max_inflight) cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); - spa->spa_scrub_inflight++; + spa->spa_load_verify_ios++; mutex_exit(&spa->spa_scrub_lock); zio_nowait(zio_read(NULL, spa, bp, abd, size, -- cgit v1.2.3