Author: avg
Date: Mon Feb 17 18:24:25 2014
New Revision: 262118
URL: http://svnweb.freebsd.org/changeset/base/262118

Log:
  MFC r260185: MFV r260155: 4391 panic system rather than corrupting pool if we 
hit bug 4390

Modified:
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c    Mon Feb 
17 18:16:50 2014        (r262117)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c    Mon Feb 
17 18:24:25 2014        (r262118)
@@ -180,6 +180,7 @@ bptree_iterate(objset_t *os, uint64_t ob
        err = 0;
        for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
                bptree_entry_phys_t bte;
+               int flags = TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST;
 
                ASSERT(!free || i == ba.ba_phys->bt_begin);
 
@@ -188,13 +189,13 @@ bptree_iterate(objset_t *os, uint64_t ob
                if (err != 0)
                        break;
 
+               if (zfs_recover)
+                       flags |= TRAVERSE_HARD;
                err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
-                   bte.be_birth_txg, &bte.be_zb,
-                   TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST,
+                   bte.be_birth_txg, &bte.be_zb, flags,
                    bptree_visit_cb, &ba);
                if (free) {
-                       ASSERT(err == 0 || err == ERESTART);
-                       if (err != 0) {
+                       if (err == ERESTART) {
                                /* save bookmark for future resume */
                                ASSERT3U(bte.be_zb.zb_objset, ==,
                                    ZB_DESTROYED_OBJSET);
@@ -202,11 +203,21 @@ bptree_iterate(objset_t *os, uint64_t ob
                                dmu_write(os, obj, i * sizeof (bte),
                                    sizeof (bte), &bte, tx);
                                break;
-                       } else {
-                               ba.ba_phys->bt_begin++;
-                               (void) dmu_free_range(os, obj,
-                                   i * sizeof (bte), sizeof (bte), tx);
                        }
+                       if (err != 0) {
+                               /*
+                                * We can not properly handle an i/o
+                                * error, because the traversal code
+                                * does not know how to resume from an
+                                * arbitrary bookmark.
+                                */
+                               zfs_panic_recover("error %u from "
+                                   "traverse_dataset_destroyed()", err);
+                       }
+
+                       ba.ba_phys->bt_begin++;
+                       (void) dmu_free_range(os, obj,
+                           i * sizeof (bte), sizeof (bte), tx);
                }
        }
 

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c      
Mon Feb 17 18:16:50 2014        (r262117)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c      
Mon Feb 17 18:24:25 2014        (r262118)
@@ -361,7 +361,7 @@ traverse_visitbp(traverse_data_t *td, co
                (void) arc_buf_remove_ref(buf, &buf);
 
 post:
-       if (err == 0 && lasterr == 0 && (td->td_flags & TRAVERSE_POST)) {
+       if (err == 0 && (td->td_flags & TRAVERSE_POST)) {
                err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg);
                if (err == ERESTART)
                        pause = B_TRUE;

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c  Mon Feb 
17 18:16:50 2014        (r262117)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c  Mon Feb 
17 18:24:25 2014        (r262118)
@@ -1347,6 +1347,9 @@ dsl_scan_free_should_pause(dsl_scan_t *s
 {
        uint64_t elapsed_nanosecs;
 
+       if (zfs_recover)
+               return (B_FALSE);
+
        elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
        return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
            (NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms &&

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c  Mon Feb 
17 18:16:50 2014        (r262117)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c  Mon Feb 
17 18:24:25 2014        (r262118)
@@ -252,6 +252,8 @@ SYSCTL_INT(_debug, OID_AUTO, zfs_flags, 
  * zfs_recover can be set to nonzero to attempt to recover from
  * otherwise-fatal errors, typically caused by on-disk corruption.  When
  * set, calls to zfs_panic_recover() will turn into warning messages.
+ * This should only be used as a last resort, as it typically results
+ * in leaked space, or worse.
  */
 int zfs_recover = 0;
 SYSCTL_DECL(_vfs_zfs);

Modified: 
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h     
Mon Feb 17 18:16:50 2014        (r262117)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h     
Mon Feb 17 18:24:25 2014        (r262118)
@@ -49,6 +49,7 @@ extern "C" {
 #endif
 
 extern int zfs_flags;
+extern int zfs_recover;
 
 #define        ZFS_DEBUG_DPRINTF       (1<<0)
 #define        ZFS_DEBUG_DBUF_VERIFY   (1<<1)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to