Only allow WAPBL to operate with UFS2 style superblocks.
Problem reported by Takeshi Nakayama.
This commit is contained in:
parent
bdb681208a
commit
ba0675032b
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ffs_wapbl.c,v 1.3 2008/08/02 02:23:51 simonb Exp $ */
|
/* $NetBSD: ffs_wapbl.c,v 1.4 2008/08/04 15:55:11 simonb Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.3 2008/08/02 02:23:51 simonb Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.4 2008/08/04 15:55:11 simonb Exp $");
|
||||||
|
|
||||||
#if defined(_KERNEL_OPT)
|
#if defined(_KERNEL_OPT)
|
||||||
#include "opt_ffs.h"
|
#include "opt_ffs.h"
|
||||||
|
@ -74,6 +74,7 @@ do { \
|
||||||
} while (/* CONSTCOND */0)
|
} while (/* CONSTCOND */0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int ffs_superblock_layout(struct fs *);
|
||||||
static int wapbl_log_position(struct mount *, struct fs *, struct vnode *,
|
static int wapbl_log_position(struct mount *, struct fs *, struct vnode *,
|
||||||
daddr_t *, size_t *, size_t *, uint64_t *);
|
daddr_t *, size_t *, size_t *, uint64_t *);
|
||||||
static int wapbl_create_infs_log(struct mount *, struct fs *, struct vnode *,
|
static int wapbl_create_infs_log(struct mount *, struct fs *, struct vnode *,
|
||||||
|
@ -83,6 +84,24 @@ static void wapbl_find_log_start(struct mount *, struct vnode *, off_t,
|
||||||
static int wapbl_remove_log(struct mount *);
|
static int wapbl_remove_log(struct mount *);
|
||||||
static int wapbl_allocate_log_file(struct mount *, struct vnode *);
|
static int wapbl_allocate_log_file(struct mount *, struct vnode *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the super block layout format - UFS1 or UFS2.
|
||||||
|
* WAPBL only works with UFS2 layout (which is still available
|
||||||
|
* with FFSv1).
|
||||||
|
*
|
||||||
|
* XXX Should this be in ufs/ffs/fs.h? Same style of check is
|
||||||
|
* also used in ffs_alloc.c in a few places.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ffs_superblock_layout(struct fs *fs)
|
||||||
|
{
|
||||||
|
if ((fs->fs_magic == FS_UFS1_MAGIC) &&
|
||||||
|
((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is invoked after a log is replayed to
|
* This function is invoked after a log is replayed to
|
||||||
* disk to perform logical cleanup actions as described by
|
* disk to perform logical cleanup actions as described by
|
||||||
|
@ -203,6 +222,10 @@ wapbl_remove_log(struct mount *mp)
|
||||||
ino_t log_ino;
|
ino_t log_ino;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
/* If super block layout is too old to support WAPBL, return */
|
||||||
|
if (ffs_superblock_layout(fs) < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If all the log locators are 0, just clean up */
|
/* If all the log locators are 0, just clean up */
|
||||||
if (fs->fs_journallocs[0] == 0 &&
|
if (fs->fs_journallocs[0] == 0 &&
|
||||||
fs->fs_journallocs[1] == 0 &&
|
fs->fs_journallocs[1] == 0 &&
|
||||||
|
@ -302,6 +325,15 @@ ffs_wapbl_start(struct mount *mp)
|
||||||
if (mp->mnt_flag & MNT_LOG) {
|
if (mp->mnt_flag & MNT_LOG) {
|
||||||
KDASSERT(fs->fs_ronly == 0);
|
KDASSERT(fs->fs_ronly == 0);
|
||||||
|
|
||||||
|
/* WAPBL needs UFS2 format super block */
|
||||||
|
if (ffs_superblock_layout(fs) < 2) {
|
||||||
|
printf("%s fs superblock in old format, "
|
||||||
|
"not journaling\n",
|
||||||
|
VFSTOUFS(mp)->um_fs->fs_fsmnt);
|
||||||
|
mp->mnt_flag &= ~MNT_LOG;
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
error = wapbl_log_position(mp, fs, devvp, &off,
|
error = wapbl_log_position(mp, fs, devvp, &off,
|
||||||
&count, &blksize, &extradata);
|
&count, &blksize, &extradata);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -428,6 +460,13 @@ ffs_wapbl_replay_start(struct mount *mp, struct fs *fs, struct vnode *devvp)
|
||||||
size_t blksize;
|
size_t blksize;
|
||||||
uint64_t extradata;
|
uint64_t extradata;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WAPBL needs UFS2 format super block, if we got here with a
|
||||||
|
* UFS1 format super block something is amiss...
|
||||||
|
*/
|
||||||
|
if (ffs_superblock_layout(fs) < 2)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
error = wapbl_log_position(mp, fs, devvp, &off, &count, &blksize,
|
error = wapbl_log_position(mp, fs, devvp, &off, &count, &blksize,
|
||||||
&extradata);
|
&extradata);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue