Author: avg
Date: Thu Nov 21 13:46:16 2019
New Revision: 354949
URL: https://svnweb.freebsd.org/changeset/base/354949

Log:
  10405 Implement ZFS sorted scans
  
  illumos/illumos-gate@a3874b8b1fe5103fc1f961609557c0587435fec0
  
https://github.com/illumos/illumos-gate/commit/a3874b8b1fe5103fc1f961609557c0587435fec0
  
  https://www.illumos.org/issues/10405
    The original implementation is: 
https://github.com/zfsonlinux/zfs/commit/d4a72f23863382bdf6d0ae33196f5b5decbc48fd
  
  Author: Toomas Soome <tso...@me.com>

Modified:
  vendor/illumos/dist/cmd/zdb/zdb.c
  vendor/illumos/dist/cmd/zpool/zpool_main.c
  vendor/illumos/dist/cmd/ztest/ztest.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_status.c

Changes in other areas also in this revision:
Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dbuf.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/ddt.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_objset.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/metaslab.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/range_tree.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_pool.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_scan.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/range_tree.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/spa_impl.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/vdev.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/vdev_impl.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zio.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_disk.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_file.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_indirect.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_mirror.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_missing.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_queue.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_raidz.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev_root.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c
  vendor-sys/illumos/dist/uts/common/sys/fs/zfs.h
  vendor-sys/illumos/dist/uts/common/sys/taskq.h

Modified: vendor/illumos/dist/cmd/zdb/zdb.c
==============================================================================
--- vendor/illumos/dist/cmd/zdb/zdb.c   Thu Nov 21 13:35:43 2019        
(r354948)
+++ vendor/illumos/dist/cmd/zdb/zdb.c   Thu Nov 21 13:46:16 2019        
(r354949)
@@ -2384,8 +2384,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");
@@ -2408,6 +2406,8 @@ dump_dir(objset_t *os)
                    leaked_objects);
                leaked_objects = 0;
        }
+
+       ASSERT3U(object_count, ==, usedobjs);
 }
 
 static void
