UBIFS FAQ and HOWTO

Table of contents

  1. How to enable UBIFS?
  2. May UBIFS be used on MLC NAND flash?
  3. How to mount UBIFS?
  4. How to create an UBIFS image?
  5. May an empty UBI volume be mounted?
  6. What is the purpose of -c (--max-leb-cnt) mkfs.ubifs option?
  7. Why I have to use ubiformat?
  8. How to compile mkfs.ubifs?
  9. What is "favor LZO" compression?
  10. Can UBIFS mount loop-back devices?
  11. How to change a file atomically?
  12. Does UBIFS support atime?
  13. Does UBIFS support NFS?
  14. Does UBIFS become slower when it is full?
  15. Why df reports too few free space?
  16. How to disable compression?
  17. How to use UBIFS with nandsim?
  18. How to extract files from an UBI/UBIFS image?
  19. Is UBIFS tolerant to power-cuts?
  20. I need more space - should I make UBIFS journal smaller?
  21. Why my file is empty after an unclean reboot?
  22. Why my file has zeroes at the end after an unclean reboot?
  23. What does the "ubifs_bgt0_0" thread do?
  24. UBIFS suddenly became read-only - what is this?
  25. I see this UBIFS error: "validate_sb: LEB size mismatch: 129024 in superblock, 126976 real"
  26. I see this UBI error: "ubi_io_read: error -74 while reading 126976 bytes from PEB 47:4096, read 126976 bytes"
  27. I see this error: "INFO: task pdflush:110 blocked for more than 120 seconds"
  28. I want to study UBIFS - any recommendations?

How to enable UBIFS?

Since UBIFS works on top of UBI, you have to enable UBI first (see here).

Then in the Linux configuration menu, go to "File systems" -> "Miscellaneous filesystems", and mark the "UBIFS file system support" check-box. UBIFS may be either compiled into the kernel or be built as a kernel module.

May UBIFS be used on MLC NAND flash?

UBIFS authors never tested UBI/UBIFS on MLC flash devices. Let's consider some specific aspects of MLC NAND flashes:

However, there are 2 other aspects which may need closer attention. The first one is the "paired pages" problem (e.g., see this Power Point presentation). Namely, MLC NAND pages are coupled in a sense that if you cut power while writing to a page, you corrupt not only this page, but also one of the previous pages which is paired with the current one. For example, pages 0 and 3, 1 and 4, 2 and 5, 3 and 6 in and so on (in the same eraseblock) may be paired (page distance is 4, but there may be other distances). So if you write data to, say, page 3 and cut the power, you may end up with corrupted data in page 0. UBIFS is not ready to handle this problem at the moment and this needs some work.

The second aspect is the "program-disturb" MLC NAND property (see here), which means that if you program an MLC NAND page, you may introduce a bit-change in a different NAND page. Well, the bit change will be fixed by ECC, but with time the changes may accumulate and become unfixable. Current UBI bit-flip handling only partially helps here, because it is passive, which means that UBI notices bit-flips only when performing users read requests, so if you never read the MLC NAND area which accumulates bit-flips, UBI will never notice this. However, it is not difficult to implement a kind of "flash crawler" which would read the flash in background from time to time and make UBI notice and fix bit-flips.

Nevertheless, UBIFS authors never worked with real raw MLC NAND flash, so we might have missed or misinterpreted some MLC NAND aspects. Any feed-back is appreciated.

How to mount UBIFS?

The modern way of mounting UBIFS is mounting UBI volume character device nodes, e.g.:

$ mount -t ubifs /dev/ubi0_0 /mnt/ubifs

will mount UBIFS to UBI volume 0 on UBI device 0. This is the easiest way to mount UBIFS, but it is supported only in kernels starting from version 2.6.32. The UBIFS back-port trees (see here) also support this mounting method.

The old method is to use device-less mount, just like procfs or sysfs. The volume to mount is specified using ubiX_Y or ubiX:NAME syntax, where

For example,

$ mount -t ubifs ubi1_0 /mnt/ubifs

mounts volume 0 on UBI device 1 to /mnt/ubifs, and

$ mount -t ubifs ubi0:rootfs /mnt/ubifs

