Author: mav
Date: Mon Mar 21 00:15:41 2016
New Revision: 297110
URL: https://svnweb.freebsd.org/changeset/base/297110

Log:
  MFC r296514: MFV r296513:
  6450 scrub/resilver unnecessarily traverses snapshots created after the
  scrub started
  
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Reviewed by: Prakash Surya <prakash.su...@delphix.com>
  Reviewed by: Richard Elling <richard.ell...@richardelling.com>
  Approved by: Richard Lowe <richl...@richlowe.net>
  Author: Matthew Ahrens <mahr...@delphix.com>
  
  illumos/illumos-gate@38d61036746e2273cc18f6698392e1e29f87d1bf

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Mon Mar 
21 00:14:30 2016        (r297109)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Mon Mar 
21 00:15:41 2016        (r297110)
@@ -856,7 +856,16 @@ dsl_scan_ds_destroyed(dsl_dataset_t *ds,
 
        if (scn->scn_phys.scn_bookmark.zb_objset == ds->ds_object) {
                if (ds->ds_is_snapshot) {
-                       /* Note, scn_cur_{min,max}_txg stays the same. */
+                       /*
+                        * Note:
+                        *  - scn_cur_{min,max}_txg stays the same.
+                        *  - Setting the flag is not really necessary if
+                        *    scn_cur_max_txg == scn_max_txg, because there
+                        *    is nothing after this snapshot that we care
+                        *    about.  However, we set it anyway and then
+                        *    ignore it when we retraverse it in
+                        *    dsl_scan_visitds().
+                        */
                        scn->scn_phys.scn_bookmark.zb_objset =
                            dsl_dataset_phys(ds)->ds_next_snap_obj;
                        zfs_dbgmsg("destroying ds %llu; currently traversing; "
@@ -896,9 +905,6 @@ dsl_scan_ds_destroyed(dsl_dataset_t *ds,
                        zfs_dbgmsg("destroying ds %llu; in queue; removing",
                            (u_longlong_t)ds->ds_object);
                }
-       } else {
-               zfs_dbgmsg("destroying ds %llu; ignoring",
-                   (u_longlong_t)ds->ds_object);
        }
 
        /*
@@ -1051,6 +1057,46 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64
 
        VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
 
+       if (scn->scn_phys.scn_cur_min_txg >=
+           scn->scn_phys.scn_max_txg) {
+               /*
+                * This can happen if this snapshot was created after the
+                * scan started, and we already completed a previous snapshot
+                * that was created after the scan started.  This snapshot
+                * only references blocks with:
+                *
+                *      birth < our ds_creation_txg
+                *      cur_min_txg is no less than ds_creation_txg.
+                *      We have already visited these blocks.
+                * or
+                *      birth > scn_max_txg
+                *      The scan requested not to visit these blocks.
+                *
+                * Subsequent snapshots (and clones) can reference our
+                * blocks, or blocks with even higher birth times.
+                * Therefore we do not need to visit them either,
+                * so we do not add them to the work queue.
+                *
+                * Note that checking for cur_min_txg >= cur_max_txg
+                * is not sufficient, because in that case we may need to
+                * visit subsequent snapshots.  This happens when min_txg > 0,
+                * which raises cur_min_txg.  In this case we will visit
+                * this dataset but skip all of its blocks, because the
+                * rootbp's birth time is < cur_min_txg.  Then we will
+                * add the next snapshots/clones to the work queue.
+                */
+               char *dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+               dsl_dataset_name(ds, dsname);
+               zfs_dbgmsg("scanning dataset %llu (%s) is unnecessary because "
+                   "cur_min_txg (%llu) >= max_txg (%llu)",
+                   dsobj, dsname,
+                   scn->scn_phys.scn_cur_min_txg,
+                   scn->scn_phys.scn_max_txg);
+               kmem_free(dsname, MAXNAMELEN);
+
+               goto out;
+       }
+
        if (dmu_objset_from_ds(ds, &os))
                goto out;
 
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to