@@ -2975,7 +2975,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)) {
@@ -3046,9 +3046,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr
                        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,

Modified: vendor/illumos/dist/cmd/zpool/zpool_main.c
==============================================================================
--- vendor/illumos/dist/cmd/zpool/zpool_main.c  Thu Nov 21 13:35:43 2019        
(r354948)
+++ vendor/illumos/dist/cmd/zpool/zpool_main.c  Thu Nov 21 13:46:16 2019        
(r354949)
@@ -1688,7 +1688,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata
        (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
            (uint64_t **)&ps, &c);
 
-       if (ps && ps->pss_state == DSS_SCANNING &&
+       if (ps != NULL && ps->pss_state == DSS_SCANNING &&
            vs->vs_scan_processed != 0 && children == 0) {
                (void) printf(gettext("  (%s)"),
                    (ps->pss_func == POOL_SCAN_RESILVER) ?
@@ -4707,11 +4707,13 @@ static void
 print_scan_status(pool_scan_stat_t *ps)
 {
        time_t start, end, pause;
-       uint64_t elapsed, mins_left, hours_left;
-       uint64_t pass_exam, examined, total;
-       uint_t rate;
+       uint64_t total_secs_left;
+       uint64_t elapsed, secs_left, mins_left, hours_left, days_left;
+       uint64_t pass_scanned, scanned, pass_issued, issued, total;
+       uint_t scan_rate, issue_rate;
        double fraction_done;
-       char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
+       char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7];
+       char srate_buf[7], irate_buf[7];
 
        (void) printf(gettext("  scan: "));
 
@@ -4725,30 +4727,37 @@ print_scan_status(pool_scan_stat_t *ps)
        start = ps->pss_start_time;
        end = ps->pss_end_time;
        pause = ps->pss_pass_scrub_pause;
+
        zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
 
        assert(ps->pss_func == POOL_SCAN_SCRUB ||
            ps->pss_func == POOL_SCAN_RESILVER);
+
        /*
         * Scan is finished or canceled.
         */
        if (ps->pss_state == DSS_FINISHED) {
-               uint64_t minutes_taken = (end - start) / 60;
-               char *fmt = NULL;
+               total_secs_left = end - start;
+               days_left = total_secs_left / 60 / 60 / 24;
+               hours_left = (total_secs_left / 60 / 60) % 24;
+               mins_left = (total_secs_left / 60) % 60;
+               secs_left = (total_secs_left % 60);
 
                if (ps->pss_func == POOL_SCAN_SCRUB) {
-                       fmt = gettext("scrub repaired %s in %lluh%um with "
-                           "%llu errors on %s");
+                       (void) printf(gettext("scrub repaired %s "
+                           "in %llu days %02llu:%02llu:%02llu "
+                           "with %llu errors on %s"), processed_buf,
+                           (u_longlong_t)days_left, (u_longlong_t)hours_left,
+                           (u_longlong_t)mins_left, (u_longlong_t)secs_left,
+                           (u_longlong_t)ps->pss_errors, ctime(&end));
                } else if (ps->pss_func == POOL_SCAN_RESILVER) {
-                       fmt = gettext("resilvered %s in %lluh%um with "
-                           "%llu errors on %s");
+                       (void) printf(gettext("resilvered %s "
+                           "in %llu days %02llu:%02llu:%02llu "
+                           "with %llu errors on %s"), processed_buf,
+                           (u_longlong_t)days_left, (u_longlong_t)hours_left,
+                           (u_longlong_t)mins_left, (u_longlong_t)secs_left,
+                           (u_longlong_t)ps->pss_errors, ctime(&end));
                }
-               /* LINTED */
-               (void) printf(fmt, processed_buf,
-                   (u_longlong_t)(minutes_taken / 60),
-                   (uint_t)(minutes_taken % 60),
-                   (u_longlong_t)ps->pss_errors,
-                   ctime((time_t *)&end));
                return;
        } else if (ps->pss_state == DSS_CANCELED) {
                if (ps->pss_func == POOL_SCAN_SCRUB) {
@@ -4763,19 +4772,15 @@ print_scan_status(pool_scan_stat_t *ps)
 
        assert(ps->pss_state == DSS_SCANNING);
 
-       /*
-        * Scan is in progress.
-        */
+       /* Scan is in progress. Resilvers can't be paused. */
        if (ps->pss_func == POOL_SCAN_SCRUB) {
                if (pause == 0) {
                        (void) printf(gettext("scrub in progress since %s"),
                            ctime(&start));
                } else {
-                       char buf[32];
-                       struct tm *p = localtime(&pause);
-                       (void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
-                       (void) printf(gettext("scrub paused since %s\n"), buf);
-                       (void) printf(gettext("\tscrub started on   %s"),
+                       (void) printf(gettext("scrub paused since %s"),
+                           ctime(&pause));
+                       (void) printf(gettext("\tscrub started on %s"),
                            ctime(&start));
                }
        } else if (ps->pss_func == POOL_SCAN_RESILVER) {
@@ -4783,49 +4788,67 @@ print_scan_status(pool_scan_stat_t *ps)
                    ctime(&start));
        }
 
-       examined = ps->pss_examined ? ps->pss_examined : 1;
+       scanned = ps->pss_examined;
+       pass_scanned = ps->pss_pass_exam;
+       issued = ps->pss_issued;
+       pass_issued = ps->pss_pass_issued;
        total = ps->pss_to_examine;
-       fraction_done = (double)examined / total;
 
-       /* elapsed time for this pass */
+       /* we are only done with a block once we have issued the IO for it  */
+       fraction_done = (double)issued / total;
+
+       /* elapsed time for this pass, rounding up to 1 if it's 0 */
        elapsed = time(NULL) - ps->pss_pass_start;
        elapsed -= ps->pss_pass_scrub_spent_paused;
-       elapsed = elapsed ? elapsed : 1;
-       pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
-       rate = pass_exam / elapsed;
-       rate = rate ? rate : 1;
-       mins_left = ((total - examined) / rate) / 60;
-       hours_left = mins_left / 60;
+       elapsed = (elapsed != 0) ? elapsed : 1;
 
-       zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
+       scan_rate = pass_scanned / elapsed;
+       issue_rate = pass_issued / elapsed;
+       total_secs_left = (issue_rate != 0) ?
+           ((total - issued) / issue_rate) : UINT64_MAX;
+
+       days_left = total_secs_left / 60 / 60 / 24;
+       hours_left = (total_secs_left / 60 / 60) % 24;
+       mins_left = (total_secs_left / 60) % 60;
+       secs_left = (total_secs_left % 60);
+
+       /* format all of the numbers we will be reporting */
+       zfs_nicenum(scanned, scanned_buf, sizeof (scanned_buf));
+       zfs_nicenum(issued, issued_buf, sizeof (issued_buf));
        zfs_nicenum(total, total_buf, sizeof (total_buf));
+       zfs_nicenum(scan_rate, srate_buf, sizeof (srate_buf));
+       zfs_nicenum(issue_rate, irate_buf, sizeof (irate_buf));
 
-       /*
-        * do not print estimated time if hours_left is more than 30 days
-        * or we have a paused scrub
-        */
+       /* do not print estimated time if we have a paused scrub */
        if (pause == 0) {
-               zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
-               (void) printf(gettext("\t%s scanned out of %s at %s/s"),
-                   examined_buf, total_buf, rate_buf);
-               if (hours_left < (30 * 24)) {
-                       (void) printf(gettext(", %lluh%um to go\n"),
-                           (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
-               } else {
-                       (void) printf(gettext(
-                           ", (scan is slow, no estimated time)\n"));
-               }
+               (void) printf(gettext("\t%s scanned at %s/s, "
+                   "%s issued at %s/s, %s total\n"),
+                   scanned_buf, srate_buf, issued_buf, irate_buf, total_buf);
        } else {
-               (void) printf(gettext("\t%s scanned out of %s\n"),
-                   examined_buf, total_buf);
+               (void) printf(gettext("\t%s scanned, %s issued, %s total\n"),
+                   scanned_buf, issued_buf, total_buf);
        }
 
        if (ps->pss_func == POOL_SCAN_RESILVER) {
-               (void) printf(gettext("    %s resilvered, %.2f%% done\n"),
+               (void) printf(gettext("\t%s resilvered, %.2f%% done"),
                    processed_buf, 100 * fraction_done);
        } else if (ps->pss_func == POOL_SCAN_SCRUB) {
-               (void) printf(gettext("    %s repaired, %.2f%% done\n"),
+               (void) printf(gettext("\t%s repaired, %.2f%% done"),
                    processed_buf, 100 * fraction_done);
+       }
+
+       if (pause == 0) {
+               if (issue_rate >= 10 * 1024 * 1024) {
+                       (void) printf(gettext(", %llu days "
+                           "%02llu:%02llu:%02llu to go\n"),
+                           (u_longlong_t)days_left, (u_longlong_t)hours_left,
+                           (u_longlong_t)mins_left, (u_longlong_t)secs_left);
+               } else {
+                       (void) printf(gettext(", no estimated "
+                           "completion time\n"));
+               }
+       } else {
+               (void) printf(gettext("\n"));
        }
 }
 

Modified: vendor/illumos/dist/cmd/ztest/ztest.c
==============================================================================
--- vendor/illumos/dist/cmd/ztest/ztest.c       Thu Nov 21 13:35:43 2019        
(r354948)
+++ vendor/illumos/dist/cmd/ztest/ztest.c       Thu Nov 21 13:46:16 2019        
(r354949)
@@ -397,15 +397,15 @@ ztest_info_t ztest_info[] = {
        { ztest_fzap,                           1,      &zopt_sometimes },
        { ztest_dmu_snapshot_create_destroy,    1,      &zopt_sometimes },
        { ztest_spa_create_destroy,             1,      &zopt_sometimes },
-       { ztest_fault_inject,                   1,      &zopt_sometimes },
+       { ztest_fault_inject,                   1,      &zopt_incessant },
        { ztest_ddt_repair,                     1,      &zopt_sometimes },
        { ztest_dmu_snapshot_hold,              1,      &zopt_sometimes },
        { ztest_mmp_enable_disable,             1,      &zopt_sometimes },
        { ztest_reguid,                         1,      &zopt_rarely    },
-       { ztest_scrub,                          1,      &zopt_rarely    },
+       { ztest_scrub,                          1,      &zopt_often     },
        { ztest_spa_upgrade,                    1,      &zopt_rarely    },
        { ztest_dsl_dataset_promote_busy,       1,      &zopt_rarely    },
-       { ztest_vdev_attach_detach,             1,      &zopt_sometimes },
+       { ztest_vdev_attach_detach,             1,      &zopt_incessant },
        { ztest_vdev_LUN_growth,                1,      &zopt_rarely    },
        { ztest_vdev_add_remove,                1,
            &ztest_opts.zo_vdevtime                             },

Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_status.c
==============================================================================
--- vendor/illumos/dist/lib/libzfs/common/libzfs_status.c       Thu Nov 21 
13:35:43 2019        (r354948)
+++ vendor/illumos/dist/lib/libzfs/common/libzfs_status.c       Thu Nov 21 
13:46:16 2019        (r354949)
@@ -225,7 +225,7 @@ check_status(nvlist_t *config, boolean_t isimport)
         */
        (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
            (uint64_t **)&ps, &psc);
-       if (ps && ps->pss_func == POOL_SCAN_RESILVER &&
+       if (ps != NULL && ps->pss_func == POOL_SCAN_RESILVER &&
            ps->pss_state == DSS_SCANNING)
                return (ZPOOL_STATUS_RESILVERING);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to