# F2FS

F2FS (Flash-Friendly File System) is a flash file system initially developed by Samsung Electronics for the Linux kernel.
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.
F2FS was designed on a basis of a log-structured file system approach, which is adapted to newer forms of storage. Jaegeuk Kim, the principal F2FS author, has stated that it remedies some known issues of the older log-structured file systems, such as the snowball effect of wandering trees and high cleaning overhead. In addition, since a NAND-based storage device shows different characteristics according to its internal geometry or flash memory management scheme (such as the Flash Translation Layer or FTL), it supports various parameters not only for configuring on-disk layout, but also for selecting allocation and cleaning algorithms.
Note, that by default F2FS uses "posix" fsync scheme, which carries higher risks of leaving the file system in dirty state during unclean shutdown (as it does not guarantee atomicity of write operations) at the benefit of better performance. There is a more stringent method that respects hardware limitations for greater security at the expense of performance; see the "fsync_mode" option in the manual for details.

## Features

* Multi-head logging
* Multi-level hash table for directory entries
* Static/dynamic hot and cold data separation
* Adaptive logging scheme
* Configurable operational units
* Dual checkpoint
* Roll-back and roll-forward recovery
* Heap-style block allocation
* TRIM/FITRIM support
* Online fs defragmentation/file defragmentation
* Inline xattrs/data/dir
* Offline filesystem check (Check and fix inconsistency)
* Atomic operations
* Filesystem-level encryption
* Offline resizing (shrinking not supported.)
* Inner periodically data flush
* Extent cache
* Transparent file compression using LZO or LZ4 (with Linux 5.6), or zstd (with Linux 5.7)

## Design
### On-disk layout

F2FS divides the whole volume into a number of segments, each of which is fixed at 2 MB. A section is composed of consecutive segments, and a zone consists of a set of sections. By default, section and zone sizes are set to the same size, but users can easily modify the size with mkfs.
F2FS splits the entire volume into six areas, and all except the superblock area consist of multiple segments as described below.

#### Superblock (SB)

    The SB is located at the beginning of the partition. There are two copies to avoid file-system corruption. It contains basic partition information and some default F2FS parameters.

#### Checkpoint (CP)

    The CP contains file system information, bitmaps for valid NAT/SIT sets, orphan inode lists, and summary entries of current active segments.

#### Segment Information Table (SIT)

    The SIT contains the valid block count and validity bitmap of all the Main Area blocks.

#### Node Address Table (NAT)

    The NAT is an address table for the Main Area node blocks.

#### Segment Summary Area (SSA)

    The SSA contains entries which contain the owner information of the Main Area data and node blocks.

#### Main Area

    The main area contains file and directory data and their indices.
In order to avoid misalignment between file system and flash storage, F2FS aligns the start block address of the CP with the segment size. It also aligns the Main Area start block address with the zone size by reserving some segments in the SSA area.

### Metadata structure

F2FS uses the checkpoint scheme to maintain file system integrity. At mount time, F2FS first tries to find the last valid checkpoint data by scanning the CP area. In order to reduce the scanning time, F2FS uses only two copies of the CP. One of them always indicates the last valid data, which is called a shadow copy mechanism. In addition to the CP, the NAT and SIT also use the shadow copy mechanism. For file system consistency, each CP points to which NAT and SIT copies are valid.

### Index structure

The key data structure is the "node". Similar to traditional file structures, F2FS has three types of nodes: inode, direct node, indirect node. F2FS assigns 4 KB to an inode block which contains 923 data block indices, two direct node pointers, two indirect node pointers, and one double indirect node pointer as described below. A direct node block contains 1018 data block indices, and an indirect node block contains 1018 node block indices. Thus, one inode block (i.e., a file) covers:
Note that all the node blocks are mapped by the NAT, which means that the location of each node is translated by the NAT. To mitigate the wandering tree problem, F2FS is able to cut off the propagation of node updates caused by leaf data writes.

### Directory structure

A directory entry (dentry) occupies 11 bytes, which consists of the following attributes.
A directory entry structure :
| hash | Hash value of the file name |
| ino | Inode number |
| len | The length of file name |
| type | File type such as directory, symlink, etc. |
A dentry block consists of 214 dentry slots and file names. A bitmap is used to represent whether each dentry is valid or not. A dentry block occupies 4 KB and has the following composition:
F2FS implements multi-level hash tables for the directory structure. Each level has a hash table with a dedicated number of hash buckets as shown below. Note that "A(2B)" means a bucket includes 2 data blocks.

