Every file, directory and link has a header block, found through the hash table of its parent directory. Header blocks share one layout at their start and end; what lies between depends on the block’s secondary type. Offsets are for 512-byte blocks; all numbers are big-endian longs unless stated. Checksums and dates are described on the disk blocks page.
Block types
| Block | Type (offset 0) | Secondary type (offset 0x1FC) |
|---|---|---|
| Root | 2 T_HEADER | 1 ST_ROOT |
| Directory | 2 | 2 ST_USERDIR |
| Soft link | 2 | 3 ST_SOFTLINK |
| Hard link to a directory | 2 | 4 ST_LINKDIR |
| File header | 2 | −3 ST_FILE |
| Hard link to a file | 2 | −4 ST_LINKFILE |
| File extension | 16 T_LIST | −3 |
| OFS data | 8 T_DATA | – |
| Directory cache | 33 T_DIRC | – |
File header block
| Offset | Size | Name | Description |
|---|---|---|---|
0x000 | 4 | type | 2. |
0x004 | 4 | header_key | This block’s own number. |
0x008 | 4 | high_seq | How many data block pointers this block holds. |
0x00C | 4 | data_size | 0. |
0x010 | 4 | first_data | The first data block. |
0x014 | 4 | chksum | Block checksum. |
0x018 | 288 | data_blocks | 72 data block numbers, filled from the end: the first data block is at 0x134, the second at 0x130, and so on. |
0x138 | 4 | – | Unused. |
0x13C | 2 + 2 | UID, GID | User and group IDs (used by multi-user systems). |
0x140 | 4 | protect | Protection bits. |
0x144 | 4 | byte_size | The file’s size in bytes. |
0x148 | 1 | comm_len | Comment length. |
0x149 | 79 | comment | The file’s comment (its “file note”). |
0x198 | 12 | – | Unused. |
0x1A4 | 12 | days, mins, ticks | Last change. |
0x1B0 | 1 | name_len | Name length, at most 30. |
0x1B1 | 30 | filename | The name. |
0x1CF | 5 | – | Unused. |
0x1D4 | 4 | real_entry | 0 (used in link blocks). |
0x1D8 | 4 | next_link | FFS: the first hard link to this file (newest first); 0 if none. |
0x1DC | 20 | – | Unused. |
0x1F0 | 4 | hash_chain | The next entry in the same hash slot of the parent; 0 at the end. |
0x1F4 | 4 | parent | The parent directory’s header block. |
0x1F8 | 4 | extension | The first file extension block, for files with more than 72 data blocks; 0 otherwise. |
0x1FC | 4 | sec_type | −3. |
A file extension block has the same frame (type 16, header_key,
high_seq, checksum at 0x14, 72 more data block numbers from the end of the
table), unused space, then parent (the file header) at 0x1F4, the next
extension at 0x1F8 and −3 at 0x1FC.
Data blocks
Under FFS a data block is 512 bytes of the file and nothing else. Under OFS it has a 24-byte header and 488 bytes of data:
| Offset | Size | Name | Description |
|---|---|---|---|
0x00 | 4 | type | 8 (T_DATA). |
0x04 | 4 | header_key | The file header block. |
0x08 | 4 | seq_num | This block’s position in the file, from 1. |
0x0C | 4 | data_size | Bytes of data used, at most 488. |
0x10 | 4 | next_data | The next data block; 0 for the last. |
0x14 | 4 | chksum | Block checksum. |
0x18 | 488 | data | The data. |
Directory block
Like the file header, but the table at 0x18 is a hash table of the directory’s
entries rather than data blocks; there is no size; the date is that of the last change;
next_link (0x1D8) lists hard links to the directory; extension
(0x1F8) is the first directory cache block under FFS with the cache; and
sec_type is 2.
Links
- Hard link (
sec_type−4 to a file, 4 to a directory): the common frame with protection bits, comment, date and name, andreal_entry(0x1D4), the header block of the real file or directory;next_link(0x1D8) chains the links to the same target. - Soft link (
sec_type3): the path of the target as a zero-terminated string at 0x18, up to 288 bytes, then the common frame.
Directory cache
Disks with the directory cache (DOS types 4 and 5) keep a summary of each directory in cache blocks, so a listing needs fewer reads.
| Offset | Size | Name | Description |
|---|---|---|---|
0x00 | 4 | type | 33. |
0x04 | 4 | header_key | This block. |
0x08 | 4 | parent | The directory it describes. |
0x0C | 4 | records_nb | Number of records. |
0x10 | 4 | next_dirc | The next cache block; 0 for the last. |
0x14 | 4 | chksum | Block checksum. |
0x18 | 488 | Records | Packed records, below. |
| Offset | Size | Name | Description |
|---|---|---|---|
0 | 4 | header | The entry’s header block. |
4 | 4 | size | File size; 0 for directories and links. |
8 | 4 | protect | Protection bits. |
12 | 2 + 2 | UID, GID | Owner. |
16 | 6 | days, mins, ticks | The date, as three 16-bit numbers. |
22 | 1 | type | The entry’s secondary type. |
23 | 1 | name_len | 1 to 30. |
24 | n | name | The name. |
| 24 + n | 1 | comm_len | 0 to 22. |
| 25 + n | c | comment | The comment, then a padding byte if needed to keep the next record on an even offset. |
Name hashing
A directory finds a name through its 72-slot hash table:
- h = length of the name.
- For each character: h = (h × 13 + upper-case(character))
AND
0x7FF. - The slot is h mod 72.
Upper-casing maps only a–z on ordinary disks; in
international mode (DOS types 2 to 5) it also maps the Latin-1 letters 224–254 except
247 by subtracting 32. Entries that share a slot are chained through
hash_chain, and names are compared without regard to case.
Protection bits
| Bit | Letter | Meaning |
|---|---|---|
| 0 | D | Owner: deleting is forbidden when set |
| 1 | E | Owner: executing is forbidden when set |
| 2 | W | Owner: writing is forbidden when set |
| 3 | R | Owner: reading is forbidden when set |
| 4 | A | Archived |
| 5 | P | Pure: re-entrant, may be made resident |
| 6 | S | Script: run by the shell or ARexx |
| 7 | H | Hold: made resident on first use (AmigaOS 2 and 3) |
| 8–11 | D, E, W, R | The same four for the group |
| 12–15 | D, E, W, R | The same four for others |
| 16–30 | – | Reserved |
| 31 | – | Set-user-ID (MultiUserFileSystem only) |
The owner bits 0–3 are inverted: a clear bit grants the right, which is why a new file has all four clear. The polarity of the group and other bits is not stated by the source used here.