readufs_ffs.c revision 1.15 1 1.15 chs /* $NetBSD: readufs_ffs.c,v 1.15 2022/11/17 06:40:39 chs 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.15 chs if (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_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.15 chs printf("FFS: detected UFS%d format\n",
88 1.15 chs (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) + 1);
89 1.3 itohy #endif
90 1.1 minoura
91 1.1 minoura /* This partition looks like an FFS. */
92 1.1 minoura fsi.fstype = UFSTYPE_FFS;
93 1.1 minoura fsi.get_inode = get_ffs_inode;
94 1.1 minoura
95 1.1 minoura /* Get information from the superblock. */
96 1.1 minoura fsi.bsize = buf.sblk.fs_bsize;
97 1.1 minoura fsi.fsbtodb = buf.sblk.fs_fsbtodb;
98 1.1 minoura fsi.nindir = buf.sblk.fs_nindir;
99 1.1 minoura
100 1.1 minoura fsi_ffs.iblkno = buf.sblk.fs_iblkno;
101 1.3 itohy fsi_ffs.old_cgoffset = buf.sblk.fs_old_cgoffset;
102 1.3 itohy fsi_ffs.old_cgmask = buf.sblk.fs_old_cgmask;
103 1.1 minoura fsi_ffs.fragshift = buf.sblk.fs_fragshift;
104 1.1 minoura fsi_ffs.inopb = buf.sblk.fs_inopb;
105 1.1 minoura fsi_ffs.ipg = buf.sblk.fs_ipg;
106 1.1 minoura fsi_ffs.fpg = buf.sblk.fs_fpg;
107 1.1 minoura
108 1.1 minoura return 0;
109 1.1 minoura }
110 1.1 minoura
111 1.1 minoura /* for inode macros */
112 1.1 minoura #define fs_ipg fs_u.u_ffs.ipg
113 1.1 minoura #define fs_iblkno fs_u.u_ffs.iblkno
114 1.3 itohy #define fs_old_cgoffset fs_u.u_ffs.old_cgoffset
115 1.3 itohy #define fs_old_cgmask fs_u.u_ffs.old_cgmask
116 1.1 minoura #define fs_fpg fs_u.u_ffs.fpg
117 1.3 itohy #define fs_magic fs_u.u_ffs.magic
118 1.1 minoura #define fs_inopb fs_u.u_ffs.inopb
119 1.1 minoura #define fs_fragshift fs_u.u_ffs.fragshift
120 1.1 minoura #define fs_fsbtodb fsbtodb
121 1.1 minoura
122 1.1 minoura /*
123 1.1 minoura * Get inode from disk.
124 1.1 minoura */
125 1.1 minoura static int
126 1.11 dsl get_ffs_inode(ino32_t ino, union ufs_dinode *dibuf)
127 1.1 minoura {
128 1.1 minoura struct ufs_info *ufsinfo = &ufs_info;
129 1.3 itohy union ufs_dinode *buf = alloca((size_t) fsi.bsize);
130 1.3 itohy union ufs_dinode *di;
131 1.3 itohy unsigned ioff;
132 1.1 minoura
133 1.14 dholland RAW_READ(buf, FFS_FSBTODB(&fsi, ino_to_fsba(&fsi, ino)),
134 1.1 minoura (size_t) fsi.bsize);
135 1.1 minoura
136 1.3 itohy ioff = ino_to_fsbo(&fsi, ino);
137 1.3 itohy
138 1.3 itohy #if defined(USE_UFS1) && defined(USE_UFS2)
139 1.3 itohy if (ufsinfo->ufstype == UFSTYPE_UFS1)
140 1.3 itohy di = (void *) &(&buf->di1)[ioff];
141 1.3 itohy else {
142 1.3 itohy di = (void *) &(&buf->di2)[ioff];
143 1.3 itohy
144 1.3 itohy /* XXX for DI_SIZE() macro */
145 1.3 itohy di->di1.di_size = di->di2.di_size;
146 1.3 itohy }
147 1.3 itohy #else
148 1.3 itohy di = &buf[ioff];
149 1.3 itohy #endif
150 1.3 itohy
151 1.1 minoura #ifdef DEBUG_WITH_STDIO
152 1.3 itohy printf("FFS: dinode(%d): mode 0%o, nlink %d, size %u\n",
153 1.3 itohy ino, di->di_common.di_mode, di->di_common.di_nlink,
154 1.3 itohy (unsigned) DI_SIZE(di));
155 1.1 minoura #endif
156 1.1 minoura
157 1.3 itohy if (di->di_common.di_mode == 0)
158 1.1 minoura return 1; /* unused inode (file is not found) */
159 1.1 minoura
160 1.1 minoura *dibuf = *di;
161 1.1 minoura
162 1.1 minoura return 0;
163 1.1 minoura }
164