Now that files and inodes are on disk, we fill in directories, free-space tracking, and the access paths that reads and writes actually follow.
40.4 Directory Organization
A directory is stored simply: its data blocks hold a list of directory
entries, each a (name โ inode number) directory entry One record in a directory's data blocks mapping a name to an inode number, typically with a record length (reclen) and string length. The reclen lets a deleted entry's space be reused. Every directory also has '.' and '..' entries. Directories are just files whose inode type is 'directory'.
defined in ch. 40 โ open in glossary
pair
with a record length (reclen) and string length (strlen):
| inum | reclen | strlen | name | |
|---|---|---|---|---|
| . | 5 | 12 | 2 | . |
| .. | 2 | 12 | 3 | .. |
| foo | 12 | 12 | 4 | foo |
| bar | 13 | 12 | 4 | bar |
| long | 24 | 36 | 28 | foobar_is_a_pretty_longname |
Every directory has . (itself) and .. (its parent). Deleting a file leaves
a gap โ often marked with a reserved inode number (like 0) โ and the reclen
lets a later, smaller entry reuse that space. Crucially, a directory is just
a file: it has an inode (with its type field set to โdirectoryโ) whose data
blocks hold these entries. So the on-disk structure needs nothing new. (Other
designs are possible โ XFS stores directories as B-trees to speed up lookups;
FAT uses linked lists and has no inodes at all.)
40.5 Free Space Management
To allocate a new inode or data block, the FS consults a bitmap. Creating a file, for instance, means scanning the inode bitmap for a free slot (a 0), marking it used (1), and writing the updated bitmap back to disk:
A refinement is pre-allocation pre-allocation An allocation heuristic (ext2/ext3) that grabs a run of consecutive free blocks (e.g. 8) for a new file at once, so part of the file lands contiguously on disk and reads/writes faster. defined in ch. 40 โ open in glossary : ext2/ext3 look for a run of, say, 8 consecutive free blocks when a file is created, so part of the file lands contiguously on disk and is faster to read and write later.
40.6 Access Paths: Reading and Writing
The second half of understanding a file system is the
access path access path The sequence of on-disk structures a file system reads and writes to carry out an operation. Opening /foo/bar walks the path from the root inode down (reading each directory's inode and data); reading a block consults the inode then the block; an allocating write touches the bitmap, inode, and data block. I/O cost grows with pathname length.
defined in ch. 40 โ open in glossary
โ which structures get read and
written for each operation. Assume the FS is mounted (superblock in memory) but inodes and
directories are still on disk. Watch what open("/foo/bar") then reading it
actually does:
The root's i-number is "well known" (2 in most UNIX file systems), so the FS can find it with no parent to consult.
Aside: Reads Donโt Touch the Allocation Structures
A common confusion: reading a file does not consult the bitmaps. The inode already points at the fileโs blocks, so thereโs nothing to allocate and nothing to check. Bitmaps are read/written only when allocating or freeing.Writing is worse, because it may allocate. Each allocating write turns into five I/Os, and creating a file โ which must allocate an inode and update its directory โ costs around ten:
| operation | disk I/Os | what they are | |
|---|---|---|---|
| open | open a file | โ path length | read inode + data for root, then foo, then read bar's inode |
| read | read one block | 3 | read inode (locate block) ยท read the data block ยท write inode (access time) |
| awrite | allocating write (one block) | 5 | read + write the data bitmap ยท read + write the inode ยท write the data block |
| create | create a file | ~10 | path traversal + inode allocation + directory update |
The Crux: How To Reduce File System I/O Costs
Even opening, reading, or writing a single file triggers a flurry of I/Os scattered across the disk. What can a file system do to cut these costs? (The next section โ caching and buffering โ is the first answer.)Check yourself: directories, free space, access paths
1.How is a directory stored in vsfs?
2.What is the record length (reclen) in a directory entry for?
3.When are the allocation bitmaps consulted during a plain file READ?
4.Why is the I/O cost of open() proportional to the pathname length?
5.Why does a single allocating write cost 5 I/Os?
6.What is pre-allocation, and why do it?