]> www.infradead.org Git - mtd-www.git/commitdiff
UBIFS: add more info about synchronization
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 5 Jun 2009 16:21:48 +0000 (19:21 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 5 Jun 2009 16:21:48 +0000 (19:21 +0300)
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
doc/ubifs.xml
faq/ubifs.xml

index 46f18692f61ba54bd2a271c95d30bdf70495e769..e77536770db7f4ff9f5b1a92279cb0838e64b89e 100644 (file)
@@ -19,6 +19,7 @@
        <li><a href="ubifs.html#L_usptools">User-space tools</a></li>
        <li><a href="ubifs.html#L_scalability">Scalability</a></li>
        <li><a href="ubifs.html#L_writeback">Write-back support</a></li>
+       <li><a href="ubifs.html#L_sync_exceptions">Synchronization exceptions for buggy applications</a></li>
        <li><a href="ubifs.html#L_compression">Compression</a></li>
        <li><a href="ubifs.html#L_checksumming">Checksumming</a></li>
        <li><a href="ubifs.html#L_readahead">Read-ahead</a></li>
@@ -457,21 +458,63 @@ the file. The <code>fflush()</code> function flushes the <i>libc</i>-level
 buffers, while <code>sync()</code>, <code>fsync()</code>, etc flush
 <i>kernel</i>-level buffers.</p>
 
-<h4>Updating a file atomically</h4>
-
-<p>This sub-section describes common technique of updating the contents of
-a file atomically. This technique is applicable to other all POSIX-compatible
-file systems, not only to UBIFS.</p>
-
-<p>To atomically update the contents of file <code>foo</code>, you have to
-first make a copy <code>bar</code> of this file, then change file
-<code>bar</code>, synchronize file <code>bar</code>, and re-name
-<code>bar</code> to <code>foo</code>. Because the re-name operation is atomic
-(this is a <code>POSIX</code> requirement) and <code>bar</code> is
-synchronized, the whole update operation is atomic as well. Indeed, if a power
-cut happens, you will end up with an intact <code>foo</code> and half-updated
-<code>bar</code>, in which case the whole atomic update operation may be run
-again.</p>
+<p>Please, refer <a href="../faq/ubifs.html#L_atomic_change">this</a> FAQ
+entry for information about how to atomically update the contents of a
+file.</p>
+
+<p>Also, the
+<a href="http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/">
+Theodore Tso's</a> article is a good reading.</p>
+
+
+
+<h2><a name="L_sync_exceptions"></a>Synchronization exceptions for buggy applications</h2>
+
+<p>As <a href="ubifs.html#L_writeback">this</a> section describes, UBIFS is
+a fully asynchronous file-system, and applications should synchronize their
+files whenever it is required. The same applies to most Linux file-systems, e.g.
+<code>XFS</code>.</p>
+
+<p>However, the many applications ignore this and does not synchronize
+files properly. And there was a huge war between user-space and kernel
+developers related to ext4 delayed allocation feature. Please, see the
+<a href="http://thunk.org/tytso/blog/2009/03/12/delayed-allocation-and-the-zero-length-file-problem/">
+Theodore Tso's blog post</a>. More information may be found at the
+<a href="http://lwn.net/Articles/326471/">LNW article</a>.</p>
+
+<p>In short, the flame war was about 2 cases. The first case was about the
+<a href="../faq/ubifs.html#L_atomic_change">atomic re-name</a>, where many
+user-space programs did not synchronize the copy before re-naming it. The
+second case was about the applications which truncate files, then change them.
+There was no final agreement, but it the "we cannot ignore the real world"
+argument found ext4 developers' understanding, and there were 2 ext4 changes
+which sort of solved both problems.</p>
+
+<p>Roughly speaking, the first chage made ext4 synchronize files on close if
+they were previously truncated. This was a hack from file-system point
+of view, but it "fixed" applications which truncate files, write new
+contents, and close the files without synchronizing them.</p>
+
+<p>The second change made ext4 synchronize the renamed file.</p>
+
+<p>Well, this is not exactly correct description, because ext4 does not write
+the files synchronously, but actually initiates asynchronous write-out of the
+files, so the performance hit is not very high. For the truncation case this
+means that the file is synchronized soon after it is closed. For the re-name
+case this means that ext4 writes data before it writes the re-name meta-data.
+</p>
+
+<p>However, the application writers should never rely on these things, because
+this is not portable. Instead, they should properly synchronize files. The ext4
+fixes were because there were many broken user-space applications in the wild
+already.</p>
+
+<p>We have plans to implement these features in UBIFS, but this has not been
+done yet. The problem is that UBI/MTD are fully synchronous and we cannot
+initiate asynchronous write-out, so we'd have to synchronously write files
+on close/rename, which is slow. So implementing these features would require
+implementing asynchronous I/O in UBI, which is a big job. But feel free to
+do this :-).</p>
 
 
 
