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 /* some systems have these defined */
76 #undef IEXEC
77 #undef IWRITE
78 #undef IREAD
79 #undef ISVTX
80 #undef ISGID
81 #undef ISUID
82 #undef IFMT
83 #undef IFIFO
84 #undef IFCHR
85 #undef IFDIR
86 #undef IFBLK
87 #undef IFREG
88 #undef IFLNK
89 #undef IFSOCK
90 #undef IFWHT
92 #define IEXEC FFS_IEXEC
93 #define IWRITE FFS_IWRITE
94 #define IREAD FFS_IREAD
95 #define ISVTX FFS_ISVTX
96 #define ISGID FFS_ISGID
97 #define ISUID FFS_ISUID
98 #define IFMT FFS_IFMT
99 #define IFIFO FFS_IFIFO
100 #define IFCHR FFS_IFCHR
101 #define IFDIR FFS_IFDIR
102 #define IFBLK FFS_IFBLK
103 #define IFREG FFS_IFREG
104 #define IFLNK FFS_IFLNK
105 #define IFSOCK FFS_IFSOCK
106 #define IFWHT FFS_IFWHT
108 /* permissions in Inode.mode */
109 IEXEC = 00100,
110 IWRITE = 0200,
111 IREAD = 0400,
112 ISVTX = 01000,
113 ISGID = 02000,
114 ISUID = 04000,
116 /* type in Inode.mode */
117 IFMT = 0170000,
118 IFIFO = 0010000,
119 IFCHR = 0020000,
120 IFDIR = 0040000,
121 IFBLK = 0060000,
122 IFREG = 0100000,
123 IFLNK = 0120000,
124 IFSOCK = 0140000,
125 IFWHT = 0160000,
127 /* type in Dirent.type */
128 DTUNKNOWN = 0,
129 DTFIFO = 1,
130 DTCHR = 2,
131 DTDIR = 4,
132 DTBLK = 6,
133 DTREG = 8,
134 DTLNK = 10,
135 DTSOCK = 12,
136 DTWHT = 14
137 };
139 struct Cylsum
141 u32int ndir;
142 u32int nbfree;
143 u32int nifree;
144 u32int nffree;
145 };
147 struct Cylsumtotal
149 u64int ndir;
150 u64int nbfree;
151 u64int nifree;
152 u64int nffree;
153 u64int numclusters;
154 u64int unused[3];
155 };
157 /* Fields beginning with underscore are deprecated in UFS2 */
158 struct Fsblk
160 u32int unused0;
161 u32int unused1;
162 daddr_t sfragno; /* fragment address of super block in file system */
163 daddr_t cfragno; /* fragment address if cylinder block in file system */
164 daddr_t ifragno; /* fragment offset of inode blocks in file system */
165 daddr_t dfragno; /* fragment offset of data blocks in cg */
166 u32int _cgoffset; /* block (maybe fragment?) offset of Cgblk in cylinder */
167 u32int _cgmask;
168 time_t _time;
169 u32int _nfrag; /* number of blocks in fs * fragsperblock */
170 u32int _ndfrag;
171 u32int ncg; /* number of cylinder groups in fs */
172 u32int blocksize; /* block size in fs */
173 u32int fragsize; /* frag size in fs */
174 u32int fragsperblock; /* fragments per block: blocksize / fragsize */
175 u32int minfree; /* ignored by us */
176 u32int rotdelay; /* ... */
177 u32int rps;
178 u32int bmask;
179 u32int fmask;
180 u32int bshift;
181 u32int fshift;
182 u32int maxcontig;
183 u32int maxbpg;
184 u32int fragshift;
185 u32int fsbtodbshift;
186 u32int sbsize; /* size of super block */
187 u32int unused2; /* more stuff we don't use ... */
188 u32int unused3;
189 u32int nindir;
190 u32int inosperblock; /* inodes per block */
191 u32int _nspf;
192 u32int optim;
193 u32int _npsect;
194 u32int _interleave;
195 u32int _trackskew;
196 u32int id[2];
197 daddr_t _csaddr; /* blk addr of cyl grp summary area */
198 u32int cssize; /* size of cyl grp summary area */
199 u32int cgsize; /* cylinder group size */
200 u32int _trackspercyl; /* tracks per cylinder */
201 u32int _secspertrack; /* sectors per track */
202 u32int _secspercyl; /* sectors per cylinder */
203 u32int _ncyl; /* cylinders in fs */
204 u32int _cylspergroup; /* cylinders per group */
205 u32int inospergroup; /* inodes per group */
206 u32int fragspergroup; /* data blocks per group * fragperblock */
207 Cylsum _cstotal; /* more unused... */
208 u8int fmod;
209 u8int clean;
210 u8int ronly;
211 u8int _flags;
212 /* char fsmnt[512]; in UFS1 */
213 char fsmnt[FSMAXMNTLEN2];
214 char volname[FSMAXVOLLEN];
215 u64int swuid;
216 u32int pad;
217 u32int cgrotor;
218 uchar ocsp[FSNOCSPTRSLEN]; /* last 4 bytes is contigdirs in UFS2 */
219 u32int contigdirs; /* csp in UFS2 */
220 u32int csp; /* maxcluster in UFS2 */
221 u32int maxcluster; /* active in UFS2 */
222 u32int _cpc;
223 /* u16int opostbl[16][8]; in UFS1 */
224 u32int maxbsize;
225 u64int spare64[17];
226 u64int sblockloc;
227 Cylsumtotal cstotal;
228 u64int time;
229 u64int nfrag;
230 u64int ndfrag;
231 u64int csaddr;
232 u64int pendingblocks;
233 u32int pendinginodes;
234 u32int snapinum[FSMAXSNAP];
235 u32int avgfilesize;
236 u32int avgfpdir;
237 /* u32int sparecon[26], pendingblocks, pendinginodes; in UFS1 */
238 u32int savecgsize;
239 u32int sparecon[26];
240 u32int flags;
241 u32int contigsumsize;
242 u32int maxsymlinklen;
243 u32int _inodefmt; /* format of on-disk inodes */
244 u64int maxfilesize; /* maximum representable file size */
245 u64int qbmask;
246 u64int qfmask;
247 u32int state;
248 u32int _postblformat;
249 u32int _nrpos;
250 u32int _postbloff;
251 u32int _rotbloff;
252 u32int magic; /* FSMAGIC or FSMAGIC2 */
253 };
255 /*
256 * Cylinder group block for a file system.
257 */
258 struct Cgblk
260 u32int unused0;
261 u32int magic; /* CGMAGIC */
262 u32int time; /* time last written */
263 u32int num; /* we are cg #cgnum */
264 u16int ncyl; /* number of cylinders in gp */
265 u16int nino; /* number of inodes */
266 u32int nfrag; /* number of fragments */
267 Cylsum csum;
268 u32int rotor;
269 u32int frotor;
270 u32int irotor;
271 u32int frsum[MAXFRAG]; /* counts of available frags */
272 u32int btotoff;
273 u32int boff;
274 u32int imapoff; /* offset to used inode map */
275 u32int fmapoff; /* offset to free fragment map */
276 u32int nextfrag; /* next free fragment */
277 u32int csumoff;
278 u32int clusteroff;
279 u32int ncluster;
280 u32int sparecon[13];
281 };
283 struct Cylgrp
285 /* these are block numbers not fragment numbers */
286 u64int bno; /* disk block address of start of cg */
287 u64int ibno; /* disk block address of first inode */
288 u64int dbno; /* disk block address of first data */
289 u64int cgblkno;
290 };
292 /*
293 * this is the on-disk structure
294 */
295 struct Inode1
297 u16int mode;
298 u16int nlink;
299 u32int unused;
300 u64int size;
301 u32int atime;
302 u32int atimensec;
303 u32int mtime;
304 u32int mtimensec;
305 u32int ctime;
306 u32int ctimensec;
307 /* rdev is db[0] */
308 u32int db[NDADDR];
309 u32int ib[NIADDR];
310 u32int flags;
311 u32int nblock;
312 u32int gen;
313 u32int uid;
314 u32int gid;
315 u32int spare[2];
316 };
318 struct Inode
320 u16int mode;
321 u16int nlink;
322 u32int uid;
323 u32int gid;
324 u32int blksize;
325 u64int size;
326 u64int nblock;
327 u64int atime;
328 u64int mtime;
329 u64int ctime;
330 u64int btime;
331 u32int atimensec;
332 u32int mtimensec;
333 u32int ctimensec;
334 u32int btimensec;
335 u32int gen;
336 u32int kernflags;
337 u32int flags;
338 u32int extsize;
339 u64int ext[NXADDR];
340 u64int db[NDADDR];
341 u64int ib[NIADDR];
342 u64int spare[3];
343 };
345 struct Dirent
347 u32int ino;
348 u16int reclen;
349 u8int type;
350 u8int namlen;
351 char name[1];
352 };
354 /*
355 * main file system structure
356 */
357 struct Ffs
359 int ufs;
360 int blocksize;
361 u64int nblock;
362 int fragsize;
363 int fragsperblock;
364 int inosperblock;
365 u64int blockspergroup;
366 u64int fragspergroup;
367 int inospergroup;
369 u64int nfrag;
370 u64int ndfrag;
372 int ncg;
373 Cylgrp *cg;
375 Disk *disk;
376 };