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