#### Term

    A indicates bucket
    B indicates block
    N indicates MAX_DIR_HASH_DEPTH
When F2FS finds a file name in a directory, first a hash value of the file name is calculated. Then, F2FS scans the hash table in level #0 to find the dentry consisting of the file name and its inode number. If not found, F2FS scans the next hash table in level #1. In this way, F2FS scans hash tables in each level incrementally from 1 to N. In each level F2FS needs to scan only one bucket determined by the following equation, which shows O(log(# of files)) complexity.
In the case of file creation, F2FS finds empty consecutive slots that cover the file name. F2FS searches the empty slots in the hash tables of whole levels from 1 to N in the same way as the lookup operation.

### Default block allocation

At runtime, F2FS manages six active logs inside the "Main Area:" Hot/Warm/Cold node and Hot/Warm/Cold data.
Block allocation policy :
| Hot node | Contains direct node blocks of directories. |
| Warm node | Contains direct node blocks except hot node blocks. |
| Cold node | Contains indirect node blocks. |
| Hot data | Contains dentry blocks. |
| Warm data | Contains data blocks except hot and cold data blocks. |
| Cold data | Contains multimedia data or migrated data blocks. |
LFS has two schemes for free space management: threaded log and copy-and-compaction. The copy-and-compaction scheme which is known as cleaning, is well-suited for devices showing very good sequential write performance, since free segments are served all the time for writing new data. However, it suffers from cleaning overhead during high utilization. Conversely, the threaded log scheme suffers from random writes, but no cleaning process is needed. F2FS adopts a hybrid scheme where the copy-and-compaction scheme is adopted by default, but the policy is dynamically changed to the threaded log scheme according to the file system status.
In order to align F2FS with underlying flash-based storage, F2FS allocates a segment in a unit of a section. F2FS expects the section size to be the same as the garbage collection unit size in FTL. With respect to the mapping granularity in FTL, F2FS allocates each section of the active logs to as many different zones as possible. FTL can write the active log data into one allocation unit according to its mapping granularity.

### Cleaning process

F2FS does cleaning both on demand, and in the background. On-demand cleaning is triggered when there are not enough free segments to serve VFS calls. The background cleaner is executed by a kernel thread, and triggers the cleaning job when the system is idle.
F2FS supports two victim selection policies: greedy, and cost-benefit algorithms. In the greedy algorithm, F2FS selects a victim segment having the smallest number of valid blocks. In the cost-benefit algorithm, F2FS selects a victim segment according to the segment age and the number of valid blocks in order to address the log block thrashing problem present in the greedy algorithm. F2FS uses the greedy algorithm for on-demand cleaning, the background cleaner uses the cost-benefit algorithm.
In order to identify whether the data in the victim segment are valid or not, F2FS manages a bitmap. Each bit represents the validity of a block, and the bitmap is composed of a bit stream covering whole blocks in the Main Area.

## Adoption
### Phone manufacturers

Google first used F2FS in their Nexus 9 in 2014.
However Google's other products didn't adopt F2FS until the Pixel 3 when F2FS was updated with inline crypto hardware support.
Huawei has used F2FS since the Huawei P9 in 2016.
OnePlus has used F2FS in the OnePlus 3T.
Motorola Mobility has used F2FS in their Moto G/E/X and Droid phones since 2012.
ZTE has used F2FS since the ZTE Axon 10 Pro in 2019.

### Linux distributions

F2FS has been merged into Linux kernel in late 2012. Many distributions support it.

## Detailed features description

