Home | History | Annotate | Line # | Download | only in xxboot
      1  1.3  christos /*	$NetBSD: readufs_lfs.c,v 1.3 2015/08/20 07:50:08 christos Exp $	*/
      2  1.1     skrll /*	from Id: readufs_lfs.c,v 1.8 2003/12/16 13:54:11 itohy Exp	*/
      3  1.1     skrll 
      4  1.1     skrll /*
      5  1.1     skrll  * FS specific support for 4.4BSD Log-structured Filesystem
      6  1.1     skrll  *
      7  1.1     skrll  * Written in 1999, 2002, 2003 by ITOH Yasufumi.
      8  1.1     skrll  * Public domain.
      9  1.1     skrll  *
     10  1.1     skrll  * Intended to be used for boot programs (first stage).
     11  1.1     skrll  * DON'T ADD ANY FANCY FEATURE.  THIS SHALL BE COMPACT.
     12  1.1     skrll  */
     13  1.1     skrll 
     14  1.1     skrll #include "readufs.h"
     15  1.1     skrll 
     16  1.1     skrll #include <sys/mount.h>
     17  1.1     skrll #include <ufs/lfs/lfs.h>
     18  1.1     skrll 
     19  1.1     skrll #ifndef USE_UFS1
     20  1.1     skrll  #error LFS currently requires USE_UFS1
     21  1.1     skrll #endif
     22  1.1     skrll 
     23  1.3  christos static struct lfs32_dinode	ifile_dinode;
     24  1.1     skrll 
     25  1.1     skrll #define fsi	(*ufsinfo)
     26  1.1     skrll #define fsi_lfs	fsi.fs_u.u_lfs
     27  1.1     skrll 
     28  1.1     skrll /*
     29  1.1     skrll  * Read and check superblock.
     30  1.1     skrll  * If it is an LFS, save information from the superblock.
     31  1.1     skrll  */
     32  1.1     skrll int
     33  1.1     skrll try_lfs(void)
     34  1.1     skrll {
     35  1.1     skrll 	struct ufs_info	*ufsinfo = &ufs_info;
     36  1.1     skrll 	struct dlfs	sblk, sblk2;
     37  1.1     skrll 	struct dlfs	*s = &sblk;
     38  1.1     skrll 	daddr_t		sbpos;
     39  1.1     skrll 	int		fsbshift;
     40  1.1     skrll 
     41  1.1     skrll #ifdef DEBUG_WITH_STDIO
     42  1.1     skrll 	printf("trying LFS\n");
     43  1.1     skrll #endif
     44  1.1     skrll 	sbpos =  btodb(LFS_LABELPAD);
     45  1.1     skrll 
     46  1.1     skrll 	/* read primary superblock */
     47  1.1     skrll 	for (;;) {
     48  1.1     skrll #ifdef DEBUG_WITH_STDIO
     49  1.1     skrll 		printf("LFS: reading primary sblk at: 0x%x\n", (unsigned)sbpos);
     50  1.1     skrll #endif
     51  1.1     skrll 		RAW_READ(&sblk, sbpos, sizeof sblk);
     52  1.1     skrll 
     53  1.1     skrll #ifdef DEBUG_WITH_STDIO
     54  1.1     skrll 		printf("LFS: sblk: magic: 0x%x, version: %d\n",
     55  1.1     skrll 			sblk.dlfs_magic, sblk.dlfs_version);
     56  1.1     skrll #endif
     57  1.1     skrll 
     58  1.1     skrll 		if (sblk.dlfs_magic != LFS_MAGIC)
     59  1.1     skrll 			return 1;
     60  1.1     skrll 
     61  1.1     skrll #ifdef DEBUG_WITH_STDIO
     62  1.1     skrll 		printf("LFS: bsize %d, fsize %d, bshift %d, blktodb %d, fsbtodb %d, inopf %d, inopb %d\n",
     63  1.1     skrll 		    sblk.dlfs_bsize, sblk.dlfs_fsize,
     64  1.1     skrll 		    sblk.dlfs_bshift, sblk.dlfs_blktodb, sblk.dlfs_fsbtodb,
     65  1.1     skrll 		    sblk.dlfs_inopf, sblk.dlfs_inopb);
     66  1.1     skrll #endif
     67  1.1     skrll 		if ((fsi_lfs.version = sblk.dlfs_version) == 1) {
     68  1.1     skrll 			fsbshift = 0;
     69  1.1     skrll 			break;
     70  1.1     skrll 		} else {
     71  1.1     skrll 			daddr_t	sbpos1;
     72  1.1     skrll #if 0
     73  1.1     skrll 			fsbshift = sblk.dlfs_bshift - sblk.dlfs_blktodb + sblk.dlfs_fsbtodb - DEV_BSHIFT;
     74  1.1     skrll #endif
     75  1.1     skrll 			fsbshift = sblk.dlfs_fsbtodb;
     76  1.1     skrll 			sbpos1 = sblk.dlfs_sboffs[0] << fsbshift;
     77  1.1     skrll 			if (sbpos == sbpos1)
     78  1.1     skrll 				break;
     79  1.1     skrll #ifdef DEBUG_WITH_STDIO
     80  1.1     skrll 			printf("LFS: correcting primary sblk location\n");
     81  1.1     skrll #endif
     82  1.1     skrll 			sbpos = sbpos1;
     83  1.1     skrll 		}
     84  1.1     skrll 	}
     85  1.1     skrll 
     86  1.1     skrll #ifdef DEBUG_WITH_STDIO
     87  1.1     skrll 	printf("fsbshift: %d\n", fsbshift);
     88  1.1     skrll 	printf("sboff[1]: %d\n", sblk.dlfs_sboffs[1]);
     89  1.1     skrll #endif
     90  1.1     skrll 
     91  1.1     skrll 	if (sblk.dlfs_sboffs[1] > 0) {
     92  1.1     skrll #ifdef DEBUG_WITH_STDIO
     93  1.1     skrll 		printf("LFS: reading secondary sblk at: 0x%x\n",
     94  1.1     skrll 		    sblk.dlfs_sboffs[1] << fsbshift);
     95  1.1     skrll #endif
     96  1.1     skrll 		/* read secondary superblock */
     97  1.1     skrll 		RAW_READ(&sblk2, (daddr_t) sblk.dlfs_sboffs[1] << fsbshift,
     98  1.1     skrll 		    sizeof sblk2);
     99  1.1     skrll 
    100  1.1     skrll #ifdef DEBUG_WITH_STDIO
    101  1.1     skrll 		printf("LFS: sblk2: magic: 0x%x, version: %d\n",
    102  1.1     skrll 			sblk2.dlfs_magic, sblk2.dlfs_version);
    103  1.1     skrll #endif
    104  1.1     skrll 
    105  1.1     skrll 		if (sblk2.dlfs_magic == LFS_MAGIC) {
    106  1.1     skrll 			if (fsi_lfs.version == 1) {
    107  1.2  christos 				if (sblk.dlfs_inopf > sblk2.dlfs_inopf)
    108  1.1     skrll 					s = &sblk2;
    109  1.1     skrll 			} else {
    110  1.1     skrll 				if (sblk.dlfs_serial > sblk2.dlfs_serial)
    111  1.1     skrll 					s = &sblk2;
    112  1.1     skrll 			}
    113  1.1     skrll 		}
    114  1.1     skrll 	}
    115  1.1     skrll 
    116  1.1     skrll 	/* This partition looks like an LFS. */
    117  1.1     skrll #if 0
    118  1.1     skrll 	fsi.get_inode = get_lfs_inode;
    119  1.1     skrll #endif
    120  1.1     skrll 	/*
    121  1.1     skrll 	 * version 1: disk addr is in disk sector --- no shifting
    122  1.1     skrll 	 * version 2: disk addr is in fragment
    123  1.1     skrll 	 */
    124  1.1     skrll 	fsi.fsbtodb = fsbshift;
    125  1.1     skrll 
    126  1.1     skrll 	/* Get information from the superblock. */
    127  1.1     skrll 	fsi.bsize = s->dlfs_bsize;
    128  1.1     skrll 	fsi.nindir = s->dlfs_nindir;
    129  1.1     skrll 	fsi_lfs.idaddr = s->dlfs_idaddr;
    130  1.1     skrll 	fsi_lfs.ibsize = (fsi_lfs.version == 1) ? s->dlfs_bsize : s->dlfs_fsize;
    131  1.1     skrll 
    132  1.1     skrll 	/*
    133  1.1     skrll 	 * version 1: number of inode per block
    134  1.1     skrll 	 * version 2: number of inode per fragment (but in dlfs_inopb)
    135  1.1     skrll 	 */
    136  1.1     skrll 	fsi_lfs.inopb = s->dlfs_inopb;
    137  1.1     skrll 
    138  1.1     skrll 	fsi_lfs.ifpb = s->dlfs_ifpb;
    139  1.1     skrll 	fsi_lfs.ioffset = s->dlfs_cleansz + s->dlfs_segtabsz;
    140  1.1     skrll 
    141  1.1     skrll 	/* ifile is always used to look-up other inodes, so keep its inode. */
    142  1.1     skrll 	if (get_lfs_inode(LFS_IFILE_INUM, (union ufs_dinode *)&ifile_dinode))
    143  1.1     skrll 		return 1;	/* OOPS, failed to find inode of ifile! */
    144  1.1     skrll 
    145  1.1     skrll 	fsi.fstype = UFSTYPE_LFS;
    146  1.1     skrll 
    147  1.1     skrll 	return 0;
    148  1.1     skrll }
    149  1.1     skrll 
    150  1.1     skrll /*
    151  1.1     skrll  * Get inode from disk.
    152  1.1     skrll  */
    153  1.1     skrll int
    154  1.1     skrll get_lfs_inode(ino32_t ino, union ufs_dinode *dibuf)
    155  1.1     skrll {
    156  1.1     skrll 	struct ufs_info *ufsinfo = &ufs_info;
    157  1.1     skrll 	daddr_t daddr;
    158  1.1     skrll 	char *buf = alloca(fsi.bsize);
    159  1.3  christos 	struct lfs32_dinode *di, *diend;
    160  1.1     skrll 	int i;
    161  1.1     skrll 
    162  1.1     skrll 	/* Get fs block which contains the specified inode. */
    163  1.1     skrll 	if (ino == LFS_IFILE_INUM)
    164  1.1     skrll 		daddr = fsi_lfs.idaddr;
    165  1.1     skrll 	else {
    166  1.1     skrll #ifdef DEBUG_WITH_STDIO
    167  1.1     skrll 		printf("LFS: ino: %d\nifpb: %d, bsize: %d\n",
    168  1.1     skrll 			ino, fsi_lfs.ifpb, fsi.bsize);
    169  1.1     skrll #endif
    170  1.1     skrll 		ufs_read((union ufs_dinode *) &ifile_dinode, buf,
    171  1.1     skrll 			 ino / fsi_lfs.ifpb + fsi_lfs.ioffset,
    172  1.1     skrll 			 fsi.bsize);
    173  1.1     skrll 		i = ino % fsi_lfs.ifpb;
    174  1.1     skrll 		daddr = (fsi_lfs.version == 1) ?
    175  1.1     skrll 		    ((IFILE_V1 *) buf + i)->if_daddr
    176  1.3  christos 		    : ((IFILE32 *) buf + i)->if_daddr;
    177  1.1     skrll 	}
    178  1.1     skrll #ifdef DEBUG_WITH_STDIO
    179  1.1     skrll 	printf("LFS(%d): daddr: %d\n", ino, (int) daddr);
    180  1.1     skrll #endif
    181  1.1     skrll 
    182  1.1     skrll 	if (daddr == LFS_UNUSED_DADDR)
    183  1.1     skrll 		return 1;
    184  1.1     skrll 
    185  1.1     skrll 	/* Read the inode block. */
    186  1.1     skrll 	RAW_READ(buf, daddr << fsi.fsbtodb, fsi_lfs.ibsize);
    187  1.1     skrll 
    188  1.1     skrll 	/* Search for the inode. */
    189  1.3  christos 	di = (struct lfs32_dinode *) buf;
    190  1.1     skrll 	diend = di + fsi_lfs.inopb;
    191  1.1     skrll 
    192  1.1     skrll 	for ( ; di < diend; di++)
    193  1.1     skrll 		if (di->di_inumber == ino)
    194  1.1     skrll 			goto found;
    195  1.1     skrll 	/* not found */
    196  1.1     skrll 	return 1;
    197  1.1     skrll 
    198  1.1     skrll found:
    199  1.1     skrll #ifdef DEBUG_WITH_STDIO
    200  1.1     skrll 	printf("LFS: dinode(%d): mode 0%o, nlink %d, inumber %d, size %d, uid %d, db[0] %d\n",
    201  1.1     skrll 		ino, di->di_mode, di->di_nlink, di->di_inumber,
    202  1.1     skrll 		(int) di->di_size, di->di_uid, di->di_db[0]);
    203  1.1     skrll #endif
    204  1.1     skrll 
    205  1.1     skrll #if 0	/* currently UFS1 only */
    206  1.1     skrll #if defined(USE_UFS1) && defined(USE_UFS2)
    207  1.1     skrll 	/* XXX for DI_SIZE() macro */
    208  1.1     skrll 	if (ufsinfo->ufstype != UFSTYPE_UFS1)
    209  1.1     skrll 		di->di1.di_size = di->si2.di_size;
    210  1.1     skrll #endif
    211  1.1     skrll #endif
    212  1.1     skrll 
    213  1.3  christos 	dibuf->dil32 = *di;
    214  1.1     skrll 
    215  1.1     skrll 	return 0;
    216  1.1     skrll }
    217