mounts "rootfs" volume of UBI device 0 to /mnt/ubifs ("rootfs" is volume name). This method of specifying UBI volume is more preferable because it does not depend on volume number.

Note, if X is not specified, UBIFS assumes 0, i.e., "ubi0:rootfs" and "ubi:rootfs" are equivalent.

Some environments like busybox are confused by the ":" delimiter (e.g., ubi:rootfs) and "!" may be used instead (e.g., ubi!rootfs).

In order to mount UBIFS as the root file system, you have to compile UBIFS 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 ubi.mtd= argument, see here). Then you should tell the kernel the file system type by providing the rootfstype= argument. And finally, you should specify which UBI volume has to be mounted on boot using the root= argument. The volume is specified the same way as described above (ubiX_Y or ubiX:NAME).

The following is an example of the kernel boot arguments to attach mtd0 to UBI and mount UBI volume "rootfs":

ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs

Please, see this section for information about how to create UBI devices and this section for information about how to create UBI volumes.

How to create an UBIFS image?

Creating UBIFS images might be a little trickier than creating JFFS2 images. First of all, you have to understand that UBIFS works on top of UBI which works on top or MTD which basically represents your raw flash. This means, that if you need to create an image which should be flashed to the raw flash, you should first create an UBIFS image, then UBI image. In other words, the process has 2 steps.

However, as described here, UBI has a volume update facility and there is an ubiupdatevol utility for this. So you may update UBI volumes on your running system as well. In this case you only need an UBIFS image, and you do not have to make the UBI image, i.e., the process has only 1 step in this case.

Moreover, you may even build the image on your target system and write it directly to your UBI volume - just specify the volume character device as the output file to mkfs.ubifs.

So, there are 2 utilities:

And depending on the needs you use either mkfs.ubifs or mkfs.ubifs plus ubinize. Choose the former if you are going to upload the update UBIFS image on your target and then update the UBI volume using ubiupdatevol. Choose the latter if you are going to flash the image to raw flash, e.g., at the factory.

The UBI and UBIFS images depend on parameters of the flash they are going to be used on. Namely, you have to know the following characteristics of the flash before creating images:

If you run Linux kernel version 2.6.30 or higher, or you have the MTD sysfs support back-ported, then you may find all these parameters by running the mtdinfo tool with -u parameter. Of course, the tool has to be run on the target system.

Please, refer this for more information about how to find these parameters.

And optionally, you should decide which compression algorithm you want to use for the file-system. UBIFS supports zlib and LZO (default) at the moment (see here). There is also favor LZO mkfs.ubifs compression method. Generally, zlib compresses better, but it is slower on both compression and decompression. So this is a trade-off between space savings and speed. The best idea is to try both and choose the one which is more appropriate for you. Here you may find compression test results for ARM platform. Alternatively, the compression may be switched off. See "-x" option of the mkfs.ubifs utility.

There are other advanced file-system and UBI characteristics which may be altered with various options of the tools. Use them only if you understand what they do.

The below example demonstrates how to create an UBI/UBIFS image for a 256MiB SLC OneNAND flash chip with 128KiB physical eraseblocks, 2048-byte NAND pages, and 512-byte sub-pages (this means that it allows to do 4x512 bytes writes to the same NAND page, which is quite typical for SLC flashes). The resulting image will have only one UBI volume storing UBIFS file-system.

$ mkfs.ubifs -r root-fs -m 2048 -e 129024 -c 2047 -o ubifs.img
$ ubinize -o ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg

where ubinize.cfg contains:

$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=200MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

Some comments about what the options mean:

The ubinize utility requires volumes description file. Please, refer this section for more ubinize usage information.

In the example, the ubinize.cfg file tells ubinize to create an UBI image which has a singe 200MiB dynamic volume with ID 0, and name "rootfs". The configuration file also sets the "autoresize" volume flag, which means that the volume will be automatically enlarged by UBI to have the maximum possible size when it runs for the first time. See here for more information about what the auto-resize feature is. And because we specified "-c 2047" mkfs.ubifs option, UBIFS will also automatically re-size on the first mount. So the end result will be that you have one single volume of maximum possible size, and UBIFS spans whole volume.

