Convert Raspberry Pi (1/2/3) to F2FS

What is F2FS?

From Wikipedia:

F2FS (Flash-Friendly File System) is a flash file system initially developed by Samsung Electronics for the Linux kernel.[2]

The motive for F2FS was to build a file system that, from the start, takes into account the characteristics of NAND flash memory-based storage devices (such as solid-state disks, eMMC, and SD cards), which are widely used in computer systems ranging from mobile devices to servers.

Basically, F2FS was a file system designed from the ground up for NAND-based devices. Motorola even started using F2FS for their Android smartphones. It’s designed to help reduce wear on the device, and improve performance on this type of storage medium. Since the Raspberry Pi was designed to run off of an SD card, it makes it a perfect candidate to play around with F2FS. It’s currently supported in the 4.4.y kernel so no need to compile your own kernel this time. For this project, you will need a USB flash drive or SSD/HDD via a USB adapter (You will lose all data on your USB device, back it up!) Let’s begin.

First we’ll want to upgrade our kernel and firmware to the latest available. Let’s update all of our packages first:

sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y dist-upgrade

Next, we’ll use a handy script included in Raspbian (not included with minimal image.) If you do not have the rpi-update script already, we’ll install it now, otherwise you may skip to the next step.

sudo apt-get install rpi-update

So let’s pull the latest kernel and firmware to our devices:

sudo rpi-update

Allow the process to finish without errors and then reboot. Next we’ll need to grab the tools we’ll need to format or repair a drive with F2FS format:

sudo apt-get install f2fs-tools

Once installed, we’ll need to plug in our USB device. If it is the only drive plugged in besides the MicroSD, it should populate as /dev/sda, otherwise you’ll want to check which disk is associated with the proper device. We’ll assume for educational purposes that it’s /dev/sda. (Doing this on the incorrect drive will DESTROY all your data, so check carefully.)

Let’s make sure our USB isn’t mounted:

sudo umount /dev/sda1

We’ll need to format our USB to ext4. I like to start fresh and create a new partition table while I’m at it:

sudo fdisk /dev/sda

From there, the fdisk prompt will appear. We will initialize the disk with a new partition table (enter in fdisk prompt):

o

Next, we’ll create a new partition:

n

You’ll be prompted for the partition type:

p

We’ll choose p for Primary. Next, we’ll be prompted for the partition number, you can choose 1, or hit enter for the default (which should be 1.)

1

Here we’ll be prompted for the first and last sector, you can hit enter to both for the default settings (It’s easier that way and it’ll use the whole disk.)

[Enter]
[Enter]

Finally our partition has been created. Now for the last step, we’ll use the command ‘w’ to write these changes to the disk.

w

If all is successful, fdisk will inform you that it was successful and exit. If you see any error relating to syncing the partition table, you can simply reboot at this point and continue with the steps. We’ll now format the USB with ext4:

sudo mke2fs -t ext4 -L rootfs /dev/sda1

If you are prompted that there’s an existing filesystem, you may safely overwrite the filesystem by choosing ‘y’. Next we’ll need to mount our USB drive so we can back up our MicroSD root partition:

sudo mount /dev/sda1 /mnt

Next we’ll use rsync to mirror our root partition to the USB, so we can restore all of our files to the newly created F2FS partition:

sudo rsync -axv / /mnt

This process can take some time depending on how much data you have. Once it’s complete, we’ll need to boot from the USB so we can format the MicroSD partition. We’ll need to modify two files. You can use your favorite text editor to modify the files, I prefer nano (sorry vim fanboys):

sudo nano /mnt/etc/fstab

First we’ll add a # in front of the /dev/mmcblk0p2 line. Then we’ll need to add a new line at the bottom that looks like this:

/dev/sda1     /          ext4     defaults,noatime     0     1

This line tells the kernel that the root partition is on /dev/sda1.

You can hit CTRL + O to save with nano, you’ll be prompted for the file name/location, leave it alone and hit enter. Then you can hit CTRL + X to quit. We’ll need to modify one more file:

sudo nano /boot/cmdline.txt

You’ll want to change from this:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

To:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait rootdelay=5

