The main issue we are going to be looking at is power loss. If we are to write to a buffer, what would happen if the system crashes, and then reboots?
Imagine we have a buffer size of 10,000,000 bytes (about 10 MBs). Since this is a very large buffer, there is potential for a fault when the system crashes and reboots.
In the Berkeley File System, the blocks that the file system writes to aren't necessarily contiguous blocks (file's contents aren't always stored in blocks in left to right order). Therefore, when the system reboots in the middle of a write, we cannot simply examine a contiguous amount of blocks left to right to see what blocks weren't written. We need to find another way.
We will examine this issue through a case study of the rename("a", "b") function. It happens in 3 steps:
Step 1: Create file "b" in working directory, the new file.
-----------------------------------------
| |"a" 27 | |"b" 65 | |
-----------------------------------------
Step 2: Set file "b"s inode to "a", remove "a".
-----------------------------------------
| | 0 | |"b" 27 | |
-----------------------------------------
Step 3: Move file "b" to location where "a" was at.
-----------------------------------------
| |"b" 27 | | 0 | |
-----------------------------------------
This gives us two potential problems in crashes. If our system crashes in between step 1 and step 2, our file system may look like this:
-----------------------------------------
| | 0 | |"b" 65 | |
-----------------------------------------
Which is equivalent to calling the command unlink("a"). This isn't what we want, as now we have lost the block number that "a"s contents correspond to, and therefore we cannot rename file "b" to file "a".
Another possibility of what our file system may look like after a crash between step 1 and step 2 is this:
-----------------------------------------
| |"a" 27 | |"b" 27 | |
-----------------------------------------
Which is equivalent to calling the commands unlink("b"), and then link("a", "b"). This is the wrong link count, as we have one more file name than we wanted. This is where the system call fsck() will come into play.