JFFS2 write/rename atomicity/ordering issue

Sergey Zakharchenko doublef.mobile at gmail.com
Thu Jun 29 03:48:58 PDT 2017


Hello all,

I have firmware doing various equivalents of

generate_data > .tmpfile
mv -f .tmpfile realfile

in parallel (with different filenames).

The files are typically small (<10 kB). POSIX rename atomicity is
expected (leaving a dangling hard link is not a problem). fsync is
properly called before renames. There are no holes in files. There's
plenty of free space on the FS; RAM shortage is a possibility though.

The typical JFFS2 entry sequence for such operations is:

Inode  #ino  TMP, ver 1,   isize 0 (create)
Dirent #pino DIR, ver V,   #ino  TMP, name .tmpfile (add dirent)
Inode  #ino  TMP, ver 2,   isize SIZE (write)
Dirent #pino DIR, ver V+1, #ino  TMP, name realfile (link)
Dirent #pino DIR, ver V+2, #ino  0,   name .tmpfile (unlink)

However, I've stumbled upon a filesystem corruption case and found the
following sequence in the filesystem:

Inode  #ino  TMP, ver 1,   isize 0 (create)
Dirent #pino DIR, ver V,   #ino TMP, name .tmpfile (add dirent)
Dirent #pino DIR, ver V+1, #ino TMP, name realfile (LINK, .tmpfile is
still 0 bytes)
Dirent #pino DIR, ver V+2, #ino 0, name .tmpfile (UNLINK)
.
. similar sequences on other files, writes still absent
.
Inode  #ino  TMP, ver 2,   isize SIZE (the forgotten write to .tmpfile)
Empty space (to the end of the block)

There were no other writes to the TMP inodes of the above-mentioned other files.
The net result was that those files ended up with a size of zero.
There were no signs of hardware-related data corruption.

This happened on mips Linux 3.3.8 as patched by this OpenWrt version:

https://github.com/openwrt/openwrt/tree/4ea8a1f1f62369e3c3055d2cfd09e8d0e01c9766

There have been some changes in the kernel since but I haven't found a
way how they could have helped fix the problem, if any. The only other
"interesting" component is overlayfs but I haven't found a way it
could have affected this.

I'm running tests to attempt to reproduce the issue but to no avail so
far. I've also tried analyzing the write/sync locking patterns but
they seem fine so far. Do you have any ideas?

Thanks in advance,

-- 
DoubleF



More information about the linux-mtd mailing list