Blob


1 /*
2 * An FFS file system is a sequence of cylinder groups.
3 *
4 * Each cylinder group is laid out as follows:
5 *
6 * fs superblock (Fsblk)
7 * cylinder group block (Cgblk)
8 * inodes
9 * data
10 *
11 * The location of the fs superblock in the first cylinder
12 * group is known. The rest of the info about cylinder group
13 * layout can be derived from the super block.
14 */
16 #define daddr_t u32int
17 #define time_t u32int
19 typedef struct Cgblk Cgblk;
20 typedef struct Cylgrp Cylgrp;
21 typedef struct Cylsum Cylsum;
22 typedef struct Cylsumtotal Cylsumtotal;
23 typedef struct Ffs Ffs;
24 typedef struct Fsblk Fsblk;
25 typedef struct Inode1 Inode1;
26 typedef struct Inode Inode;
27 typedef struct Dirent Dirent;
29 enum
30 {
31 BYTESPERSEC = 512,
33 /* constants for Fsblk */
34 FSMAXMNTLEN = 512,
35 FSMAXMNTLEN2 = 468,
36 FSMAXVOLLEN = 32, /* UFS2 */
37 FSNOCSPTRSLEN = 128-12,
38 FSNOCSPTRSLEN2 = 128-16, /* UFS2 */
39 FSMAXSNAP = 20,
40 FSMAGIC = 0x011954,
41 FSMAGIC2 = 0x19540119,
42 FSCHECKSUM = 0x7c269d38,
44 /* Fsblk.inodefmt */
45 FS42INODEFMT = -1,
46 FS44INODEFMT = 2,
48 /* offset and size of first boot block */
49 BBOFF = 0,
50 BBSIZE = 8192,
52 /* offset and size of first super block */
53 SBOFF = BBOFF+BBSIZE,
54 SBOFF2 = BBOFF+65536, /* UFS2 */
55 SBOFFPIGGY = BBOFF+262144, /* UFS2 */
56 SBSIZE = 8192,
58 /* minimum block size */
59 MINBSIZE = 4096,
61 /* maximum fragments per block */
62 MAXFRAG = 8,
64 /* constants for Cgblk */
65 CGMAGIC = 0x090255,
67 /* inode-related */
68 ROOTINODE = 2,
69 WHITEOUT = 1,
71 NXADDR = 2, /* UFS2 */
72 NDADDR = 12,
73 NIADDR = 3,
75 /* permissions in Inode.mode */
76 IEXEC = 00100,
77 IWRITE = 0200,
78 IREAD = 0400,
79 ISVTX = 01000,
80 ISGID = 02000,
81 ISUID = 04000,
83 /* type in Inode.mode */
84 IFMT = 0170000,
85 IFIFO = 0010000,
86 IFCHR = 0020000,
87 IFDIR = 0040000,
88 IFBLK = 0060000,
89 IFREG = 0100000,
90 IFLNK = 0120000,
91 IFSOCK = 0140000,
92 IFWHT = 0160000,
94 /* type in Dirent.type */
95 DTUNKNOWN = 0,
96 DTFIFO = 1,
97 DTCHR = 2,
98 DTDIR = 4,
99 DTBLK = 6,
100 DTREG = 8,
101 DTLNK = 10,
102 DTSOCK = 12,
103 DTWHT = 14
104 };
106 struct Cylsum
108 u32int ndir;
109 u32int nbfree;
110 u32int nifree;
111 u32int nffree;
112 };
114 struct Cylsumtotal
116 u64int ndir;
117 u64int nbfree;
118 u64int nifree;
119 u64int nffree;
120 u64int numclusters;
121 u64int unused[3];
122 };
124 /* Fields beginning with underscore are deprecated in UFS2 */
125 struct Fsblk
127 u32int unused0;
128 u32int unused1;
129 daddr_t sfragno; /* fragment address of super block in file system */
130 daddr_t cfragno; /* fragment address if cylinder block in file system */
131 daddr_t ifragno; /* fragment offset of inode blocks in file system */
132 daddr_t dfragno; /* fragment offset of data blocks in cg */
133 u32int _cgoffset; /* block (maybe fragment?) offset of Cgblk in cylinder */
134 u32int _cgmask;
135 time_t _time;
136 u32int _nfrag; /* number of blocks in fs * fragsperblock */
137 u32int _ndfrag;
138 u32int ncg; /* number of cylinder groups in fs */
139 u32int blocksize; /* block size in fs */
140 u32int fragsize; /* frag size in fs */
141 u32int fragsperblock; /* fragments per block: blocksize / fragsize */
142 u32int minfree; /* ignored by us */
143 u32int rotdelay; /* ... */
144 u32int rps;
145 u32int bmask;
146 u32int fmask;
147 u32int bshift;
148 u32int fshift;
149 u32int maxcontig;
150 u32int maxbpg;
151 u32int fragshift;
152 u32int fsbtodbshift;
153 u32int sbsize; /* size of super block */
154 u32int unused2; /* more stuff we don't use ... */
155 u32int unused3;
156 u32int nindir;
157 u32int inosperblock; /* inodes per block */
158 u32int _nspf;
159 u32int optim;
160 u32int _npsect;
161 u32int _interleave;
162 u32int _trackskew;
163 u32int id[2];
164 daddr_t _csaddr; /* blk addr of cyl grp summary area */
165 u32int cssize; /* size of cyl grp summary area */
166 u32int cgsize; /* cylinder group size */
167 u32int _trackspercyl; /* tracks per cylinder */
168 u32int _secspertrack; /* sectors per track */
169 u32int _secspercyl; /* sectors per cylinder */
170 u32int _ncyl; /* cylinders in fs */
171 u32int _cylspergroup; /* cylinders per group */
172 u32int inospergroup; /* inodes per group */
173 u32int fragspergroup; /* data blocks per group * fragperblock */
174 Cylsum _cstotal; /* more unused... */
175 u8int fmod;
176 u8int clean;
177 u8int ronly;
178 u8int _flags;
179 /* char fsmnt[512]; in UFS1 */
180 char fsmnt[FSMAXMNTLEN2];
181 char volname[FSMAXVOLLEN];
182 u64int swuid;
183 u32int pad;
184 u32int cgrotor;
185 uchar ocsp[FSNOCSPTRSLEN]; /* last 4 bytes is contigdirs in UFS2 */
186 u32int contigdirs; /* csp in UFS2 */
187 u32int csp; /* maxcluster in UFS2 */
188 u32int maxcluster; /* active in UFS2 */
189 u32int _cpc;
190 /* u16int opostbl[16][8]; in UFS1 */
191 u32int maxbsize;
192 u64int spare64[17];
193 u64int sblockloc;
194 Cylsumtotal cstotal;
195 u64int time;
196 u64int nfrag;
197 u64int ndfrag;
198 u64int csaddr;
199 u64int pendingblocks;
200 u32int pendinginodes;
201 u32int snapinum[FSMAXSNAP];
202 u32int avgfilesize;
203 u32int avgfpdir;
204 /* u32int sparecon[26], pendingblocks, pendinginodes; in UFS1 */
205 u32int savecgsize;
206 u32int sparecon[26];
207 u32int flags;
208 u32int contigsumsize;
209 u32int maxsymlinklen;
210 u32int _inodefmt; /* format of on-disk inodes */
211 u64int maxfilesize; /* maximum representable file size */
212 u64int qbmask;
213 u64int qfmask;
214 u32int state;
215 u32int _postblformat;
216 u32int _nrpos;
217 u32int _postbloff;
218 u32int _rotbloff;
219 u32int magic; /* FSMAGIC or FSMAGIC2 */
220 };
222 /*
223 * Cylinder group block for a file system.
224 */
225 struct Cgblk
227 u32int unused0;
228 u32int magic; /* CGMAGIC */
229 u32int time; /* time last written */
230 u32int num; /* we are cg #cgnum */
231 u16int ncyl; /* number of cylinders in gp */
232 u16int nino; /* number of inodes */
233 u32int nfrag; /* number of fragments */
234 Cylsum csum;
235 u32int rotor;
236 u32int frotor;
237 u32int irotor;
238 u32int frsum[MAXFRAG]; /* counts of available frags */
239 u32int btotoff;
240 u32int boff;
241 u32int imapoff; /* offset to used inode map */
242 u32int fmapoff; /* offset to free fragment map */
243 u32int nextfrag; /* next free fragment */
244 u32int csumoff;
245 u32int clusteroff;
246 u32int ncluster;
247 u32int sparecon[13];
248 };
250 struct Cylgrp
252 /* these are block numbers not fragment numbers */
253 u64int bno; /* disk block address of start of cg */
254 u64int ibno; /* disk block address of first inode */
255 u64int dbno; /* disk block address of first data */
256 u64int cgblkno;
257 };
259 /*
260 * this is the on-disk structure
261 */
262 struct Inode1
264 u16int mode;
265 u16int nlink;
266 u32int unused;
267 u64int size;
268 u32int atime;
269 u32int atimensec;
270 u32int mtime;
271 u32int mtimensec;
272 u32int ctime;
273 u32int ctimensec;
274 /* rdev is db[0] */
275 u32int db[NDADDR];
276 u32int ib[NIADDR];
277 u32int flags;
278 u32int nblock;
279 u32int gen;
280 u32int uid;
281 u32int gid;
282 u32int spare[2];
283 };
285 struct Inode
287 u16int mode;
288 u16int nlink;
289 u32int uid;
290 u32int gid;
291 u32int blksize;
292 u64int size;
293 u64int nblock;
294 u64int atime;
295 u64int mtime;
296 u64int ctime;
297 u64int btime;
298 u32int atimensec;
299 u32int mtimensec;
300 u32int ctimensec;
301 u32int btimensec;
302 u32int gen;
303 u32int kernflags;
304 u32int flags;
305 u32int extsize;
306 u64int ext[NXADDR];
307 u64int db[NDADDR];
308 u64int ib[NIADDR];
309 u64int spare[3];
310 };
312 struct Dirent
314 u32int ino;
315 u16int reclen;
316 u8int type;
317 u8int namlen;
318 char name[1];
319 };
321 /*
322 * main file system structure
323 */
324 struct Ffs
326 int ufs;
327 int blocksize;
328 u64int nblock;
329 int fragsize;
330 int fragsperblock;
331 int inosperblock;
332 u64int blockspergroup;
333 u64int fragspergroup;
334 int inospergroup;
336 u64int nfrag;
337 u64int ndfrag;
339 int ncg;
340 Cylgrp *cg;
342 Disk *disk;
343 };