(Notes by Thomas Lively)
Front matter
Pset 3 is out
- First 3 of 6 parts released
- Code reading then design a VFS layer
Goal: Implement file descriptors on top of basic read/write syscalls
- File descriptor table points to open files with offsets
- Open files refer to vnodes (many to one)
Take a look at Linux's file operations (there are a log of them)
xv6 has only read
and write
(only supports one FS)
Eddie's solutions are cumulatively 950 lines for reference
waiter::block_until
waiter::block_until
parameterized with type of predicate F
.
- Predicate is usually a lambda expression
- Harvard students learn about C++ lambda expressions
- tart lambda with
[&]
to allow it to reference its environment - Lambda is completely inlined
- Template errors are not caught at call site, they're caught after expansion
Locking in FS
- Does file descriptor table need lock? Yes, because it is shared among threads
- Do open files need locks? Yes, because they are shared among processes
- Do vnodes need locks? Yes, because they are shared among processes
Possible situation
T1 T2
read(0)
(blocks)
close(0)
OK: read returns EBADF OK: read blocks until data returns BAD: close blocks forever BAD: read accesses freed kernel memory
How to avoid badness
- Reference count shared structures, only free if refcount goes to 0
Steps to do something with file
- lock file descriptor table
- find file
- lock file (noirq)
- unlock file descriptor table
- increment file refcount
- unlock file
- block with continuing existence of file guaranteed
- lock file
- decrement file refcount
- unlock file
- maybe free file
Refcount cannot start at 0, since file descriptor table already has reference
Refcount is like a lock—a shared lock on existence!
- While refcount > 0, impossible to free the file.
Virtual methods
Eddie explains how virtual methods work
- Use override to save yourself work when you change things
- Virtual in base class, override in children, anything else is madness
this_cpu
and current
Why does this_cpu
need disabled interrupts while current
(proc) does not?
- If the task can be moved to a different CPU,
this_cpu
will be useless - With interrupts disabled,
this_cpu
's result can be trusted until interrupts are turned on