mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 19:50:25 +03:00
26126 panic system rather than corrupting pool if we hit bug 26100
References: delphix/delphix-os@931c8aaab7 Ported-by: Richard Yao <ryao@gentoo.org> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #1650
This commit is contained in:
parent
2517c8ee08
commit
78e2739d3c
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/arc.h>
|
#include <sys/arc.h>
|
||||||
@ -180,6 +180,7 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
|
|||||||
err = 0;
|
err = 0;
|
||||||
for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
|
for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
|
||||||
bptree_entry_phys_t bte;
|
bptree_entry_phys_t bte;
|
||||||
|
int flags = TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST;
|
||||||
|
|
||||||
ASSERT(!free || i == ba.ba_phys->bt_begin);
|
ASSERT(!free || i == ba.ba_phys->bt_begin);
|
||||||
|
|
||||||
@ -188,13 +189,13 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
|
|||||||
if (err != 0)
|
if (err != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (zfs_recover)
|
||||||
|
flags |= TRAVERSE_HARD;
|
||||||
err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
|
err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
|
||||||
bte.be_birth_txg, &bte.be_zb,
|
bte.be_birth_txg, &bte.be_zb, flags,
|
||||||
TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST,
|
|
||||||
bptree_visit_cb, &ba);
|
bptree_visit_cb, &ba);
|
||||||
if (free) {
|
if (free) {
|
||||||
ASSERT(err == 0 || err == ERESTART);
|
if (err == ERESTART) {
|
||||||
if (err != 0) {
|
|
||||||
/* save bookmark for future resume */
|
/* save bookmark for future resume */
|
||||||
ASSERT3U(bte.be_zb.zb_objset, ==,
|
ASSERT3U(bte.be_zb.zb_objset, ==,
|
||||||
ZB_DESTROYED_OBJSET);
|
ZB_DESTROYED_OBJSET);
|
||||||
@ -202,13 +203,23 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
|
|||||||
dmu_write(os, obj, i * sizeof (bte),
|
dmu_write(os, obj, i * sizeof (bte),
|
||||||
sizeof (bte), &bte, tx);
|
sizeof (bte), &bte, tx);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
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++;
|
ba.ba_phys->bt_begin++;
|
||||||
(void) dmu_free_range(os, obj,
|
(void) dmu_free_range(os, obj,
|
||||||
i * sizeof (bte), sizeof (bte), tx);
|
i * sizeof (bte), sizeof (bte), tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(!free || err != 0 || ba.ba_phys->bt_begin == ba.ba_phys->bt_end);
|
ASSERT(!free || err != 0 || ba.ba_phys->bt_begin == ba.ba_phys->bt_end);
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
|
|||||||
(void) arc_buf_remove_ref(buf, &buf);
|
(void) arc_buf_remove_ref(buf, &buf);
|
||||||
|
|
||||||
post:
|
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);
|
err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg);
|
||||||
if (err == ERESTART)
|
if (err == ERESTART)
|
||||||
pause = B_TRUE;
|
pause = B_TRUE;
|
||||||
|
@ -1334,6 +1334,9 @@ dsl_scan_free_should_pause(dsl_scan_t *scn)
|
|||||||
{
|
{
|
||||||
uint64_t elapsed_nanosecs;
|
uint64_t elapsed_nanosecs;
|
||||||
|
|
||||||
|
if (zfs_recover)
|
||||||
|
return (B_FALSE);
|
||||||
|
|
||||||
elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
|
elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
|
||||||
return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
|
return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
|
||||||
(NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms &&
|
(NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms &&
|
||||||
|
@ -41,6 +41,8 @@ int zfs_flags = 0;
|
|||||||
* zfs_recover can be set to nonzero to attempt to recover from
|
* zfs_recover can be set to nonzero to attempt to recover from
|
||||||
* otherwise-fatal errors, typically caused by on-disk corruption. When
|
* otherwise-fatal errors, typically caused by on-disk corruption. When
|
||||||
* set, calls to zfs_panic_recover() will turn into warning messages.
|
* 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;
|
int zfs_recover = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user