(Notes by Thomas Lively)
Front matter
Chickadee updates
- can now access an IDE disk
- we store pointers to local variables globally, but it's ok
- see IDE state in k-devices.cc
Wait queue enqueue bug
- assertion was too aggressive
- only need to check task is resumable if it not already running
Unix FFS design
- Superblock (fixed location)
- number of blocks in FS
- version
- number of inodes
- Free block bitmap
- 1 bit per block (0 if used, 1 if free)
- Inode area
- type
- link count
- size
- pointers to blocks
- 10 direct, 1 indirect, 1 doubly indirect
- Data area
Can find data blocks for first 4096 x 10 bytes in inode, after that need to look in indirect (or doubly indirect) block.
Adding byte to empty file
- find free block (using bitmap)
- mark as allocated (using bitmap)
- store data in block
- link block from inode
FFS Correctness
Want to survive things like power outages without data loss/corruption.
Invariants
- Every block is used for one purpose
- Every referenced block is initialized
- Every referenced block is allocated
- Every unreferenced block is free (break this one)
Allocate 11th block (bad order)
- find free block for data
- write data to data block
- write data block ptr to indirect block
- write indirect ptr to inode
- find free block for indirect block
- mark data allocated
- mark indirect block allocated
Crashing after (4) leaves garbage in file. Lots of bad orders, few good orders!
Allocate 11th block (good order)
- find free block for data
- write data to data block (worst possibility is lost final write)
- find free block for indirect block
- write data block ptr to indirect block (ok because indirect block is free)
- mark data block allocated (could leak 1 block)
- mark indirect block allocated (could leak 2 blocks)
Size is updated when inodes are written (entire inode updated atomically)
FFS Speed
Naively ~7 disk round trips for a single write (suuuuuuper slow)
Can writes be coalesced with writes from other processes?
Soft updates
- Kernel maintains large dependency web to determine order of writes
- Works if writes are atomic (they're not)
(Redo) Journaling
- log written blocks in a journal (fast) so they can be redone after crash
- write commit records to group transactions
- write to FS in any order
- write a completion record to journal
There is a recovery procedure that runs after a crash, replaying writes from the journal
Journal records idempotent actions (they can be done 1 or more times)
Can avoid write barrier after (1) by using checksum in commit record