In commit, click the line whose disk write is the moment the transaction becomes
durable: if the power fails before this write completes, the transaction never
happened; after it, the next boot will finish it.
end_op clears committing, increments ncommit, and wakes sleepers on &log
end_op sets log.committing = 1 under log.lock, then releases the lock
write_head again, with n = 0: erase the transaction
write_log: copy each logged block from the cache into the log area
write_head: write the header with n and the block list (the commit point)
install_trans(0): copy each block to its home location and unpin it
4warm-upType a number
The log is empty (log.lh.n = 0) and no commit is running. Processes keep calling
begin_op and none of them has reached end_op yet. How many of them are
admitted before the next one has to sleep?
ireclaim scans the inodes for orphans (allocated, nlink == 0) and frees them
fsinit reads the superblock (block 1) and checks its magic number
read_head copies n and the block list from the header block into log.lh
install_trans(1) copies each log block to its home block, printing recovering tail …
6warm-upChoose one
Inside one transaction, writei changes block 1006 and calls log_write; a moment
later the same transaction changes block 1006 again and calls log_write a second time.
What does the second call do?
One transaction is running (log.outstanding = 1, log.committing = 0). A second
process calls begin_op. What is the largest value of log.lh.n for which it is
admitted without sleeping?
A process writes 2000 bytes at offset 0 to an empty regular file (no data blocks yet).
The log was empty and no other transaction runs. The filewrite chunk is one
transaction. How many distinct blocks are in log.lh.block[] when end_op
commits?
decimal, 0x hex or 0b binary
13solidChoose all that apply
Which of these situations make begin_op put the caller to sleep?
Which of these run inside a transaction (begin_op … end_op) in this kernel?
19solidDecode the bits
After a crash, gdb shows the first 16 bytes of block 2 (the log header,
struct logheader, little-endian 32-bit ints) as
03 00 00 00 22 00 00 00 2f 00 00 00 21 00 00 00. sb.logstart is 2. Decode it.
Value: 03000000 22000000 2f000000 21000000
20solidClick the line
While a commit is running, log.lock is not held. Click the line in end_op that
keeps new transactions from starting during the commit.
The machine is booting after a crash. pid 1 is in install_trans during recovery,
executing line 78 (the memmove from the log block’s buffer to the home block’s
buffer). Both buffers are held. What is the state of the hart running it?
kernel/log.c
66// Copy committed blocks from log to their home location
Suppose commit omitted line 210 (it still sets log.lh.n = 0 in memory, but no
longer writes the empty header). The disk header would keep saying n = 3: 34, 47, 33
after this commit. What could go wrong?