Please, run ubinize -h and mkfs.ubifs -h for more information and for more possibilities to tweak the generated images.

Here is one more example for a 32MiB NOR flash with 128KiB physical eraseblock size.

$ mkfs.ubifs -r root-fs -m 1 -e 130944 -c 255 -o ubifs.img
$ ubinize -o ubi.img -m 1 -p 128KiB ubinize.cfg

where ubinize.cfg contains:

$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=30MiB
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
vol_flags=autoresize

And one more example for a 512MiB MLC NAND flash with 128KiB physical eraseblock size, 2048 bytes NAND page size and no sub-page write support.

$ mkfs.ubifs -r root-fs -m 2048 -e 126976 -c 4095 -o ubifs.img
$ ubinize -o ubi.img -m 2048 -p 128KiB ubinize.cfg

where ubinize.cfg contains:

$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=450MiB
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
vol_flags=autoresize

To flash UBI images, please use the ubiformat utility (see here) or use/implement a proper custom flasher program. (here you may find some hints). Please, read this section for more information why you should use ubiformat.

Is it OK to mount empty UBI volumes?

Yes, it is OK to mount empty UBI volumes, i.e. the volumes which contain only 0xFF bytes. In this case UBIFS formats the media automatically with default parameters (journal size, compression, etc). But generally, this feature should have limited use (developing, debugging), and a proper UBIFS image should preferably be created and flashed (see this section).

Note, UBI has similar property and it automatically formats the flash media if it is empty (see here). So if there is an mtd0 MTD device, the following will work:

# Wipe the MTD device out. Note, we could use flash_eraseall, but we do not
# want to lose erase counters
ubiformat /dev/mtd0

# Load UBI module
modprobe ubi

# Attach mtd0 to UBI - UBI will detect that the MTD device is
# empty and automatically format it. This command will also create
# UBI device 0 and udev should create /dev/ubi0 node
ubiattach /dev/ubi_ctrl -m 0

# Create an UBI volume - the created volume will be empty
ubimkvol /dev/ubi0 -N test_volume -s 10MiB

# Mount UBIFS - it will automatically format the empty volume
mount -t ubifs ubi0:test_volume /mnt/ubifs

It is also possible to wipe out an existing UBIFS volume represented by /dev/ubi0_0 using the following command:

ubiupdatevol /dev/ubi0_0 -t

What is the purpose of -c (--max-leb-cnt) mkfs.ubifs option?

It is a form of specifying file-system size. But instead of specifying the exact file-system size, this option defines the maximum file-system size (more strictly, maximum UBI volume size). For example, if you use --max-leb-cnt=200 mkfs.ubifs option, than it will be possible to put the resulting image to smaller UBI volume and mount it. But if the image is put to a larger UBI volume, the file-system will anyway take only first 200 LEBs, and the rest of the volume will be wasted.

Note, the --max-leb-cnt option does not affect the size of the resulting image file, which depends only on the amount of data in the file-system. mkfs.ubifs just writes the --max-leb-cnt value to the file-system superblocks.

This feature is quite handy on NAND flashes, because they have random amount of initial bad eraseblocks (marked as bad in production). This means, that different devices may have slightly different volume sizes (especially if the UBI auto-resize feature is used). So you may specify the maximum possible volume size and this will guarantee that the image will work on all devices, irrespectively on the amount of initial bad eraseblocks.

Fundamentally, mkfs.ubifs has to know file-system size because UBIFS maintains and stores per-LEB information (like amount of dirty and free space in each LEB) in so-called LPT area on the media. So obviously, the size of this area depends on the total amount of LEBs, i.e. on the volume size. Note, various characteristics of the LPT B-tree depend on the LPT area size, e.g., we use less bits in LPT tree keys of smaller LPT area. So do not use unnecessarily large --max-leb-cnt value to achieve better performance.

Can UBIFS mount loop-back devices?

Unfortunately not, because loop-back devices are block devices (backed by regular files), while UBIFS works on top of UBI devices (see here).

