UFS1 Superblock
The superblock contains the basic file system category of data in a UFS file system and UFS1 and UFS2 use different data structures. The UFS1 superblock is located in sector 16 and is allocated 2,048 bytes, but most of it is not essential or is zero. I am going to discuss only the essential data, but all the fields are included in the following table, if only to show how many non-essential values there are. The fields in the UFS1 superblock that are used by FreeBSD, NetBSD, and OpenBSD are shown in Table 17.1.
Byte Range |
Description |
Essential |
---|---|---|
07 |
Unused |
No |
811 |
Offset to backup superblock in cylinder group relative to a "base" |
Yes |
1215 |
Offset to group descriptor in cylinder group relative to a "base" |
Yes |
1619 |
Offset to inode table in cylinder group relative to a "base" |
Yes |
2023 |
Offset to first data block in cylinder group relative to a "base" |
No |
2427 |
Delta value for calculating staggering offset in cylinder group |
Yes |
2831 |
Mask for calculating staggering offset (cycle value) in cylinder group |
Yes |
3235 |
Last written time |
No |
3639 |
Number of fragments in file system |
Yes |
4043 |
Number of fragments that can store file data |
No |
4447 |
Number of cylinder groups in file system |
Yes |
4851 |
Size of a block in bytes |
Yes |
5255 |
Size of a fragment in bytes |
Yes |
5659 |
Size of a block in fragments |
No |
6063 |
Minimum percent of free blocks |
No |
6467 |
Milliseconds of rotation for next block |
No |
6871 |
Disk RPMs |
No |
7275 |
Mask used to calculate the address for a block |
No |
7679 |
Mask used to calculate the address for a fragment |
No |
8083 |
Shift used to calculate the byte address for a block |
No |
8487 |
Shift used to calculate the byte address for a fragment |
No |
8891 |
Maximum number of contiguous blocks to allocate |
No |
9295 |
Maximum number of blocks per cylinder group per file |
No |
9699 |
Number of bits to convert between a block address and a fragment address |
No |
100103 |
Number of bits to convert between a fragment address and a sector address |
No |
104107 |
Size of superblock |
No |
108111 |
Offset to cylinder summary area (no longer used) |
No |
112115 |
Size of cylinder summary area (no longer used) |
No |
116119 |
Number of indirect addresses per fragment |
No |
120123 |
Number of inodes per block in inode table |
No |
124127 |
Number of sectors per fragment |
No |
128131 |
Optimization technique |
No |
132135 |
Sectors per track |
No |
136139 |
Hard disk sector interleave |
No |
140143 |
Hard disk track skew |
No |
144151 |
File System ID |
No |
152155 |
Fragment address of cylinder group summary area |
No |
156159 |
Size of cylinder group summary area in bytes |
No |
160163 |
Size of cylinder group descriptor in bytes |
No |
164167 |
Hard disk tracks per cylinder |
No |
168171 |
Hard disk sectors per track |
No |
172175 |
Hard disk sectors per cylinder |
No |
176179 |
Cylinders in file system |
No |
180183 |
Cylinders per cylinder group |
No |
184187 |
Inodes per cylinder group |
Yes |
188191 |
Fragments per cylinder group |
Yes |
192195 |
Number of directories |
No |
196199 |
Number of free blocks |
No |
200203 |
Number of free inodes |
No |
204207 |
Number of free fragments |
No |
208208 |
Super block modified flag |
No |
209209 |
FS was clean when it was mounted |
No |
210210 |
Mounted read only flag (set to 1 if read only) |
No |
211211 |
General flags (see Table 17.2) |
No |
212723 |
Last mount point |
No |
724727 |
Last cylinder group searched |
No |
7281115 |
Unused |
No |
11161195 |
Array inode addresses for snap shot inodes |
No |
11961199 |
Expected average file size |
No |
12001203 |
Expected number of files per directory |
No |
12041311 |
Unused |
No |
13121315 |
Last time fsck was run |
No |
1316 1319 |
Size of cluster summary array in group descriptors |
No |
13201323 |
Maximum length of internal symbolic link |
Yes |
13241327 |
Format of inodes |
Yes |
13281335 |
Maximum file size |
No |
13361343 |
Mask used to calculate the offset in a block for an address |
No |
13441351 |
Mask used to calculate the offset in a fragment for an address |
No |
13521355 |
File system state |
No |
13561359 |
Format of positional layout tables |
No |
13601363 |
Number of rotational positions |
No |
13641367 |
Rotational block list head |
No |
13681371 |
Blocks for each rotation |
No |
13721375 |
Signature value (0x011954) |
Yes |
Flag Value |
Description |
Essential |
---|---|---|
0x01 |
Uncleanset when file system is mounted |
No |
0x02 |
Soft dependencies are being used |
No |
0x04 |
Needs consistency check next time it is mounted |
No |
0x08 |
Directories are indexed using hashtree or B-Tree |
No |
0x10 |
Access Control Lists are being used |
No |
0x20 |
TrustedBSD Mandatory Access Control multi-labels are being used |
No |
0x80 |
Flags have been moved (used by UFS2 in the "old" field) |
No |
The first fields give the offsets that are used to locate data structures inside each cylinder group. We also can see the delta and cycle values that are used to calculate the base address for each cylinder group in UFS1. The standard total number of blocks, fragments, and cylinder groups is given, sometimes in multiple formats. The number of inodes and fragments per cylinder group is given later in the superblock.
Byte 128 has a field for the block allocation optimization technique. There are currently two values for this field. If set to 0, the OS should try to save time when allocating new blocks, which might cause wasted space and fragmentation as the file system fills up. If set to 1, the OS should try to save space when allocating new blocks and find an ideal-sized location. This might take more time though when creating files. Knowing this might help during file recovery.
There are several flags starting at byte 208. The first flag is set when the superblock has been modified and is cleared when mounted. The flag in byte 209 is set to 0 if the file system was clean when it was mounted. The flag in byte 210 is set to 1 if the file system was mounted read only. Lastly, the flag in byte 211 is a general flag and can contain any of the values given in Table 17.2.
There is also a field at byte 1234 to 1237 that identifies which type of inode is used to store file metadata. If the field is 2, it is the 4.4BSD inode, and if it is 0xffffffff, it is the 4.2BSD inode. The other data in the superblock are non-essential and might or might not contain valid data.
Let's take a look at an OpenBSD system. The superblock is in sector 16 and is allocated four sectors, so we use the following dd command:
# dd if=openbsd1.dd bs=512 skip=16 count=4 | xxd 0000000: 0000 0000 0000 0000 1000 0000 1800 0000 ................ 0000016: 2000 0000 1001 0000 2000 0000 f0ff ffff ....... ....... 0000032: dc9d 0f41 1027 0000 ff24 0000 0200 0000 ...A.'...$...... 0000048: 0020 0000 0004 0000 0800 0000 0500 0000 . .............. 0000064: 0000 0000 3c00 0000 00e0 ffff 00fc ffff ....<........... 0000080: 0d00 0000 0a00 0000 0700 0000 0008 0000 ................ 0000096: 0300 0000 0100 0000 0008 0000 00fe ffff ................ 0000112: 0900 0000 0008 0000 4000 0000 0200 0000 ........@....... 0000128: 0000 0000 3f00 0000 0100 0000 0000 0000 ....?........... 0000144: 2c9d 0f41 8f5a 19a2 1001 0000 0004 0000 ,..A.Z.......... 0000160: 0008 0000 1000 0000 3f00 0000 f003 0000 ........?....... 0000176: 1400 0000 1000 0000 8007 0000 801f 0000 ................ 0000192: 0400 0000 fe03 0000 e50e 0000 1000 0000 ................ 0000208: 0001 0000 2f6d 6e74 0000 0000 0000 0000 ..../mnt........ 0000224: 0000 0000 0000 0000 0000 0000 0000 0000 ................ [REMOVED] 0000832: 0000 0000 0000 0000 0000 0000 00e6 d2d0 ................ 0000848: 0038 d3d0 003c d3d0 0100 0000 0000 0000 .8...<.......... [REMOVED] 0001184: 0000 0000 0000 0000 0000 0000 0040 0000 .............@.. 0001200: 4000 0000 0000 0000 0000 0000 0000 0000 @............... [REMOVED] 0001312: 0000 0000 0700 0000 3c00 0000 0200 0000 ........<....... 0001328: ff7f 0101 0840 0000 ff1f 0000 0000 0000 .....@.......... 0001344: ff03 0000 0000 0000 0000 0000 0100 0000 ................ 0001360: 0100 0000 6005 0000 6205 0000 5419 0100 ....`...b...T... 0001376: 0000 0101 0101 0101 0101 0101 0101 0101 ................
This file system is from an IA32 system, so the bytes are in a little-endian ordering. If the file system were from a big-endian system, such as a Sparc system, the bytes in each numeric field would be reversed.
Bytes 8 to 11 show that the backup superblocks are located at an offset of 16 fragments (0x10) from the base of each cylinder group. Bytes 12 to 15 show that the group descriptor is located at an offset of 24 fragments (0x18) from the base, and bytes 16 to 19 show that the inode table starts 32 fragments (0x20) from the base.
To calculate the base of a UFS1 cylinder group, we start with bytes 24 to 27, which shows the delta value as 32 (0x20). This means that group 0 will have its base at fragment 0, and group 1 will have its base at fragment 32. Bytes 28 to 31 in the superblock show that the cycle mask is 0xfffffff0, which means that we care only about the final four bits of the group number. Therefore, after every 16 groups, we cycle back to the beginning and the base offset returns to fragment 0. In this case, group 15 will have a base offset of fragment 480, and group 16 will have a base offset of fragment 0.
Bytes 32 to 35 is the time that this was last written to, and the format is the number of seconds since January 1, 1970 GMT. Bytes 36 to 39 show that there are 10,000 (0x2710) fragments in the file system, and bytes 44 to 47 show that there are only two cylinder groups in this file system. The size of each block is given in bytes 48 to 51, and we see that it is 8,192 bytes (0x2000). The fragment size is in bytes 52 to 55, and it is 1,024 bytes (0x0400). To ensure you don't have to divide these two numbers, the number of fragments per block is given in bytes 56 to 59, which is 8.
Bytes 104 to 107 show that the superblock is 2,048 bytes (0x0800). Bytes 152 to 155 give the location of the cylinder group summary area, and it is located in fragment 272 of this file system. Its size is given in bytes 156 to 159, and we see that it is 1,024 bytes, or one fragment. Bytes 184 to 187 give the number of inodes per cylinder group, and there are 1,920 (0x0780) in this file system. The number of fragments per cylinder group is in bytes 188 to 191, and there are 8064 (0x1f80).
The flags start at byte 208 and the first byte is 0, which means that the superblock has been written after the last modification. Byte 209 shows that soft dependencies are used, and the flags in 210 and 211 are in their default state. Byte 212 starts the location of the last mount point, and this file system claims to have been last mounted at /mnt/. The remaining fields are left for you to enjoy processing. The fsstat tool output for this image was previously given in the "File System Category" section of Chapter 16.