Home | History | Annotate | Line # | Download | only in boot_ufs
readufs_lfs.c revision 1.1
      1  1.1  minoura /*	$Id: readufs_lfs.c,v 1.1 2001/09/27 10:14:50 minoura Exp $	*/
      2  1.1  minoura 
      3  1.1  minoura /*
      4  1.1  minoura  * FS specific support for 4.4BSD Log-structured Filesystem
      5  1.1  minoura  *
      6  1.1  minoura  * Written by ITOH, Yasufumi (itohy (at) netbsd.org).
      7  1.1  minoura  * Public domain.
      8  1.1  minoura  *
      9  1.1  minoura  * Intended to be used for boot programs (first stage).
     10  1.1  minoura  * DON'T ADD ANY FANCY FEATURE.  THIS SHALL BE COMPACT.
     11  1.1  minoura  */
     12  1.1  minoura 
     13  1.1  minoura #include <sys/types.h>
     14  1.1  minoura #include <sys/param.h>
     15  1.1  minoura #include <sys/mount.h>
     16  1.1  minoura #include <ufs/ufs/dinode.h>
     17  1.1  minoura #include <ufs/lfs/lfs.h>
     18  1.1  minoura 
     19  1.1  minoura #include "readufs.h"
     20  1.1  minoura 
     21  1.1  minoura static int get_lfs_inode __P((ino_t ino, struct dinode *dibuf));
     22  1.1  minoura 
     23  1.1  minoura static struct dinode	ifile_dinode;
     24  1.1  minoura 
     25  1.1  minoura #define fsi	(*ufsinfo)
     26  1.1  minoura #define fsi_lfs	fsi.fs_u.u_lfs
     27  1.1  minoura 
     28  1.1  minoura /*
     29  1.1  minoura  * Read and check superblock.
     30  1.1  minoura  * If it is an LFS, save information from the superblock.
     31  1.1  minoura  */
     32  1.1  minoura int
     33  1.1  minoura try_lfs()
     34  1.1  minoura {
     35  1.1  minoura 	struct ufs_info *ufsinfo = &ufs_info;
     36  1.1  minoura 	struct dlfs	sblk, sblk2;
     37  1.1  minoura 	struct dlfs	*s = &sblk;
     38  1.1  minoura 
     39  1.1  minoura #ifdef DEBUG_WITH_STDIO
     40  1.1  minoura 	printf("trying LFS\n");
     41  1.1  minoura #endif
     42  1.1  minoura 	/* read primary superblock */
     43  1.1  minoura 	RAW_READ(&sblk, btodb(LFS_LABELPAD), sizeof sblk);
     44  1.1  minoura 
     45  1.1  minoura #ifdef DEBUG_WITH_STDIO
     46  1.1  minoura 	printf("LFS: sblk: magic: 0x%x, version: %d\n",
     47  1.1  minoura 		sblk.dlfs_magic, sblk.dlfs_version);
     48  1.1  minoura #endif
     49  1.1  minoura 
     50  1.1  minoura 	if (sblk.dlfs_magic != LFS_MAGIC)
     51  1.1  minoura 		return 1;
     52  1.1  minoura 
     53  1.1  minoura #ifdef DEBUG_WITH_STDIO
     54  1.1  minoura 	printf("sboff[1]: %d\n", sblk.dlfs_sboffs[1]);
     55  1.1  minoura #endif
     56  1.1  minoura 
     57  1.1  minoura 	if (sblk.dlfs_sboffs[1] > 0) {
     58  1.1  minoura 		/* read secondary superblock */
     59  1.1  minoura 		RAW_READ(&sblk2,
     60  1.1  minoura 			 (unsigned int) sblk.dlfs_sboffs[1], sizeof sblk2);
     61  1.1  minoura 
     62  1.1  minoura #ifdef DEBUG_WITH_STDIO
     63  1.1  minoura 		printf("LFS: sblk2: magic: 0x%x, version: %d\n",
     64  1.1  minoura 			sblk2.dlfs_magic, sblk2.dlfs_version);
     65  1.1  minoura #endif
     66  1.1  minoura 
     67  1.1  minoura 		if (sblk2.dlfs_magic == LFS_MAGIC &&
     68  1.1  minoura 		    sblk.dlfs_tstamp > sblk2.dlfs_tstamp)
     69  1.1  minoura 			s = &sblk2;
     70  1.1  minoura 	}
     71  1.1  minoura 
     72  1.1  minoura 	/* This partition looks like an LFS. */
     73  1.1  minoura 	fsi.get_inode = get_lfs_inode;
     74  1.1  minoura 	/* Disk addr in inode is in disk sector --- no shifting. */
     75  1.1  minoura 	fsi.iblkshift = 0;
     76  1.1  minoura 
     77  1.1  minoura 	/* Get information from the superblock. */
     78  1.1  minoura 	fsi.bsize = s->dlfs_bsize;
     79  1.1  minoura 	fsi.fsbtodb = s->dlfs_fsbtodb;
     80  1.1  minoura 	fsi.nindir = s->dlfs_nindir;
     81  1.1  minoura 
     82  1.1  minoura 	fsi_lfs.idaddr = s->dlfs_idaddr;
     83  1.1  minoura 	fsi_lfs.inopb = s->dlfs_inopb;
     84  1.1  minoura 	fsi_lfs.ifpb = s->dlfs_ifpb;
     85  1.1  minoura 	fsi_lfs.cleansz = s->dlfs_cleansz;
     86  1.1  minoura 	fsi_lfs.segtabsz = s->dlfs_segtabsz;
     87  1.1  minoura 
     88  1.1  minoura 	/* ifile is always used to look-up other inodes, so keep its inode. */
     89  1.1  minoura 	if (get_lfs_inode(LFS_IFILE_INUM, &ifile_dinode))
     90  1.1  minoura 		return 1;	/* OOPS, failed to find inode of ifile! */
     91  1.1  minoura 
     92  1.1  minoura 	fsi.fstype = UFSTYPE_LFS;
     93  1.1  minoura 
     94  1.1  minoura 	return 0;
     95  1.1  minoura }
     96  1.1  minoura 
     97  1.1  minoura /*
     98  1.1  minoura  * Get inode from disk.
     99  1.1  minoura  */
    100  1.1  minoura static int
    101  1.1  minoura get_lfs_inode(ino, dibuf)
    102  1.1  minoura 	ino_t ino;
    103  1.1  minoura 	struct dinode *dibuf;
    104  1.1  minoura {
    105  1.1  minoura 	struct ufs_info *ufsinfo = &ufs_info;
    106  1.1  minoura 	ufs_daddr_t daddr;
    107  1.1  minoura 	char *buf = alloca(fsi.bsize);
    108  1.1  minoura 	struct dinode *di;
    109  1.1  minoura 	int cnt;
    110  1.1  minoura 
    111  1.1  minoura 	/* Get fs block which contains the specified inode. */
    112  1.1  minoura 	if (ino == LFS_IFILE_INUM)
    113  1.1  minoura 		daddr = fsi_lfs.idaddr;
    114  1.1  minoura 	else {
    115  1.1  minoura #ifdef DEBUG_WITH_STDIO
    116  1.1  minoura 	printf("LFS: ino: %d\nifpb: %d, cleansz: %d, segtabsz: %d, bsize: %d\n",
    117  1.1  minoura 	    ino, fsi_lfs.ifpb, fsi_lfs.cleansz, fsi_lfs.segtabsz, fsi.bsize);
    118  1.1  minoura #endif
    119  1.1  minoura 		ufs_read(&ifile_dinode, buf,
    120  1.1  minoura 			 ino / fsi_lfs.ifpb + fsi_lfs.cleansz +
    121  1.1  minoura 				fsi_lfs.segtabsz,
    122  1.1  minoura 			 fsi.bsize);
    123  1.1  minoura 		daddr = ((IFILE *) buf + ino % fsi_lfs.ifpb)->if_daddr;
    124  1.1  minoura 	}
    125  1.1  minoura #ifdef DEBUG_WITH_STDIO
    126  1.1  minoura 	printf("LFS(%d): daddr: %d\n", ino, daddr);
    127  1.1  minoura #endif
    128  1.1  minoura 
    129  1.1  minoura 	if (daddr == LFS_UNUSED_DADDR)
    130  1.1  minoura 		return 1;
    131  1.1  minoura 
    132  1.1  minoura 	/* Read the inode block. */
    133  1.1  minoura 	RAW_READ(buf, (unsigned int) daddr, fsi.bsize);
    134  1.1  minoura 
    135  1.1  minoura 	/* Search for the inode. */
    136  1.1  minoura 	cnt = fsi_lfs.inopb;
    137  1.1  minoura 	di = (struct dinode *) buf + (cnt - 1);
    138  1.1  minoura 
    139  1.1  minoura 	for ( ; cnt--; di--)
    140  1.1  minoura 		if (di->di_inumber == ino)
    141  1.1  minoura 			goto found;
    142  1.1  minoura 	/* not found */
    143  1.1  minoura 	return 1;
    144  1.1  minoura 
    145  1.1  minoura found:
    146  1.1  minoura #ifdef DEBUG_WITH_STDIO
    147  1.1  minoura 	printf("LFS: dinode(%d): mode 0%o, nlink %d, inumber %d, size %d, uid %d, gid %d, db[0] %d\n",
    148  1.1  minoura 		ino, di->di_mode, di->di_nlink, di->di_inumber,
    149  1.1  minoura 		(int)di->di_size, di->di_uid, di->di_gid, di->di_db[0]);
    150  1.1  minoura #endif
    151  1.1  minoura 
    152  1.1  minoura 	*dibuf = *di;
    153  1.1  minoura 
    154  1.1  minoura 	return 0;
    155  1.1  minoura }
    156