However, there is an unusual way to make UBIFS work with a file-backed image using NAND simulator (see here). If your image is not very big, then you can create a RAM-backed nandsim MTD device, then copy your image to that emulated MTD device. If the image is large and you do not have that much RAM, you can create a file-backed nandsim MTD device using the cache_file nandsim module option. Below is an example:

# Create a 1GiB emulated MTD device backed by regular file "my_image"
$ modprobe nandsim cache_file=my_image first_id_byte=0xec second_id_byte=0xd3 \
  third_id_byte=0x51 fourth_id_byte=0x95

See here for more instructions about using UBIFS with nandsim.

What is "favor LZO" compression?

Starting from version 1.1, the mkfs.ubifs utility supports so-called "favor LZO" compression. This is not a new compression algorithm, it is just a method of combining LZO and zlib compressors to balance speed and compression ratio. A similar method exists in the mkfs.jffs2 utility, and we borrowed this idea from there.

As this documentation section highlights, zlib compressor provides better compression ratio comparing to the LZO compressor, but it is considerably slower, especially on embedded platforms which do not usually have powerful CPUs. The favor LZO compression method makes it possible to use zlib compressor for data chunks which zlib may compress much better than LZO, and to use LZO compressor for data chunks which zlib compresses only slightly better than LZO. See this section for some favor LZO experiment results on ARM platform.

Here is the favor LZO algorithm. Each 4KiB data chunk is compressed by both zlib and LZO compressors. If zlib compresses at least 20% better than LZO, then zlib is used for this data chunk. Otherwise, LZO is used. Very simple. The 20% threshold is configurable via the "-X mkfs.ubifs option, so you may make it 10% or anything else. Example:

$ mkfs.ubifs -r rootfs -m 2048 -e 129024 -c 2047 -x favor_lzo -X 5 -o ubifs.img

This command creates an UBIFS image containing the rootfs directory, using favor LZO compression with threshold 5%. This means that if a data chunk compresses at least 5% better with zlib, then mkfs.ubifs uses zlib, otherwise it uses LZO.

So UBIFS images created with favor LZO compression will contain both LZO and zlib-compressed data nodes. However, the default file-system compressor will be LZO. This means, the kernel will use LZO compressor for all data. This is because the favor LZO method is not implemented in-kernel, just because UBIFS authors did not need it there. Of course you can mount the UBIFS images created with the favor LZO compression method, and they will work fine. But if you write a file to the UBIFS file-system, it will be compressed only by the LZO compressor. So favor LZO is actually useful only for read-only files which are not going to be over-written. However, it should be easy to implement favor LZO in the kernel.

Why I have to use ubiformat?

The first obvious reason is that ubiformat preserves erase counters, so you do not lose your wear-leveling information when flashing new images.

The other reason is more subtle, and specific to NAND flashes which have ECC calculation algorithm which produces ECC code not equivalent to all 0xFF bytes if the NAND page contains only 0xFF bytes. Consider an example.

In fewer words, ubiformat makes sure that every NAND page is written once and only once after the erasure. If you use nandwrite, some pages are written twice - once by nandwrite, and once by UBIFS.

How to compile mkfs.ubifs?

The mkfs.ubifs utility requires zlib, lzo and uuid libraries. The former two are used for compressing the data, and the latter one is used for generating universally unique ID number for the file-system. In Fedora install zlib-devel, lzo-devel, and libuuid-devel. Old Fedora distributions (Fedora 11 and earlier) had the uuid library in the e2fsprogs-devel package. In Debian install zlib1g-dev, liblzo2-dev and uuid-dev packages.

Note, this section provides information about other dependencies in the mtd-utils tree.

How to change a file atomically?

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:

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 POSIX requirement and UBIFS satisfies it.

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, although we plan to implement it. Please, refer this section.

Does UBIFS support atime?

No, it does not support atime. The authors think it is not very useful in embedded world and did not implement this. Indeed most of the users do not provably want the file-system doing inode updates every time they are read.

Does UBIFS support NFS?

Not, it does not, which means you cannot export UBIFS file-system via NFS. We did make an attempt to support NFS, but the support was not exactly correct so it was dropped, and we have never find time to come back to that. Please, refer this tread for some more details. The original patch can also be found there.

