<story><title>The No-Order File System (2012)</title><url>http://pages.cs.wisc.edu/~vijayc/nofs.htm</url></story><parent_chain><item><author>Animats</author><text>That&amp;#x27;s progress.&lt;p&gt;I&amp;#x27;ve previously suggested that operating systems should have stronger file integrity guarantees. &amp;quot;Unit&amp;quot; files (rewriting replaces the whole file atomically, no reader ever sees a partially written file). That&amp;#x27;s the default. &amp;quot;Log&amp;quot; files (always end at a clean end point, don&amp;#x27;t tail off into junk). &amp;quot;Temp&amp;quot; files (disappear on reboot). And, for databases, &amp;quot;Managed&amp;quot; files.&lt;p&gt;Managed files have more I&amp;#x2F;O functions. In particular, you get two completion events on writes - &amp;quot;copy complete&amp;quot; (the caller can reuse the buffer) and &amp;quot;safely stored&amp;quot; (the data has reached its final resting place, all links are complete, etc.). Programs like databases would use that. Those are the semantics databases want, and struggle to get by flushing, waiting, and various workarounds.&lt;p&gt;When I mention this, what usually happens is that people get lost in complicated workarounds for simulating unit files. Different approaches are needed for Linux, Windows, NTFS, and various VM systems. This should Just Work.&lt;p&gt;This isn&amp;#x27;t my invention; it&amp;#x27;s from Popek&amp;#x27;s kernel in 1985 at UCLA, later seen as UCLA-Locus and as an IBM product. They had explicit commit and revert functions for file systems. I&amp;#x27;d suggest having the default be commit on normal close or normal program exit, but if the program aborts or crashes or is killed, unit files don&amp;#x27;t commit and remain unchanged.</text></item></parent_chain><comment><author>KMag</author><text>For the temp file issue, there&amp;#x27;s the common pattern of creating a file and unlinking it right away while keeping an open file handle.  It&amp;#x27;s unfortunate that there&amp;#x27;s not a version of creat() that takes a path to a directory (for determining on which fs to create) but doesn&amp;#x27;t link the file, plus a version of link() that takes a source file descriptor instead of a source file.&lt;p&gt;If extended to support non-file fds, the link function might also do some interesting things, like have TCP connections show up in the virtual file system, similar to Unix pipes.</text></comment>
<story><title>The No-Order File System (2012)</title><url>http://pages.cs.wisc.edu/~vijayc/nofs.htm</url></story><parent_chain><item><author>Animats</author><text>That&amp;#x27;s progress.&lt;p&gt;I&amp;#x27;ve previously suggested that operating systems should have stronger file integrity guarantees. &amp;quot;Unit&amp;quot; files (rewriting replaces the whole file atomically, no reader ever sees a partially written file). That&amp;#x27;s the default. &amp;quot;Log&amp;quot; files (always end at a clean end point, don&amp;#x27;t tail off into junk). &amp;quot;Temp&amp;quot; files (disappear on reboot). And, for databases, &amp;quot;Managed&amp;quot; files.&lt;p&gt;Managed files have more I&amp;#x2F;O functions. In particular, you get two completion events on writes - &amp;quot;copy complete&amp;quot; (the caller can reuse the buffer) and &amp;quot;safely stored&amp;quot; (the data has reached its final resting place, all links are complete, etc.). Programs like databases would use that. Those are the semantics databases want, and struggle to get by flushing, waiting, and various workarounds.&lt;p&gt;When I mention this, what usually happens is that people get lost in complicated workarounds for simulating unit files. Different approaches are needed for Linux, Windows, NTFS, and various VM systems. This should Just Work.&lt;p&gt;This isn&amp;#x27;t my invention; it&amp;#x27;s from Popek&amp;#x27;s kernel in 1985 at UCLA, later seen as UCLA-Locus and as an IBM product. They had explicit commit and revert functions for file systems. I&amp;#x27;d suggest having the default be commit on normal close or normal program exit, but if the program aborts or crashes or is killed, unit files don&amp;#x27;t commit and remain unchanged.</text></item></parent_chain><comment><author>jcranmer</author><text>POSIX filesystem semantics are one of the things where POSIX just plain got stuff wrong. And it isn&amp;#x27;t helped by the fact that a lot of people want to game benchmarks by slightly lying about their durability compliance, so you really have to jump through hoops to make sure you actually achieve durability.&lt;p&gt;I do agree with you that we need a better way to interact with the filesystem with regards to integrity and durability, although I&amp;#x27;m not sure we entirely agree on how that would look. The idea of multiple modes makes a lot of sense:&lt;p&gt;* File-atomic mode. This is I believe trivial to implement in the filesystem layer for all filesystems, and the basic idea of this mode has existed for decades. When a reader opens a file for reading, it will never see any other writes to the file. A writer will only update the file when it closes the file [1], at which point any &lt;i&gt;new&lt;/i&gt; reader will see only the new file created. The code is intrinsically safe in the face of multiple processes interacting with the file, and is probably the semantics most people would prefer in that situation.&lt;p&gt;* Append-only transactional files. Here, you can&amp;#x27;t random-access write into the file (but you can random-access read), only write at the end or truncate the file. A writer designates the text to append to the file as atomic blocks: the reader will only atomically see or not see the block [2]. If the file is truncated, all readers see the original contents of the file until they close.&lt;p&gt;* Raw files. Don&amp;#x27;t pretend that a file is a stream of bytes. Instead, expose it as a set of blocks that can be atomically updated (including atomically adding or removing blocks from the file at different places). I don&amp;#x27;t know filesystem semantics to give any good details here, but my understanding is that databases basically try to get these semantics today, and that getting good guarantees on fully random-access read&amp;#x2F;write semantics is effectively impossible anyways.&lt;p&gt;There does feel to me to be a bit of a hole here, where you basically get no multiprocess interactions via files unless you completely change how your code works, but I&amp;#x27;m not sure it&amp;#x27;s entirely feasible to have a middle ground here. You can probably get close enough for most needs with a way to be notified and reopen the file in file-atomic mode, and anything where that&amp;#x27;s not sufficient probably needs you to go to raw files to really get the guarantees you want.&lt;p&gt;In addition to the basic file I&amp;#x2F;O issues, there also needs to be a way to be more transactional with directories, I think. Using paths as the basis for filesystem issues is already opening up programmers to time-of-check-time-of-use attacks today, and moving to a file descriptor-based approach for directory manipulation would solve that while opening up the possibility for better transactional support on the directory level.&lt;p&gt;The other issue is durability. Most applications in the first two modes would probably be fine with an optional durability: the result of an unexpected power outage would be a file that is out of date, but not corrupt. The filesystem could provide an optional callback on commit that returns when it is durability committed, which would handle those cases where you do actually need to make sure that the data will be committed on unexpected power outage. And the simple semantics of the first two modes means that providing durability reliably should be easy for filesystems.&lt;p&gt;[1] This also suggests that there should be a way to abort the write.&lt;p&gt;[2] You can also see how a file-atomic reader can interact with an append-only writer: the filesystem layer needs to remember the size the reader first saw and pretend that&amp;#x27;s the EOF, but otherwise there&amp;#x27;s no issue. And append-only readers will act as a file-atomic reader with respect to a file-atomic writer. The interactions make sense, that&amp;#x27;s a good sign for the model!</text></comment>