Outline
- Minix FS in-memory data structures
- Minix FS disk layout
- buffer cache
- inodes and superblock
- opening files
- reading and writing files
- pipes
- linking and unlinking
- slow system calls
Minix File System Implementation: in-memory data structures
- the file system process table (p. 925) includes the current
and root directories, process IDs, an array of pointers to open files,
and information that allows saving information for slow reads/writes
(e.g. on a pipe or a terminal)
- inodes on disk (p. 921 and p. 928) have up to
8 direct block pointer ("zones"), one indirect,
one double-indirect -- total, 64 bytes
- an inode block is read from disk whenever the file corresponding
to at least one of the inodes is opened
- the corresponding inode representation in memory (p. 928) has
additional references to make it easy to locate the device and the
device's superblock, whether the inode is dirty, whether the file
is special in some way (pipe, mount, etc)
- the superblock array (p. 930) stores information about each
mounted file system, particularly the sizes of the inode and zone
bitmaps. The in-memory copy of the structure also stores mount
information, including the device and the byte-order
- an open file structure (p. 927), pointed to by the open files
in the process table, contains a pointer to the inode,
the position being read or written, and a few other items. These
structures may be shared, e.g. by a parent and a child after a fork.
- the lock array (p. 928) contains information for each file lock
set -- this is checked every time a lock is requested
- the device array (p. 686) contains function pointers for opening,
closing, and reading/writing data, and the number of the corresponding
device task
Minix File System Implementation: on disk
- boot block, including the partition table if any
- superblock, including information about the layout of the file
system on disk
- bitmap for free inodes
- bitmap for free zones (blocks)
- inodes
- zones (blocks)
Minix File System Implementation: buffer cache
- a buffer may contain (p. 926) a data page, a directory page,
an indirect block, an inode block, or a bitmap block
- free buffers are kept in a hash table, to make it easy
to locate them quickly. The hash table is indexed by the low
bits of the block number
- most free buffers are maintained in an LRU doubly-linked list,
but some free buffers are placed at the head of the list because
they are very unlikely to be needed again (e.g. superblock buffers)
- when a new buffer is needed, it is taken from the head of the list
- when reading a block from disk (or when writing part of a block),
the hash table is searched to see if the block might be in the
buffer -- if so, no need to access the disk
- when writing a full block to disk, the block then goes to the
head of the LRU list
- most dirty buffers on the LRU list are only written back when:
- the block reaches the head of the list, or
- another block on the same device is written back
- when writing any block to disk, Minix writes all blocks from
that device, in sorted (elevator) order
Minix Buffer Cache Implementation
- get_block (p. 934) searches through the list,
returning it (line 22463) if found, and if not found,
allocates a new block (by recycling the head of the LRU, p. 934)
and, if necessary, fetches it from disk (line 22511, also p. 937)
- recycling the first block on the LRU chain may require
writing back a dirty block, in which case all blocks are
written back (flushall, p. 938, rw_scattered, p. 938)
- put_block (p. 935) puts the block at the rear or at
the front of the LRU list, possibly writing it back immediately
- alloc_zone (p. 936) and
free_zone (p. 937) manage the bitmaps for zones, reading
the bitmap from disk and saving it back to disk as appropriate --
see alloc_bit (p. 947) and free_bit (p. 948) in
server/fs/super.c
- rw_scattered (p. 938) does the actual sorting of
reads/writes and performs the I/O requests, freeing the corresponding
blocks (by calling put_block, lines 22779 and 22791) and
clearing the dirty bits
Minix Buffer Cache Summary
- blocks are in LRU queue and also hash table
- blocks in buffer cache are not in use, may be reused soon
- blocks in buffer cache may be dirty, in which case they
should be written back before they may be used
- free blocks are taken from the head of the queue
- newly freed blocks are put at the end of the LRU queue,
except in special cases
- newly freed dirty inode blocks are written back immediately

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.