Home | History | Annotate | Line # | Download | only in boot_ufs
readufs_ffs.c revision 1.14
      1  1.14  dholland /*	$NetBSD: readufs_ffs.c,v 1.14 2013/06/23 02:06:05 dholland Exp $	*/
      2   1.3     itohy /*	from Id: readufs_ffs.c,v 1.6 2003/04/08 09:19:32 itohy Exp 	*/
      3   1.1   minoura 
      4   1.1   minoura /*
      5   1.1   minoura  * FS specific support for 4.2BSD Fast Filesystem
      6   1.1   minoura  *
      7  1.13     itohy  * Written in 1999, 2002, 2003 by ITOH Yasufumi.
      8   1.1   minoura  * Public domain.
      9   1.1   minoura  *
     10   1.1   minoura  * Intended to be used for boot programs (first stage).
     11   1.1   minoura  * DON'T ADD ANY FANCY FEATURE.  THIS SHALL BE COMPACT.
     12   1.1   minoura  */
     13   1.1   minoura 
     14   1.3     itohy #include "readufs.h"
     15   1.3     itohy 
     16   1.1   minoura #include <ufs/ffs/fs.h>
     17   1.1   minoura 
     18  1.10       dsl static int get_ffs_inode(ino32_t ino, union ufs_dinode *dibuf);
     19   1.1   minoura 
     20   1.1   minoura #define fsi	(*ufsinfo)
     21   1.1   minoura #define fsi_ffs	fsi.fs_u.u_ffs
     22   1.1   minoura 
     23   1.1   minoura /*
     24   1.1   minoura  * Read and check superblock.
     25   1.1   minoura  * If it is an FFS, save information from the superblock.
     26   1.1   minoura  */
     27   1.1   minoura int
     28  1.12    cegger try_ffs(void)
     29   1.1   minoura {
     30   1.1   minoura 	union {
     31   1.1   minoura 		struct fs	sblk;
     32   1.3     itohy 		unsigned char	pad[SBLOCKSIZE];
     33   1.1   minoura 	} buf;
     34   1.1   minoura 	struct ufs_info *ufsinfo = &ufs_info;
     35   1.3     itohy 	static const int sblocs[] = SBLOCKSEARCH;
     36   1.3     itohy 	const int *sbl;
     37   1.3     itohy 	int magic;
     38   1.1   minoura 
     39   1.1   minoura #ifdef DEBUG_WITH_STDIO
     40   1.1   minoura 	printf("trying FFS\n");
     41   1.1   minoura #endif
     42   1.1   minoura 	/* read FFS superblock */
     43   1.3     itohy 	for (sbl = sblocs; ; sbl++) {
     44   1.3     itohy 		if (*sbl == -1)
     45   1.3     itohy 			return 1;
     46   1.1   minoura 
     47   1.3     itohy 		RAW_READ(&buf, (daddr_t) btodb(*sbl), SBLOCKSIZE);
     48   1.3     itohy 
     49   1.3     itohy 		magic = buf.sblk.fs_magic;
     50   1.1   minoura #ifdef DEBUG_WITH_STDIO
     51   1.3     itohy 		printf("FFS: sblk: pos %d magic 0x%x\n", btodb(*sbl), magic);
     52   1.1   minoura #endif
     53   1.7       dsl #ifdef USE_UFS1
     54   1.7       dsl 		if (magic == FS_UFS1_MAGIC
     55   1.7       dsl 		    && !(buf.sblk.fs_old_flags & FS_FLAGS_UPDATED)) {
     56   1.6       dsl 			if (*sbl == SBLOCK_UFS2)
     57   1.6       dsl 				/* might be an alternate suberblock */
     58   1.6       dsl 				continue;
     59   1.7       dsl 			break;
     60   1.6       dsl 		}
     61   1.7       dsl #endif
     62   1.7       dsl 		if (*sbl != buf.sblk.fs_sblockloc)
     63   1.7       dsl 			/* must be an alternate suberblock */
     64   1.7       dsl 			continue;
     65   1.1   minoura 
     66   1.3     itohy #ifdef USE_UFS1
     67   1.7       dsl 		if (magic == FS_UFS1_MAGIC) {
     68   1.3     itohy 			break;
     69   1.7       dsl 		}
     70   1.3     itohy #endif
     71   1.3     itohy #ifdef USE_UFS2
     72   1.3     itohy 		if (magic == FS_UFS2_MAGIC) {
     73   1.3     itohy #ifdef USE_UFS1
     74   1.3     itohy 			fsi.ufstype = UFSTYPE_UFS2;
     75   1.3     itohy #endif
     76   1.3     itohy 			break;
     77   1.3     itohy 		}
     78   1.3     itohy #endif
     79   1.3     itohy 	}
     80   1.3     itohy 
     81   1.3     itohy 	/*
     82   1.3     itohy 	 * XXX <ufs/ffs/fs.h> always uses fs_magic
     83   1.3     itohy 	 * (UFS1 only or UFS2 only is impossible)
     84   1.3     itohy 	 */
     85   1.3     itohy 	fsi_ffs.magic = magic;
     86   1.3     itohy #ifdef DEBUG_WITH_STDIO
     87   1.3     itohy 	printf("FFS: detected UFS%d format\n", (magic == FS_UFS2_MAGIC) + 1);
     88   1.3     itohy #endif
     89   1.1   minoura 
     90   1.1   minoura 	/* This partition looks like an FFS. */
     91   1.1   minoura 	fsi.fstype = UFSTYPE_FFS;
     92   1.1   minoura 	fsi.get_inode = get_ffs_inode;
     93   1.1   minoura 
     94   1.1   minoura 	/* Get information from the superblock. */
     95   1.1   minoura 	fsi.bsize = buf.sblk.fs_bsize;
     96   1.1   minoura 	fsi.fsbtodb = buf.sblk.fs_fsbtodb;
     97   1.1   minoura 	fsi.nindir = buf.sblk.fs_nindir;
     98   1.1   minoura 
     99   1.1   minoura 	fsi_ffs.iblkno = buf.sblk.fs_iblkno;
    100   1.3     itohy 	fsi_ffs.old_cgoffset = buf.sblk.fs_old_cgoffset;
    101   1.3     itohy 	fsi_ffs.old_cgmask = buf.sblk.fs_old_cgmask;
    102   1.1   minoura 	fsi_ffs.fragshift = buf.sblk.fs_fragshift;
    103   1.1   minoura 	fsi_ffs.inopb = buf.sblk.fs_inopb;
    104   1.1   minoura 	fsi_ffs.ipg = buf.sblk.fs_ipg;
    105   1.1   minoura 	fsi_ffs.fpg = buf.sblk.fs_fpg;
    106   1.1   minoura 
    107   1.1   minoura 	return 0;
    108   1.1   minoura }
    109   1.1   minoura 
    110   1.1   minoura /* for inode macros */
    111   1.1   minoura #define fs_ipg		fs_u.u_ffs.ipg
    112   1.1   minoura #define fs_iblkno	fs_u.u_ffs.iblkno
    113   1.3     itohy #define fs_old_cgoffset	fs_u.u_ffs.old_cgoffset
    114   1.3     itohy #define fs_old_cgmask	fs_u.u_ffs.old_cgmask
    115   1.1   minoura #define fs_fpg		fs_u.u_ffs.fpg
    116   1.3     itohy #define fs_magic	fs_u.u_ffs.magic
    117   1.1   minoura #define fs_inopb	fs_u.u_ffs.inopb
    118   1.1   minoura #define fs_fragshift	fs_u.u_ffs.fragshift
    119   1.1   minoura #define fs_fsbtodb	fsbtodb
    120   1.1   minoura 
    121   1.1   minoura /*
    122   1.1   minoura  * Get inode from disk.
    123   1.1   minoura  */
    124   1.1   minoura static int
    125  1.11       dsl get_ffs_inode(ino32_t ino, union ufs_dinode *dibuf)
    126   1.1   minoura {
    127   1.1   minoura 	struct ufs_info *ufsinfo = &ufs_info;
    128   1.3     itohy 	union ufs_dinode *buf = alloca((size_t) fsi.bsize);
    129   1.3     itohy 	union ufs_dinode *di;
    130   1.3     itohy 	unsigned ioff;
    131   1.1   minoura 
    132  1.14  dholland 	RAW_READ(buf, FFS_FSBTODB(&fsi, ino_to_fsba(&fsi, ino)),
    133   1.1   minoura 			(size_t) fsi.bsize);
    134   1.1   minoura 
    135   1.3     itohy 	ioff = ino_to_fsbo(&fsi, ino);
    136   1.3     itohy 
    137   1.3     itohy #if defined(USE_UFS1) && defined(USE_UFS2)
    138   1.3     itohy 	if (ufsinfo->ufstype == UFSTYPE_UFS1)
    139   1.3     itohy 		di = (void *) &(&buf->di1)[ioff];
    140   1.3     itohy 	else {
    141   1.3     itohy 		di = (void *) &(&buf->di2)[ioff];
    142   1.3     itohy 
    143   1.3     itohy 		/* XXX for DI_SIZE() macro */
    144   1.3     itohy 		di->di1.di_size = di->di2.di_size;
    145   1.3     itohy 	}
    146   1.3     itohy #else
    147   1.3     itohy 	di = &buf[ioff];
    148   1.3     itohy #endif
    149   1.3     itohy 
    150   1.1   minoura #ifdef DEBUG_WITH_STDIO
    151   1.3     itohy 	printf("FFS: dinode(%d): mode 0%o, nlink %d, size %u\n",
    152   1.3     itohy 		ino, di->di_common.di_mode, di->di_common.di_nlink,
    153   1.3     itohy 		(unsigned) DI_SIZE(di));
    154   1.1   minoura #endif
    155   1.1   minoura 
    156   1.3     itohy 	if (di->di_common.di_mode == 0)
    157   1.1   minoura 		return 1;	/* unused inode (file is not found) */
    158   1.1   minoura 
    159   1.1   minoura 	*dibuf = *di;
    160   1.1   minoura 
    161   1.1   minoura 	return 0;
    162   1.1   minoura }
    163