Worksheet 15: File-system
Dream Coding

Niko has a special talent: dream coding. He can write codes with eyes closed, and the quality is better than monkey punching keyboard. One night, he burns the midnight oil to implement the dining philosophers solution from OS lecture, because the demo is next morning.
Niko starts dream coding:
11:53 PM:
$ vim dining_dogs.c
[creates the classic 5 dogs, 5 spoons problem]
[dogs keep deadlocking, all holding left spoon, waiting for right]
$ git add dining_dogs.c
$ git commit -m "add dining dogs deadlock problem"
$ git push origin master
Pushed to master12:15 AM:
$ vim doghouse_sem.c
[adds doghouse semaphore with limit 4]
$ git add doghouse_sem.c
$ git commit -m "doghouse semaphore for concurrency throttling"
$ git push origin master
Pushed to master12:40 AM:
$ vim dining_dogs.c
[wiring up sem_wait before entering doghouse]
[adding sem_post after leaving]
[integrating the throttling logic...]
$ git add dining_dogs.c
$ git commit -m "integrate doghouse throttling to prevent deadlock"
$ git push origin master
Pushing... 43%... 67%...12:41 AM: Niko finally falls asleep after 8-hours non-stop working.

Next Morning - 9:00 AM
Capoo arrives at the office and pulls latest code:
$ git pull origin master
Updating a3f829c..e8b9d12
Fast-forward
dining_dogs.c | 67 +++++++++++++++++
doghouse_sem.c | 23 ++++++++Capoo opens dining_dogs.c:
// 5 dogs trying to eat with 5 spoons (forks)
void* dog(void* arg) {
int id = *(int*)arg;
int a, b, c;
while(1) {
drooling(); // Hungry @_@
// Try to pick up spoons
pthread_mutex_lock(&spoon[id]); // Pick left spoon
pthread_mutex_lock(&spoon[(id+1) % 5]); // Pick right spoon
eat_dogfood(id); // like a king
// Put down spoons
pthread_mutex_unlock(&spoon[??]);
pthread_mutex_unlock(&spoon[??]);
}Capoo opens doghouse_sem.c:
sem_t doghouse;
sem_init(&doghouse, 0, ???);
// 4 dogs can enter doghouse at once
// With 4 dogs and 5 spoons, no deadlock
sem_wait(???)“WHAT THE …” Capoo’s coffee spills.
“Don’t even compile. What are these random variables int a, b, c? And sem_wait(???)? Wait on WHAT?”
The code is just messy torn writes. (´・ω・`)
Capoo runs into Nini’s office.
Capoo: “Niko pushed the dining dogs code but it’s garbage.”
Nini: “Where’s Niko?”
Capoo: “Still asleep at his desk.””
Nini sigh: “Classic torn write problem. He brain dumped everything but crashed in the middle.”
Nini calls Niko into the office. Niko looks like a zombie.

Nini: “Man. You committed broken code … Do you even remember what you were doing?”
Niko (tired as dog): “Eh .. I… I learned about concurrency throttling in OS lecture. You limit 4 dogs in the doghouse. Then deadlock can’t happen because… uh…”
Nini: “Right! But your code contains garbage like sem_wait(???). Nobody knows what the heck you try to do!”
Nini: “Now LISTEN. Before you write a single line of code, create a pull request (PR) FIRST.”
“If you pass out next time, Capoo could at least throw your PR to Gemini Code. OK?” 11:30 PM - Same Situation, Different Approach Niko travels on a time machine and goes back to last night. This time, he remembers Nini’s rule: “PR before dream coding.” Opens GitHub, clicks “New Pull Request”: 11:45 PM - Niko clicks “Create Pull Request”, and starts coding: 12:05 AM - Continues: 12:23 AM - Niko passed out again … Next Morning - 8:45 AM Capoo arrives office, … done after Capoo drinks a cup of coffee. (✪ω✪) 8:50 AM - Capoo 9:00 AM - Capoo pokes Niko on Discord: Capoo: Good morning, bro. “Finished your doghouse deadlock prevention. Just threw your PR.md at Gemini Code, done in 10 minutes.” like a breeze. (◕ܫ◕) Niko (just wake up): “Wait, Google mini Doge?” Capoo: “Yes. A piece of fish for the Google AI. Your PR was our write-ahead-log-style journal.” “After you crashed, the AI replayed the journal to fix your broken dreamed code.” Niko: “Le Mao.” Appending new data to a file requires updates to multiple blocks: allocate a block, write data, mark it used, update the inode and directory metadata. A power failure mid-update leaves the filesystem in a strange states, like: data written but unreachable, or size wrong, or wrong block reused. Journaling fixes this by first recording the entire plan in a write-ahead log. Only after the journal is safely stored does the filesystem perform the real operations. If a crash occurs, the journal is replayed to perform any incomplete steps so the file-system ends up consistent (either fully appended or untouched, never half-baked). Watch this week’s lecture if you have no idea what I’m mumbling. I don’t know anyone except Niko who can do dream coding. I myself can do dream debugging, though.Time Machine Back to Yesterday
### Problem
5 dogs, 5 spoons, classic deadlock when all grab left spoon simultaneously.
### Solution
Doghouse semaphore with limit 4. Only 4 dogs allowed in the doghouse.
With 4 dogs and 5 spoons, deadlock impossible (always a spare spoon).
### Implementation Steps
1. Create dining_dogs.c with deadlock problem
2. Create doghouse_sem.c with semaphore (init value = 4)
3. Add sem_wait(&doghouse) before dog enters
4. Add sem_post(&doghouse) after dog leaves
5. Initialize semaphore in main() with value 4$ vim dining_dogs.c
[creates dog function with mutex locks]
[creates the deadlock scenario]
$ git add dining_dogs.c
$ git commit -m "PR: Step 1 - Create dining dogs deadlock problem"
$ git push origin feature/doghouse-deadlock-prevention$ vim doghouse_sem.c
[declares sem_t doghouse]
[adds initialization code: sem_init(&doghouse, 0, 4)]
$ git commit -m "PR: Step 2 - Create doghouse semaphore with limit 4"
$ git push origin feature/doghouse-deadlock-preventiongit pull, check out the PR branch. He continues to open Gemini Code and types:

git push:$ git add *.c
$ git commit -m "PR: Complete Steps 3-5 using PR description"
$ git push origin feature/doghouse-deadlock-preventionBack to Filesystems
Video Lecture
Remember to open the English subtitle on Youtube: eLearn link of the video lecture
(◕ܫ◕) (◕ܫ◕)
!!有繁體中文字幕!!
Readings
Learning Objectives
I understand the following concepts:
- Virtual File-system (VFS)
- What “mounting a file-system” means
- The content of superblock, inode
- ext2 inode structure: the direct pointer / single indirect pointer / double indirect pointer / triple indirect pointer, and how to calculate the maximum supported file size.
- Dentry and dentry cache
- Path resolution
- Torn writes
- The Atomic Rename Trick
- Write Ahead Logging: journal writes, checkpoint, free, journal replay