fsck.f2fs: read ahead xattr & direct node blocks
authorYunlei He <heyunlei@huawei.com>
Mon, 29 Jan 2018 09:37:41 +0000 (17:37 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 7 May 2018 21:49:37 +0000 (14:49 -0700)
This patch read ahead xattr & direct node blocks, and
keep the order:

1. check data blocks
2. readahead xattr block
3. fsck xattr block
4. readahead {d,id,did}node block
5. fsck {d,id,did}node block

With above order, we can avoid unneeded readahead before
sub-directory iterated traversing or encountering error.

Signed-off-by: Yunlei He <heyunlei@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: Fix a bug breaking the right order.]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fsck/fsck.c

index 668ecc1..443a44f 100644 (file)
@@ -621,6 +621,29 @@ unmatched:
        child->state |= FSCK_UNMATCHED_EXTENT;
 }
 
+void fsck_reada_node_block(struct f2fs_sb_info *sbi, u32 nid)
+{
+       struct node_info ni;
+
+       if (nid != 0 && IS_VALID_NID(sbi, nid)) {
+               get_node_info(sbi, nid, &ni);
+               if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr))
+                       dev_reada_block(ni.blk_addr);
+       }
+}
+
+void fsck_reada_all_direct_node_blocks(struct f2fs_sb_info *sbi,
+                                               struct f2fs_node *node_blk)
+{
+       int i;
+
+       for (i = 0; i < NIDS_PER_BLOCK; i++) {
+               u32 nid = le32_to_cpu(node_blk->in.nid[i]);
+
+               fsck_reada_node_block(sbi, nid);
+       }
+}
+
 /* start with valid nid and blkaddr */
 void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
                enum FILE_TYPE ftype, struct f2fs_node *node_blk,
@@ -680,6 +703,9 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
                }
        }
 
+       /* readahead xattr node block */
+       fsck_reada_node_block(sbi, le32_to_cpu(node_blk->i.i_xattr_nid));
+
        if (fsck_chk_xattr_blk(sbi, nid,
                        le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt) &&
                        c.fix_on) {
@@ -736,19 +762,6 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
                goto check;
        }
 
-       /* readahead node blocks */
-       for (idx = 0; idx < 5; idx++) {
-               u32 nid = le32_to_cpu(node_blk->i.i_nid[idx]);
-
-               if (nid != 0 && IS_VALID_NID(sbi, nid)) {
-                       struct node_info ni;
-
-                       get_node_info(sbi, nid, &ni);
-                       if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr))
-                               dev_reada_block(ni.blk_addr);
-               }
-       }
-
        /* init extent info */
        get_extent_info(&child.ei, &node_blk->i.i_ext);
        child.last_blk = 0;
@@ -778,6 +791,12 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
                }
        }
 
+       /* readahead node blocks */
+       for (idx = 0; idx < 5; idx++) {
+               u32 nid = le32_to_cpu(node_blk->i.i_nid[idx]);
+               fsck_reada_node_block(sbi, nid);
+       }
+
        /* check node blocks in inode */
        for (idx = 0; idx < 5; idx++) {
                nid_t i_nid = le32_to_cpu(node_blk->i.i_nid[idx]);
@@ -997,6 +1016,8 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
        int need_fix = 0, ret;
        int i = 0;
 
+       fsck_reada_all_direct_node_blocks(sbi, node_blk);
+
        for (i = 0; i < NIDS_PER_BLOCK; i++) {
                if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
                        goto skip;
@@ -1037,6 +1058,8 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
        int i = 0;
        int need_fix = 0, ret = 0;
 
+       fsck_reada_all_direct_node_blocks(sbi, node_blk);
+
        for (i = 0; i < NIDS_PER_BLOCK; i++) {
                if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
                        goto skip;