diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index f837a07..745d5f5 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -998,6 +998,7 @@ extern struct vop_ops hammer_spec_vops; extern struct vop_ops hammer_fifo_vops; extern struct bio_ops hammer_bioops; +extern int hammer_skip_redo; extern int hammer_debug_io; extern int hammer_debug_general; extern int hammer_debug_debug; diff --git a/sys/vfs/hammer/hammer_recover.c b/sys/vfs/hammer/hammer_recover.c index 0b699d2..3f7f8c7 100644 --- a/sys/vfs/hammer/hammer_recover.c +++ b/sys/vfs/hammer/hammer_recover.c @@ -116,6 +116,21 @@ #include "hammer.h" /* + * Specify the way we want to handle stage2 errors. + * + * Following values are accepted: + * + * 0 - Run redo recovery normally and fail to mount if + * the operation fails (default). + * 1 - Run redo recovery, but don't fail to mount if the + * operation fails. + * 2 - Completely skip redo recovery (only for severe error + * conditions and/or debugging. + */ +int hammer_skip_redo = 0; +TUNABLE_INT("vfs.hammer.skip_redo", &hammer_skip_redo); + +/* * Each rterm entry has a list of fifo offsets indicating termination * points. These are stripped as the scan progresses. */ @@ -570,6 +585,10 @@ hammer_recover_stage2(hammer_mount_t hmp, hammer_volume_t root_volume) bytes = rootmap->alloc_offset - first_offset + (last_offset & HAMMER_OFF_LONG_MASK); } + if (hammer_skip_redo) + kprintf("HAMMER(%s) recovery redo marked as optional\n", + root_volume->ondisk->vol_name); + kprintf("HAMMER(%s) recovery redo %016jx-%016jx (%jd bytes)%s\n", root_volume->ondisk->vol_name, (intmax_t)first_offset, diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index 03049b3..4b8d3ba 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -304,6 +304,7 @@ static int hammer_vfs_init(struct vfsconf *conf); static int hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, struct fid *fhp, struct vnode **vpp); static int hammer_vfs_vptofh(struct vnode *vp, struct fid *fhp); +static int hammer_vfs_runredo(hammer_mount_t hmp, hammer_volume_t vol); static int hammer_vfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp, struct ucred **credanonp); @@ -525,7 +526,7 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data, rootvol = hammer_get_root_volume(hmp, &error); if (rootvol) { hammer_recover_flush_buffers(hmp, rootvol, 1); - error = hammer_recover_stage2(hmp, rootvol); + error = hammer_vfs_runredo(hmp, rootvol); bcopy(rootvol->ondisk->vol0_blockmap, hmp->blockmap, sizeof(hmp->blockmap)); @@ -781,7 +782,7 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data, vput(rootvp); /*vn_unlock(hmp->rootvp);*/ if (hmp->ronly == 0) - error = hammer_recover_stage2(hmp, rootvol); + error = hammer_vfs_runredo(hmp, rootvol); /* * If the stage2 recovery fails be sure to clean out all cached @@ -1241,3 +1242,14 @@ hammer_vfs_export(struct mount *mp, int op, const struct export_args *export) return(error); } +static int +hammer_vfs_runredo(hammer_mount_t hmp, hammer_volume_t vol) +{ + int error; + error = 0; + + if (hammer_skip_redo != 2) + error = hammer_recover_stage2(hmp, vol); + + return (hammer_skip_redo ? 0 : error); +}