Does UBIFS become slower when it is full?

Yes, UBIFS writes (but not reads) become slower when it is full or close to be full. There are 2 main reasons for this:

  • Note, also slows down when it is close to being full, but UBIFS should be better than JFFS2 in this respect (slow down less). This is because UBIFS always chooses optimal LEBs to garbage-collect, while JFFS2 may choose random eraseblocks.
  • Why df reports too few free space?

    UBIFS flash space accounting is quite challenging and it is not always possible to report accurate amount of free space. The df utility usually reports less free space than users may actually write to the file-system, but it never reports more space.

    UBIFS cannot precisely predict how much data the user will be able to write to the file-system. There are several reasons for this - compression, write-back, space wastage at the end of logical eraseblocks, garbage-collection, etc. Please, refer this section for details.

    Note, JFFS2 also has problems with free space predictions, but in average, it reports much more accurate amount of free space. However, JFFS2 may lie and report more free space than it actually has. For example, we experienced situations when JFFS2 reported 8MiB free space, while we were able to write only 2 MiB of data. This makes some user-space applications very unhappy.

    UBIFS also lies, but it always report less space that user may actually write. For example, it may report 2MiB of free space, but if you start writing to it, may be able to write 4MiB there (even if you have compression disabled).

    Thus, the only way to find out precise amount of free space is to fill up the file-system and see how much has been written. Try something like this:

    $ touch /mnt/ubifs/file
    $ chattr -c /mnt/ubifs/file # Disable compression for this file
    $ dd if=/dev/zero of=/mnt/ubifs/file bs=4096
    
    or
    # Presumably random data does not compress
    dd if=/dev/urandom of=/mnt/ubifs/file bs=4096
    

    and see the size of the file. And do not forget that some space is reserved for the super-user (see here), so it is better to be the root.

    UBIFS users should know that the more dirty cached FS data there are, the less precise is the df report. Try to create a big file, and look at the df report. Then synchronize the file-system (using the sync command) and look at the df report again. You should notice that df reports more free space after the synchronization. Here is an example:

    # Create a 64MiB uncompressible file
    $ dd if=/dev/urandom of=/mnt/ubifs/file bs=8192 count=8192
    $ df
    Filesystem           1K-blocks      Used Available Use% Mounted on
    ubi0:ubifs              117676     68880     43736  62% /mnt/ubifs
    
    $ sync
    $ df
    Filesystem           1K-blocks      Used Available Use% Mounted on
    ubi0:ubifs              117676     64304     48308  58% /mnt/ubifs
    

    Notice that the amount of free space increased by 4%. However, that was an uncompressible file. Here is a similar example, but which uses a file which compresses well:

    # Create a 64MiB file containing zeroes
    $ dd if=/dev/zero of=/mnt/ubifs/file bs=8192 count=8192
    $ df
    Filesystem           1K-blocks      Used Available Use% Mounted on
    ubi0:ubifs              117676     69312     43304  62% /mnt/ubifs
    
    $ sync
    $ df
    Filesystem           1K-blocks      Used Available Use% Mounted on
    ubi0:ubifs              117676      7052    105564   7% /mnt/ubifs
    

    If instead of synchronizing the file-system you just watch how the df report is changing, you will notice that the amount of free space continuously grows until reaches its final value. This happens because the kernel starts writing the dirty data back by time-out (5 sec by default) and the amount of dirty data goes down, making the df report more precize.

    If you want to have as precise free space prediction as possible - synchronize the file-system. This not only flushes dirty data to the media, this also commits UBIFS journal, which improves free space prediction even more. The other possibility is to mount UBIFS in synchronous mode using -o sync mount option. However, it may perform not as well as in asynchronous (default) mode.

    It is also worth noting that the closer is UBIFS to being full, the less accurate is free space reporting.

    To conclude:

    How to disable compression?

    UBIFS compression may be disabled for whole file system during the image creation time using the "-x none" mkfs.ubifs option. However, if UBIFS compression is enabled, it may be disabled for individual files by cleaning the inode compression flag:

    $ chattr -c /mnt/ubifs/file
    

    in shell, or

    /* Get inode flags */
    ioctl(fd, FS_IOC_GETFLAGS, &flags);
    /* Set "compression" flag */
    flags &= ~FS_COMPR_FL;
    /* Change inode flags */
    ioctl(fd, FS_IOC_SETFLAGS, &flags);
    

    in C programs. Similarly, if compression is disabled by default, you may enable if for individual inodes by setting the compression flag. Note, the code which uses the compression flag works fine on other Linux file-systems, because the flag is just ignored in this case.

    It might be a good idea to disable compression for say, mp3 or jpeg files which would anyway not compress and UBIFS would just waste CPU time trying to compress them. The compression may also be disabled if one wants faster file I/O, because UBIFS would not need to compress or decompress the data on reads and write. However, I/O speed may actually become slower if compression is disabled. Indeed, in case of a very fast CPU and very slow flash compressed writes are faster, but this is usually not true for embedded systems.

    How to use UBIFS with nandsim?

    The same way as with any MTD device. Here is an example of how to load nandsim, create an UBI volume and mount it.

    # Create an 256MiB emulated NAND flash with 2KiB NAND page size
    # (you should see the new MTD device in /proc/mtd)
    modprobe nandsim first_id_byte=0x20 second_id_byte=0xaa \
                     third_id_byte=0x00 fourth_id_byte=0x15
    
    # MTD is not LDM-enabled and udev does not create device
    # MTD device nodes automatically, so create /dev/mtd0
    # (we assume that you do not have other MTD devices)
    mknod /dev/mtd0 c 90 0
    
    # Load UBI module and attach mtd0
    modprobe ubi mtd=0
    
    # Create a 200MiB UBI volume with name "ubifs-vol"
    ubimkvol /dev/ubi0 -N ubifs-vol -s 200MiB
    
    # Mount UBIFS
    mount -t ubifs /dev/ubi0_0 /mnt/ubifs
    

    For more information about nandsim see here.

    How to extract files from an UBI/UBIFS image?

    Unfortunately, at the moment there are no user-space tools which can un-wrap UBI and UBIFS images. UBIFS cannot be loop-back mounted as well, because it does not work with block devices.

    However, there is a hacky way to un-wrap UBI/UBIFS images. But you have to make sure you have UBIFS support in your host machine. UBIFS is a relatively new file system and is not supported by all Linux distributions. But at least Fedora 11 does include it.

    Let's consider a simple example. Suppose you have an ubi.img file. This is an UBI image, which contains a single UBI volume, which in turn contains UBIFS file-system. In other words, this is an image which was created using the mkfs.ubifs and ubinize tools, just like it is described in this section (the image is created for a 256MiB NAND flash with 2KiB NAND page size and which supports sub-pages). Here is what you can do:

    # Create an 256MiB emulated NAND flash with 2KiB NAND page size
    # (you should see the new MTD device in /proc/mtd)
    modprobe nandsim first_id_byte=0x20 second_id_byte=0xaa \
                     third_id_byte=0x00 fourth_id_byte=0x15
    
    # MTD is not LDM-enabled and udev does not create device
    # MTD device nodes automatically, so create /dev/mtd0
    # (we assume that you do not have other MTD devices)
    mknod /dev/mtd0 c 90 0
    
    # Copy the contents of your image to the emulated MTD device
    dd if=ubi.img of=/dev/mtd0 bs=2048
    
    # Load UBI module and attach mtd0
    modprobe ubi mtd=0
    
    # Mount UBIFS
    mount -t ubifs /dev/ubi0_0 /mnt/ubifs
    

    Now you have the file-system in /mnt/ubifs. Use the following to get rid of it:

    umount /mnt/ubifs
    rmmod ubifs ubi nandsim
    

    Is UBIFS tolerant to power-cuts?

    Yes, both UBI (see here) and UBIFS are tolerant to power-cuts, and they were designed with this property in mind.

    UBIFS has internal debugging infrastructure to emulate power failures and the authors used it for extensive testing. It was tested for long time with power-fail emulation. The advantage of the emulation is that it emulates power failures even at the situations which happen not very often. For example, when the master node is updated, or the log is changed. The probability to interrupt the system at those moments is very low in real-life.

    Real power-cut tests have also done on OneNAND flash. We used Power Node devices which are controlled via serial line and may switch the power of the connected device on and off. UBIFS survived more than 100000 power-cuts while running stress tests.

    We've also done real power-cut tests on Spansion NOR flash. Some problems were found, but they were fixed and the board survived 10000 power-cuts after this. Please, see related discussions at the MTD mailing list. The thread has "UBIFS Corrupt during power failure" subject. The beginning of the thread may be found here, then it continues here, and then continues here, and here, and here.

    I need more space - should I make UBIFS journal smaller?

    UBIFS journal is very different to ext3 journal. In case of ext3, the journal has fixed position on the block device. The data are first written to the journal, and then copied to the file-system. This copying is done during the commit. After the commit, new data may be written to the journal, and so on. So in case of ext3 changing journal size would change file-system capacity.

    The situation is different in UBIFS. UBIFS journal is "wandering". It does not have fixed position in the UBI volume. When the journal is full, UBIFS is committing it which means it simply amends the FS index to refer the data which is stored in the journal. Then different LEBs are picked for the new journal, and so on. So the journal constantly migrates. The journal contains the same information as other data LEBs, but this information is just not referred from the index, it is not indexed. But there is flash space reserved for the indexing information, and this space is used during commit.

    In other words, if your file-system is full, the journal will also be full and contain data. And the situation does not really change if you vary journal size.

    To put it simple, the amount of available space on UBIFS does not really depend on the journal size. There is very weak dependency, though, because for bigger journal we need bigger log, but it is really something which does not make any noticeable difference.

    Why my file is empty after an unclean reboot?

    Zero-length files are a special case of corruption which happens when an application first truncates a file, then updates it. The truncation is synchronous in UBIFS, so it is written to the 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.

    Zero-length files also appear when an application creates a new file, then writes to the file, and a power cut happens. The reason is similar - file creation is a synchronous operation, data writing is not.

    Well, the description is a bit simplified. Actually, when a file is created or truncated, the creation/truncation UBIFS information is written to the write-buffer, not straight to the media. So if a power cut happens before the write-buffer is synchronized, the file will disappear (creation case) or stay intact (truncation case). But since the write-buffer is small and all UBIFS writes go there, it is usually synchronized very soon. After this point the file is created/truncated for real.

    There are several ways to affect the situation.

    1. Synchronize files using something like "fsync()" - this section contains all information about synchronization. But this does not guarantee that unclean reboots will not corrupt the file. Indeed, if an unclean reboot happens when only half of the data are written, the file will be corrupted/inconsistent. But this lessens the probability of corruptions.
    2. If you gave up fixing all your applications, you may mount UBIFS in synchronous mode - use "-o sync" mount option. But this makes UBIFS perform worse. And unfortunately, this also does not save you from all possible corruptions - you may still end up with holes (zeroes) at the end of files. See this section for more information.
    3. You may use the well-known atomic file update technique - see this section.
    4. You may use the Linux write-back knobs to lessen the dirty write-back time-out - see this section.

    The ext4 file-system helps buggy applications to lessen the probability of getting zero-length files by implementing a special hack. Please, refer this section for more information. UBIFS does not provide a similar hack, although we are planning to implement it.

    Why my file has zeroes at the end after an unclean reboot?

    Power cuts often lead to holes at the end of files. Holes are areas of the file which contain no data. For example, if you truncate a file to a larger size and synchronize it - you end up with a hole. Holes are read as zeroes. Often files with holes are referred to as sparse files. People sometimes deliberately create sparse files in order to save space - this is sometimes better than filling files with lots of zeroes.

    Please, read more information about how unclean reboots result in holes in this section.

    What does the "ubifs_bgt0_0" thread do?

    The UBIFS background thread is created for every mounted file-system and has "ubifs_bgtX_Y" name, where "X" is UBI device number and "Y" is UBI volume ID. For example, "ubifs_bgt1_2" is UBIFS background thread corresponding to the mounted volume 2 on UBI device 1.

    The background thread exists for optimization. One of its functions is background journal commit. It starts committing the journal in background when it is about 80% full. The idea is to make sure the journal is committed or almost committed by the time it becomes full, so writers would not have to wait for commit and keep writing data. The UBIFS presentation slides and the UBIFS white-paper contain more information about the journal and committing, see this section.

    The other function of the background thread is flushing write-buffers. Each write-buffer has a timer, and when the timer expires, the background thread is woken up and the write-buffer is flushed. Please, refer this section for more information about UBIFS write-buffers.

    Another thing which the background thread could do is background garbage collection, just like in JFFS2. However, this is not implemented and UBIFS does not garbage-collect in background at the moment.

    UBIFS suddenly became read-only - what is this?

    Read-write UBIFS file-system may suddenly become read-only because of an error. This is how UBIFS reacts on unexpected errors which it cannot properly handle - it immediately switches to read-only mode in order to protect the data from any possible further corruption.

    If this happened, you should look at UBIFS-related dmesg messages. UBIFS usually prints error messages before switching to read-only mode. The messages may shed some light on what happened. Feel free to ask for help from the MTD mailing list. If you think this is an UBIFS bug, please, send a bug report.

    I see this UBIFS error: "validate_sb: LEB size mismatch: 129024 in superblock, 126976 real"

    When you create an UBIFS image using the mkfs.ubifs utility, you specify LEB size using the -e option. This is a very important parameter and you should specify it correctly in order to have working UBIFS image. Indeed, LEB size is the major UBIFS storage unit, e.g., UBIFS nodes never cross LEB boundaries, garbage collection is performed on individual LEBs, etc. See this section for more information.

    The error message means that LEB size information which is stored in the UBIFS superblock does not match the real LEB size, which UBIFS takes from UBI. The superblock was created by the mkfs.ubifs utility, therefore you failed to pass the correct LEB size to the utility. Fix this by passing correct LEB size via the -e option.

    I see this UBI error: "ubi_io_read: error -74 while reading 126976 bytes from PEB 47:4096, read 126976 bytes"

    The -74 error code is -EBADMSG and means an ECC error. In other words, UBI tried to read some data from the flash, but the flash driver found that there is an uncorrectable ECC error, and returned -EBADMSG.

    There may be many reasons for this. It may be because your NAND driver is buggy, or you HW is buggy. We recommend you to validate the driver using the MTD tests.

    The other possibility is that you failed to flash your UBI/UBIFS image properly. Try to erase your flash, then attach it to UBI/UBIFS without writing any image, and check if you still have these errors.

    If you do not have errors when you mount empty flash, it is probably indeed related to how you flash the UBI/UBIFS images. One typical problem is related to ECC calculation algorithm - read here for more information. Make sure that you use ubiformat), or make sure your flashing program skips 0xFF properly (see here).

    Another possibility is that your flash does reports that it supports sub-page, but does not actually support them properly. In that case the -74 error happens when reading the first NAND page.

    I see this error: "INFO: task pdflush:110 blocked for more than 120 seconds"

    If this happens with a NOR flash, then this is a known issue and is about the UBI background thread doing a lot of erasures. When you attach to empty flash to UBI, it will format the flash in background, in the context of the UBI background thread (see here). Formatting means that for each eraseblock it does the following:

    Depending on your MTD/CFI chip driver the "MTD/CFI chip lock" may be held for the time it needs to erase an eraseblock. User-space applications which manipulate files on the UBIFS file-system may then also be blocked on the same "MTD/CFI chip lock. This causes pdflush to block as well since it tries to acquire the UBIFS journal mutex, which is already locked by the process which is waiting on the "MTD/CFI chip lock". See this discussion for some more details. The ways to solve this:
    1. Use ubiformat and format the NOR partition before attaching it to UBI. But this will not help in situations when you delete may files, and starts erasing many eraseblocks, so the "MTD/CFI chip lock" becomes very condtended.
    2. Use erase-suspend for writing (if your chip supports this).

    I want to study UBIFS - any recommendations?

    Follow these instructions.

    Last updated: 27 Oct 2008, dedekind Valid XHTML 1.0! Valid CSS!