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.
I don’t get f2fs-tools (unable to locate).
sources.list says:
deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
All five steps as noted above (before f2fs-tools) were carried out successfully. Any hint about what’s wrong? I’m using Raspberry 1.
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.
“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?
You’re right! Thanks for catching that. Fixed
instead
sudo umount / dev / sda
must be
sudo umount / dev / sda1
before
sudo wipefs -a / dev / mmcblk0p2
must be
sudo umount / dev / mmcblk0p2
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!
https://www.youtube.com/watch?v=WUZ1iwSLq7U&t=56s
Great idea making a video tutorial!
Thanks for this Tutorial.
Works great ! Thanks for the tutorial.
Does this work with the latest full noobs?
Wondering about the partitioning as a result of using noobs to install raspbian.
To be honest, I’ve never used NOOBS before. I’m not sure what the partition scheme looks like.
This:
sudo nano /mnt/etc/fstab
should be:
sudo nano /etc/fstab
I mean, the first call.
We don’t want to modify fstab for the device we are no longer using as the root filesystem. Further, when we use rsync to copy back the filesystem to the new F2FS partition, I chose to modify fstab before copying over, so doing so is not needed.
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.
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.