/*
* FS specific support for 4.4BSD Log-structured Filesystem
*
* Written in 1999, 2002, 2003 by ITOH Yasufumi.
* Public domain.
*
* Intended to be used for boot programs (first stage).
* DON'T ADD ANY FANCY FEATURE. THIS SHALL BE COMPACT.
*/
#include "readufs.h"
#include <sys/mount.h>
#include <ufs/lfs/lfs.h>
#ifndef USE_UFS1
#error LFS currently requires USE_UFS1
#endif
/*
* Read and check superblock.
* If it is an LFS, save information from the superblock.
*/
int
try_lfs(void)
{
struct ufs_info *ufsinfo = &ufs_info;
struct dlfs sblk, sblk2;
struct dlfs *s = &sblk;
daddr_t sbpos;
int fsbshift;
if (sblk2.dlfs_magic == LFS_MAGIC) {
if (fsi_lfs.version == 1) {
if (sblk.dlfs_inopf > sblk2.dlfs_inopf)
s = &sblk2;
} else {
if (sblk.dlfs_serial > sblk2.dlfs_serial)
s = &sblk2;
}
}
}
/* This partition looks like an LFS. */
#if 0
fsi.get_inode = get_lfs_inode;
#endif
/*
* version 1: disk addr is in disk sector --- no shifting
* version 2: disk addr is in fragment
*/
fsi.fsbtodb = fsbshift;
/* Get information from the superblock. */
fsi.bsize = s->dlfs_bsize;
fsi.nindir = s->dlfs_nindir;
fsi_lfs.idaddr = s->dlfs_idaddr;
fsi_lfs.ibsize = (fsi_lfs.version == 1) ? s->dlfs_bsize : s->dlfs_fsize;
/*
* version 1: number of inode per block
* version 2: number of inode per fragment (but in dlfs_inopb)
*/
fsi_lfs.inopb = s->dlfs_inopb;
/* ifile is always used to look-up other inodes, so keep its inode. */
if (get_lfs_inode(LFS_IFILE_INUM, (union ufs_dinode *)&ifile_dinode))
return 1; /* OOPS, failed to find inode of ifile! */
fsi.fstype = UFSTYPE_LFS;
return 0;
}
/*
* Get inode from disk.
*/
int
get_lfs_inode(ino32_t ino, union ufs_dinode *dibuf)
{
struct ufs_info *ufsinfo = &ufs_info;
daddr_t daddr;
char *buf = alloca(fsi.bsize);
struct lfs32_dinode *di, *diend;
int i;