index bfc72ba4f92e7bed42f80991a36ff8dbd79bc973..72dd19d706d69fcced4724767b4560ff0d7ba73c 100644 (file)
@@ -31,6 +31,7 @@
        <li><a href="ubifs.html#L_powercut">Is UBIFS tolerant to power-cuts?</a></li>
        <li><a href="ubifs.html#L_smaller_jrn">I need more space - should I make UBIFS journal smaller?</a></li>
        <li><a href="ubifs.html#L_sudden_ro">UBIFS suddenly became read-only - what is this?</a></li>
+       <li><a href="ubifs.html#L_empty_file">Why my file is empty after an unclean reboot?</a></li>
        <li><a href="ubifs.html#L_study_ubifs">I want to study UBIFS - any recommendations?</a></li>
 </ol>
 
@@ -143,7 +144,7 @@ into the kernel (instead of compiling it as a kernel module) and specify proper
 kernel boot arguments and make the kernel mount UBIFS on boot. You have to
 provide the boot arguments to attach the UBI device (using the
 <code>ubi.mtd=</code> argument, see <a href="ubi.html#L_attachmtd">here</a>).
-Then you should tell the kernel the file system type by prividing the
+Then you should tell the kernel the file system type by providing the
 <code>rootfstype=</code> argument. And finally, you should specify which UBI
 volume has to be mounted on boot using the <code>root=</code> argument.
 The volume is specified the same way as described above (<code>ubiX_Y</code>
@@ -533,7 +534,7 @@ information about other dependencies in the  <code>mtd-utils</code> tree.</p>
 
 <h2><a name="L_atomic_change">How to change a file atomically?</a></h2>
 
-<p>Changing a file atomically means changing the contents in a way that unclean
+<p>Changing a file atomically means changing its contents in a way that unclean
 reboots could not lead to any corruption or inconsistency in the file. The only
 reliable way to do this in UBIFS (and in most of other file-systems, e.g. JFFS2
 or ext3) is the following:</p>
@@ -544,11 +545,19 @@ or ext3) is the following:</p>
        <li>synchronize the copy (see
        <a href="../doc/ubifs.html#L_writeback">here</a>);</li>
        <li>re-name the copy to the file (using the <code>rename()</code>
-       <i>libc</i> function or <code>mv</code> utility).</li>
+       <i>libc</i> function or the <code>mv</code> utility).</li>
 </ul>
 
-<p>Note, if power-cut happens during re-naming, the original file will be
-intact. This is <code>POSIX</code> requirement and UBIFS satisfies it.</p>
+<p>Note, if a power-cut happens during the re-naming, the original file will be
+intact because the re-name operation is atomic. This is a <code>POSIX</code>
+requirement and UBIFS satisfies it.</p>
+
+<p>Often applications do not do the third step - synchronizing the copy.
+Although this is generally an application bug, the ext4 file-system
+has a hack which makes sure the data of the copy hits the disk before the
+re-name meta-data, which "fixes" buggy applications. However, UBIFS does not
+have this feature, altough we plan to implement it. Please, refer
+<a href="../doc/ubifs.html#L_sync_exceptions">this</a> section.</p>
 
 
 
@@ -843,6 +852,31 @@ make any noticeable difference.</p>
 
 
 
+<h2><a name="L_empty_file">Why my file is empty after an unclean reboot?</a></h2>
+
+<p>The general answer to this is that you did not synchronized your file
+using something like <code>fsync()</code> <code>libc</code> function.
+You have to do this because UBIFS file-system is asynchronous and supports
+write-back. See <a href="../doc/ubifs.html#L_writeback">here</a> for more
+information about UBIFS write-back support. You may also take a look
+<a href="ubifs.html#L_atomic_change">here</a> for information about how
+to update the contents of files atomically.</p>
+
+<p>Zero-length files are a special case of corruptions which happen when
+applications first truncate files, then update them. The truncation is
+synchronous in UBIFS, so it is written to the flash media straight away. But
+when the data are written, they go to the page cache, not to the flash media.
+So when an unclean reboot happens, the file becomes empty (truncated) because
+the data are lost. The solution for this is to use <code>fsync()</code>.</p>
+
+<p>However, the ext4 file-system helps buggy applications to lessen the
+probability of getting zero-length files by implementing a special hack.
+Please, refer <a href="../doc/ubifs.html#L_sync_exceptions">this</a> section
+for more information. UBIFS does not provide a similar hack, although we are
+planning to implement it.</p>
+
+
+
 <h2><a name="L_sudden_ro">UBIFS suddenly became read-only - what is this?</a></h2>
 
 <p>Read-write UBIFS file-system may suddenly become read-only because of an