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

Reply via email to