Commit 390fe587b1 ("fsck.f2fs: support restore lost files into ./lost_found/") restores unreachable files, which have no parent directory or their parent directories are removed by fsck, to ./lost_found directory.
However, it has several limitations: 1. ./lost_found dir does not locate inside f2fs, thus it may needs another partition to save ./lost_found. 2. encrypted files are not supported to be restored. 3. some xattrs may be lost, it depends on whether dump_node() enables dumping such xattrs. 4. not support restoring files on Android devices (the same reason as #1). In order to address the above limitations, the lost+found feature is introduced. This is an ext4-style lost+found. It tries to restore unreachable files into /lost+found directory inside f2fs. If lost+found feature is switched on when mkfs, /lost+found directory is created by mkfs. It can also be created by mkdir manually. It should be located right under root directory. If fsck detects unreachable nids, it scans all these nids, and skips non- inode or directory inode nodes. For the left nids, they are all file inodes. Fsck then checks these inodes and update corresponding counters and bitmaps. From now on, the filesystem is in a "consistent" state, fsck can allocate blocks safely and start reconnecting files to lost+found. The reconnection adds new dentry in lost+found and update metadata (i_name, i_pino) of file inode. If reconnection fails, fsck will clear the counters and bitmaps. Files reconnected to lost+found will be renamed after its ino number. However, because of lost+found directory, f2fs should avoid to encrypting root directory. So f2fs should also check if lost+found feature is enabled or not. I create a testcase which injects faults to generate unreachable nids. $ mkfs.f2fs -O lost+found -O encrypt test.img $ tree /data /data ├── dir │ ├── foo │ └── subdir │ └── bar ├── encrypt-dir │ ├── foo │ └── subdir │ └── bar └── lost+found Inject nat_entry->blk_addr of dir/encrypt-dir to 0. $ fsck.f2fs -f test.img Info: Force to fix corruption Info: Segments per section = 1 Info: Sections per zone = 1 Info: sector size = 512 Info: total sectors = 204800 (100 MB) Info: MKFS version "Linux version 4.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017" Info: FSCK version from "Linux version 4.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017" to "Linux version 4.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017" Info: superblock features = 201 : encrypt lost+found Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000 Info: total FS sectors = 204800 (100 MB) Info: CKPT version = 2995f9d3 Info: Found valid nat_bits in checkpoint Info: checkpoint state = 1c5 : trimmed nat_bits crc compacted_summary unmount [ASSERT] (sanity_check_nid: 386) --> nid[0x5] ino is 0 [FIX] (__chk_dentries:1456) --> Unlink [0x5] - dir len[0x3], type[0x2] [ASSERT] (sanity_check_nid: 386) --> nid[0xd] ino is 0 [FIX] (__chk_dentries:1456) --> Unlink [0xd] - encrypt-dir len[0xb], type[0x2] [ASSERT] (fsck_chk_inode_blk: 895) --> ino: 0x3 i_links: 5, real links: 3 [FIX] (fsck_chk_inode_blk: 900) --> Dir: 0x3 i_links= 0x5 -> 0x3 NID[0x6] is unreachable NID[0x7] is unreachable NID[0x8] is unreachable NID[0x9] is unreachable NID[0xa] is unreachable NID[0xb] is unreachable NID[0xc] is unreachable NID[0xe] is unreachable NID[0xf] is unreachable NID[0x10] is unreachable [FSCK] Reconnect 4 files to lost+found [FSCK] Unreachable nat entries [Fail] [0xa] [FSCK] SIT valid block bitmap checking [Fail] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Fail] [0xc56] [FSCK] valid_node_count matcing with CP (de lookup) [Fail] [0xa] [FSCK] valid_node_count matcing with CP (nat lookup) [Fail] [0xc] [FSCK] valid_inode_count matched with CP [Fail] [0x6] [FSCK] free segment_count matched with CP [Ok..] [0x1e] [FSCK] next block offset is free [Ok..] [FSCK] fixing SIT types [FSCK] other corrupted bugs [Fail] [FIX] (nullify_nat_entry:2064) --> Remove nid [0xb] in NAT [FIX] (nullify_nat_entry:2064) --> Remove nid [0xf] in NAT Info: Write valid nat_bits in checkpoint Done. $ tree /data /data/ └── lost+found ├── 12 ├── 14 ├── 16 └── 6 Any comments and tests are appreciated. Thanks, Sheng Sheng Yong (5): mkfs.f2fs: introduce mkfs parameters in f2fs_configuration f2fs-tools: init f2fs_configuration wit as 0 fsck.f2fs: integrate sanity_check_inode to __check_inode_mode mkfs.f2fs: create lost+found directory fsck.f2fs: reconnect unreachable files to lost+found fsck/dir.c | 19 ++- fsck/fsck.c | 402 +++++++++++++++++++++++++++++++++++++++++++++--- fsck/fsck.h | 3 + fsck/mount.c | 5 + include/f2fs_fs.h | 11 ++ lib/libf2fs.c | 18 +-- mkfs/f2fs_format.c | 251 ++++++++++++++++++++++++++---- mkfs/f2fs_format_main.c | 2 + 8 files changed, 639 insertions(+), 72 deletions(-) -- 2.11.0 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel