If the WAPBL journal can't be read (ffs_wapbl_replay_start() fails),

mount the filesystem anyway if MNT_FORCE is present.
This allows to still boot single-user a system with a corrupted
WAPBL on /, and so get a chance to run fsck to fix it.
http://mail-index.netbsd.org/tech-kern/2009/08/17/msg005896.html
and followups.
This commit is contained in:
bouyer 2009-09-13 14:30:21 +00:00
parent cab6cd67bc
commit b9440228c5
1 changed files with 25 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.251 2009/09/13 05:17:36 tsutsui Exp $ */ /* $NetBSD: ffs_vfsops.c,v 1.252 2009/09/13 14:30:21 bouyer Exp $ */
/*- /*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.251 2009/09/13 05:17:36 tsutsui Exp $"); __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.252 2009/09/13 14:30:21 bouyer Exp $");
#if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT)
#include "opt_ffs.h" #include "opt_ffs.h"
@ -959,28 +959,32 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
#ifdef WAPBL #ifdef WAPBL
if ((mp->mnt_wapbl_replay == 0) && (fs->fs_flags & FS_DOWAPBL)) { if ((mp->mnt_wapbl_replay == 0) && (fs->fs_flags & FS_DOWAPBL)) {
error = ffs_wapbl_replay_start(mp, fs, devvp); error = ffs_wapbl_replay_start(mp, fs, devvp);
if (error) if (error && (mp->mnt_flag & MNT_FORCE) == 0)
goto out; goto out;
if (!error) {
if (!ronly) {
/* XXX fsmnt may be stale. */
printf("%s: replaying log to disk\n",
fs->fs_fsmnt);
error = wapbl_replay_write(mp->mnt_wapbl_replay,
devvp);
if (error)
goto out;
wapbl_replay_stop(mp->mnt_wapbl_replay);
fs->fs_clean = FS_WASCLEAN;
} else {
/* XXX fsmnt may be stale */
printf("%s: replaying log to memory\n",
fs->fs_fsmnt);
}
if (!ronly) { /* Force a re-read of the superblock */
/* XXX fsmnt may be stale. */ brelse(bp, BC_INVAL);
printf("%s: replaying log to disk\n", fs->fs_fsmnt); bp = NULL;
error = wapbl_replay_write(mp->mnt_wapbl_replay, devvp); free(fs, M_UFSMNT);
if (error) fs = NULL;
goto out; goto sbagain;
wapbl_replay_stop(mp->mnt_wapbl_replay);
fs->fs_clean = FS_WASCLEAN;
} else {
/* XXX fsmnt may be stale */
printf("%s: replaying log to memory\n", fs->fs_fsmnt);
} }
/* Force a re-read of the superblock */
brelse(bp, BC_INVAL);
bp = NULL;
free(fs, M_UFSMNT);
fs = NULL;
goto sbagain;
} }
#else /* !WAPBL */ #else /* !WAPBL */
if ((fs->fs_flags & FS_DOWAPBL) && (mp->mnt_flag & MNT_FORCE) == 0) { if ((fs->fs_flags & FS_DOWAPBL) && (mp->mnt_flag & MNT_FORCE) == 0) {