| Feature name | Description | Kernel version | F2FS tools version | Kernel commit | F2FS tools commit |
| Lost parent inode number (pino) bit | If a file is linked, F2FS may loose its parent inode number so that fsync calls for the linked file need to perform the checkpoint every time. But, if the pino can be recovered after the checkpoint, roll-forward mechanism for the further fsync calls can be adjusted, which improves the fsync performance significantly. | 3.11 | N/A | 354a3399dc6f ("f2fs: recover wrong pino after checkpoint during fsync") | N/A |
| Inline extended attributes | Add a mount option inline_xattr, which is enabled when xattr is set, if the mount option is enabled, all the files are marked with the inline_xattrs flag. | 3.12 | 1.2.0 | 444c580f7e9a ("f2fs: add flags for inline xattrs") | cd1e470 ("fsck, lib: support inline xattr") |
| Inline data | Support inline data in regular/symlink inode via inline_data mount option. | 3.14 | 1.3.0 | 1001b3479ce9 ("f2fs: add flags and helpers to support inline data") | 061ee67 ("f2fs-tools: add inline data check") |
| Large directory | Add a parameter to adjust structure of large directory for lookup performance tuning. | 3.15 | 1.4.0 | 3843154598a0 ("f2fs: introduce large directory support") | 99250ec ("mkfs: support large directory") |
| Large volume | Support for large volumes over around 3TB. | 3.16 | 1.4.0 | 1dbe4152168d ("f2fs: large volume support") | 092e3d9 ("mkfs.f2fs: large volume support") |
| Fsck flag | Adds "need fsck" flag to superblock to conduct fsck.f2fs later, this flag can only be removed by fsck.f2fs. | 3.18 | 1.4.0 | 2ae4c673e3cb ("f2fs: retain inconsistency information to initiate fsck.f2fs") | 7eb6c5a ("fsck.f2fs: add auto_fix feature") |
| Fastboot flag | Allow checkpoint write node summaries to speed up boot after a sudden poweroff. | 3.2 | 1.4.1 | 119ee9144534 ("f2fs: split UMOUNT and FASTBOOT flags") | b57708a ("dump.f2fs: show checkpoint flag") |
| Inline data (fix) | Enhance stability of inline_data feature (changes disk layout). | 3.19 | 1.4.1 | b3d208f96d6b ("f2fs: revisit inline_data to avoid data races and potential bugs") | 7279f03 ("fsck.f2fs: fix DATA_EXIST flag for old partition") |
| Inline dentry | Support storing of directory entries in the directory inode. | 3.19 | 1.4.1 | 34d67debe02b ("f2fs: add infra struct and helper for inline dir") | 6d88640 ("fsck.f2fs: support inline_dentry") |
| Version info | Stores current kernel version, updated on fsck. | 4.2 | 1.4.1 | 0040b933187b ("f2fs: add missing version info in superblock") | 6fa2547 ("fsck.f2fs: trigger fsck.f2fs when new change was made") |
| Initial version info | Identifies the Linux kernel version when the format was done. | 4.2 | 1.4.1 | 0040b933187b ("f2fs: add missing version info in superblock") | 762eedf ("mkfs.f2fs: give a kernel version for initial format") |
| Keep size bit | Ensures preallocated (with fallocate) file size does not change during roll-forward recovery. If a file needs to keep its i_size set by fallocate, autorecovery needs to be turned off during roll-forward recovery | 4.1 | N/A | 26787236b366 ("f2fs: do not activate auto_recovery for fallocated i_size") | N/A |
| Inline dots | Support to fix directory which has no '.' or '..' dentries, it changes disk layout | 4.1 | 1.5.0 | 510022a85839 ("f2fs: add F2FS_INLINE_DOTS to recover missing dot dentries") | f1e4f9c ("fsck.f2fs: fix missing dentries") |
| Encryption | Enables support for filesystem level encryption. | 4.2 | 1.5.0 | cde4de120577 ("f2fs crypto: declare some definitions for f2fs encryption feature") | 6e6c713 ("mkfs.f2fs: set encryption feature") |
| Block zoned | Specify F2FS filesystem to support the block zoned feature. It depends on multiple devices feature. | 4.8 | 1.7.0 | 52763a4b7a21 ("f2fs: detect host-managed SMR by feature flag") | 70a8fc3 ("mkfs/fsck: add host-managed smr feature") |
| Multiple devices | Enable support for multiple physical storage devices to be treated as a single logical volume | 4.1 | 1.8.0 | 3c62be17d4f5 ("f2fs: support multiple devices") | de7e07e ("f2fs-tools: support multiple devices") |
| Trimmed flag | Optimizes the handling of discarded blocks. This flag (CP_TRIMMED_FLAG) allows the F2FS kernel module to record that all invalid blocks were trimmed before umount, so on the next mount these operations can be skipped. | 4.12 | 1.9.0 | 1f43e2ad7bff ("f2fs: introduce CP_TRIMMED_FLAG to avoid unneeded discard") | f642b24 ("f2fs-tools: support to set and recognize CP_TRIMMED_FLAG") |
| NAT bits | Adds bitmaps to represent empty/full NAT blocks containing all used/free nid entries to optimize the management of NAT blocks. | 4.11 | 1.9.0 | 22ad0b6ab466 ("f2fs: add bitmaps for empty or full NAT blocks") | 191573e ("mkfs.f2fs: support nat_bits feature") |
| CRC recovery | Use CRC in addition to checkpoint version during roll-forward recovery. This allows for a more robust and reliable way to determine which version of the file to recover. Introduces new flag (CP_CRC_RECOVERY_FLAG) to indicate when the new mechanism is used. | 4.9 | 1.9.0 | a468f0ef516f ("f2fs: use crc and cp version to determine roll-forward recovery") | a0bd5b9 ("f2fs-tools: catch up up-to-date checkpoint flag") |
| Atomic write | Atomic write feature, this feature does not change disk layout. | 4.14 | 1.9.0 | e65ef20781cb ("f2fs: add ioctl to expose current features") | 8721519 ("f2fs-tools: add atomic_write feature flag") |
| Extra attributes | Enable extra attributes feature, required for some of the other features (see below). | 4.14 | 1.9.0 | 7a2af766af15 ("f2fs: enhance on-disk inode structure scalability") | dad33a1 ("f2fs-tools: enhance on-disk inode structure scalability") |
| Project quota | Enable project ID tracking for projet quota accounting. Uses extra attributes. | 4.14 | 1.9.0 | 5c57132eaf52 ("f2fs: support project quota") | a3d9db1 ("f2fs-tools: support project quota") |
| Inode checksum | Enable inode checksum. Uses extra attributes. | 4.14 | 1.9.0 | 704956ecf5bc ("f2fs: support inode checksum") | 7457726 ("f2fs-tools: support inode checksum") |
| Nocrc recovery | Disables the use of CRC during the checkpoint recovery process relying solely on the checkpoint version. | 4.16 | 1.10.0 | f236792311f4 ("f2fs: allow to recover node blocks given updated checkpoint") | f789444 ("fsck.f2fs: allow roll-forward for small checkpoint fix") |
| Flexible inline xattr | Enable flexible inline xattr size. Uses extra attributes. | 4.15 | 1.10.0 | 6afc662e68b5 ("f2fs: support flexible inline xattr size") | 8d46072 ("f2fs-tools: support flexible inline xattr size") |
| Quota sysfile | Enable quota feature (it allows F2FS to maintain an inner sysfile for disk quota data recording). | 4.15 | 1.10.0 | 234a96896142 ("f2fs: add quota_ino feature infra") | 23a872f ("mkfs.f2fs: support quota option in mkfs") |
| Pinfile | Support pinfile to avoid migration of its physical data blocks. | 4.16 | 1.12.0 | 1ad71a27124c ("f2fs: add an ioctl to disable GC for specific file") | "91bb7b2 (""f2fs-tools: fix to reset i_gc_failures offline"") 820b5e3 (""sload.f2fs: use F2FS_COMPRESS_RELEASED instead of IMMUTABLE bit"") added the F2FS_PIN_FILE flag w/o any use." |
| Inode creation time | Enable inode creation time feature. Requires extra attributes. | 4.16 | 1.10.0 | 1c1d35df7110 ("f2fs: support inode creation time") | 4862080 ("f2fs-tools: support inode creation time") |
| Extended node bitmap | Enable extended node bitmap to increase upper boundary limitation of node block count. | 4.17 | 1.11.0 | 199bc3fef29c ("f2fs: support large nat bitmap") | baaa076 ("mkfs.f2fs: expand scalability of nat bitmap") |
| Hot file extensions | Allows specifying a list of file extensions that F2FS will treat as hot files. The data of files with those extensions will be stored in the hot log. | 4.17 | 1.11.0 | b6a06cbbb5f7 ("f2fs: support hot file extension") | 6fdc37f ("mkfs.f2fs: support hot file extension") |
| lost+found | Enable lost+found feature. | 4.17 | 1.11.0 | b7c409deda6b ("f2fs: introduce F2FS_FEATURE_LOST_FOUND feature") | ff37829 ("mkfs.f2fs: create lost+found directory") |
| fs-verity | Enable support for verity protected files (a.k.a. fs-verity). | 5.4 | 1.11.0 | 95ae251fe828 ("f2fs: add fs-verity support") | 76cd377 ("mkfs.f2fs: support fsverity feature") |
| Checkpoint disable flag | Indicate checkpoint is disabled. | 4.2 | 1.12.0 | 4354994f097d ("f2fs: checkpoint disabling") | a48bda0 ("fsck.f2fs: support checkpoint=disable") |
| Quota needs fsck | Add a global state SBI_QUOTA_NEED_REPAIR to indicate that quota operation failed due to -EIO or -ENOSPC, so later, a) checkpoint will skip syncing dquot metadata. b) CP_QUOTA_NEED_FSCK_FLAG will be set in last cp pack to give a hint for fsck repairing. | 4.2 | 1.12.0 | af033b2aa8a8 ("f2fs: guarantee journalled quota data by checkpoint") | dfede78 ("fsck.f2fs: detect and recover corrupted quota file") |
| Superblock checksum | Enable superblock checksum. | 4.2 | 1.12.0 | d440c52d3151 ("f2fs: support superblock checksum") | 886a924 ("f2fs-tools: introduce sb checksum") |
| Checkpoint disable quick | Add a quick method of checkpoint disabling. | 5.1 | N/A | db610a640eee ("f2fs: add quick mode of checkpoint=disable for QA") | N/A |
| Casefolding | Enable casefolding support in the filesystem. Optional flags can be passed with -C. | 5.4 | 1.13.0 | 5aba54302a46 ("f2fs: include charset encoding information in the superblock") | ce64ea0 ("f2fs-tools: Add support for Casefolding") |
| Compression | Enable support for filesystem level compression. Requires extra attributes. | 5.6 | 1.14.0 | 4c8ff7095bef ("f2fs: support data compression") | fdd47b2 ("f2fs-tools: support data compression") |
| Resize FS flag | Introduces a new checkpoint flag, CP_RESIZEFS_FLAG, to help fsck fix issues related to online resizing. | 5.7 | 1.14.0 | c84ef3c5e65c ("f2fs: Add a new CP flag to help fsck fix resize SPO issues") | 9a31cef ("fsck.f2fs: allow fsck to fix issues with online resize due to SPO") |
| Compression (fix) | This change introduces a new flag (F2FS_COMPRESS_RELEASED) to represent the status of the released compressed blocks. Previously used IMMUTABLE bit prevented all operations on the released block. | 5.14 | 1.15.0 | c61404153eb6 ("f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit") | 820b5e3 ("sload.f2fs: use F2FS_COMPRESS_RELEASED instead of IMMUTABLE bit") |
| Readonly image | Enable readonly feature to eliminate OVP/SSA on-disk layout for small readonly partition. | 5.14 | 1.15.0 | a7d9fe3c3388 ("f2fs: support RO feature") | 1d2683f ("f2fs-tools: support small RO partition") |
| Trunc bit | "Direct IO (DIO) preallocates physical blocks before writing actual data, but if an error occurrs or a power-cut happens, the unwritten blocks' contents can be accessed by the user. This patch fixes it by: 1) turning to buffered writes for DIO into holes 2) truncating unwritten blocks from error or power-cut." | 5.17 | N/A | d4dd19ec1ea0 ("f2fs: do not expose unwritten blocks to user by DIO") | N/A |
| CP error recording | Supports recording the detailed stop checkpoint error into f2fs_super_block.s_stop_reason. | 6.1 | 1.16.0 | a9cfee0ef98e ("f2fs: support recording stop_checkpoint reason into super_block") | 2f1dde2 ("fsck.f2fs: trigger repairing if filesystem was forced to stop") |
| FS error recording | Supports recording the detailed reason of FSCORRUPTED error into f2fs_super_block.s_errors. | 6.1 | 1.16.0 | 95fa90c9e5a7 ("f2fs: support recording errors into superblock") | 8cbe34e ("fsck.f2fs: trigger repairing if filesystem has inconsistent errors") |
| 16KB block support | Supports for 16K block size, mkfs can choose block size via the -b option, with other tools getting the blocksize from the superblock. | 6.7 | Not released yet | d7e9a9037de2 ("f2fs: Support Block Size == Page Size") | 50fd00b ("f2fs-tools: Support different block sizes") c404632 ("f2fs-tools: Refactor f2fs_dentry_block struct") ef47782 ("f2fs-tools: Refactor Summary block struct and friends") bb051c7 ("f2fs-tools: Refactor SIT/NAT block structs") 32f5a37 ("f2fs-tools: Refactor f2fs_node struct and friends") b1aeb99 ("f2fs-tools: Refactor Orphan Block struct") 30825b3 ("f2fs-tools: Define constants in terms of BLKSIZE") |
| Device alias | Enables device aliasing feature. | 6.13 | Not released yet | 128d333f0dff ("f2fs: introduce device aliasing file") | 8cc4e25 ("mkfs.f2fs: add device aliasing feature") |