The only changes made were setting the root partition to ‘root=/dev/sda1’ instead of mmcblk0p2 and added ‘rootdelay=5’ to the end so the kernel waits a couple seconds for the USB device to be ready. In nano we can again do CTRL + O to save the file, and CTRL-X to exit. NOTE: You may use this method to use a USB device as your root partition! Pretty neat, huh? Now reboot and unmount:

sudo umount /mnt
sudo reboot

If all went well, we should boot right up with no issues. Now that the MicroSD root partition is no longer in use, we can format it. We’ll use wipefs to remove the ext4 filesystem:

sudo wipefs -a /dev/mmcblk0p2

Finally we can format our MicroSD root partition to f2fs:

sudo mkfs.f2fs /dev/mmcblk0p2

If you are prompted about overwriting an existing filesystem, you may choose ‘y’. Once finished, we’ll need to mount the MicroSD root partition so we can copy our files back:

sudo mount /dev/mmcblk0p2 /mnt

Once again, we’ll use rsync to copy all of our data back:

sudo rsync -axv / /mnt

This should take a little bit. Once it’s done, we’ll need to edit /boot/cmdline.txt and /mnt/etc/fstab again. We’ll start with /mnt/etc/fstab:

sudo nano /mnt/etc/fstab

Here we can delete or comment out the /dev/sda1 line, and uncomment the /dev/mmcblk0p2 line by deleting the #. Then you’ll want your /dev/mmcblk0p2 line to reflect these values:

/dev/mmcblk0p2  /               f2fs    defaults,noatime,discard	0       1

If your device is does not support TRIM, you can remove the discard option. Typically, most SD cards/eMMC/SSD will support this command, while USB flash drives may not. You’ll know during the mkfs.f2fs process as it will tell you whether your device does or not. Close and save the file once the changes are complete and accurate. Only one more file to modify and then we’re set:

sudo nano /boot/cmdline.txt

We’ll change ‘root=/dev/sda1’ to ‘root=/dev/mmcblk0p2’, ‘rootfstype=ext4’ to ‘rootfstype=f2fs’ and finally remove ‘rootdelay=5’ since we are no longer booting from a USB device. It should look similar to this:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=f2fs elevator=deadline fsck.repair=yes rootwait

Now we’ll unmount the SD and reboot using our new F2FS root partition:

sudo umount /mnt
sudo reboot

And we’re done! Enjoy F2FS on your Pi!

Question/Comments? Leave feedback in the comments.

 

17 Comments

    • ryan

      I’m not sure if f2fs-tools are available in Wheezy, I would check the backports repo for Wheezy, otherwise I would look at upgrading to Jessie.

  1. Serge J.

    “Finally we can format our MicroSD root partition to f2fs: sudo mkfs.f2fs /dev/sda1”

    Shouldn’t we use “/dev/mmcblk0p2” instead of “/dev/sda1” there?

  2. lsar

    instead
    sudo umount / dev / sda
    must be
    sudo umount / dev / sda1

    before
    sudo wipefs -a / dev / mmcblk0p2
    must be
    sudo umount / dev / mmcblk0p2

    • ryan

      I have made the first fix, thank you. The second, however, is not necessary because when using the USB stick as root, mmcblk0p2 is not mounted by default, only mmcblk0p1 (boot). I appreciate the comment!

  3. Stumpy

    Does this work with the latest full noobs?
    Wondering about the partitioning as a result of using noobs to install raspbian.

  4. zach

    It looks like this method actually rsync’s two copies of the root filesystem (one from /, and one from /media/usb0) when copying files back onto the SD card.

    There is only a single copy on the USB drive (using hard links?), but rsync sees them as separate and thusly syncs both. After all is said and done, the SD card is using >2x the space (4.7G on /dev/mmcblk0p2 mounted on /mnt vs. 2.1G on /dev/root (USB drive)).

    Probably should add an –exclude /medua/usb0 to the 2nd rsync step.

    Workaround for now is to reboot from SD card and rm -rf /media/usb0/* to free up that extra space.

    • ryan

      All rsync does is copy and preserve permissions/ownership from one source to another. I’m not sure where you’re getting /media/usb0, it sounds like a custom mount you created. Because no one else likely has that custom mount point, there’s no need to add the instructions, but it sounds like it was necessary in your situation. Good to have that information.

Leave a Reply

Your email address will not be published. Required fields are marked *