On 2018/6/18 8:39, Jaegeuk Kim wrote:
> This patch adds to check nat_bits is valid or not. If not, it writes correct
> nat_bits.
> 
> Signed-off-by: Jaegeuk Kim <jaeg...@kernel.org>
> ---
>  fsck/mount.c | 95 ++++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 74 insertions(+), 21 deletions(-)
> 
> diff --git a/fsck/mount.c b/fsck/mount.c
> index a481a1e..f830e9b 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -1044,6 +1044,78 @@ void write_nat_bits(struct f2fs_sb_info *sbi,
>       free(nat_bits);
>  }
>  
> +static int check_nat_bits(struct f2fs_sb_info *sbi,
> +     struct f2fs_super_block *sb, struct f2fs_checkpoint *cp)
> +{
> +     struct f2fs_nm_info *nm_i = NM_I(sbi);
> +     u_int32_t nat_blocks = get_sb(segment_count_nat) <<
> +                             (get_sb(log_blocks_per_seg) - 1);
> +     u_int32_t nat_bits_bytes = nat_blocks >> 3;
> +     u_int32_t nat_bits_blocks = F2FS_BYTES_TO_BLK((nat_bits_bytes << 1) +
> +                                     8 + F2FS_BLKSIZE - 1);
> +     unsigned char *nat_bits, *full_nat_bits, *empty_nat_bits;
> +     u_int32_t i, j;
> +     block_t blkaddr;
> +     int err = 0;
> +
> +     nat_bits = calloc(F2FS_BLKSIZE, nat_bits_blocks);
> +     ASSERT(nat_bits);
> +
> +     full_nat_bits = nat_bits + 8;
> +     empty_nat_bits = full_nat_bits + nat_bits_bytes;
> +
> +     blkaddr = get_sb(segment0_blkaddr) + (sbi->cur_cp <<
> +                             get_sb(log_blocks_per_seg)) - nat_bits_blocks;
> +
> +     for (i = 0; i < nat_bits_blocks; i++) {
> +             if (dev_read_block(nat_bits + i * F2FS_BLKSIZE, blkaddr + i))
> +                     ASSERT_MSG("\tError: read NAT bits to disk!!!\n");
> +     }
> +
> +     if (*(__le64 *)nat_bits != get_cp_crc(cp)) {
> +             err = -1;
> +             goto out;
> +     }
> +
> +     for (i = 0; i < nat_blocks; i++) {
> +             u_int32_t start_nid = i * NAT_ENTRY_PER_BLOCK;
> +             u_int32_t valid = 0;
> +
> +             for (j = 0; j < NAT_ENTRY_PER_BLOCK; j++) {
> +                     if (f2fs_test_bit(start_nid + j, nm_i->nid_bitmap))
> +                             valid++;
> +             }
> +             if (valid == 0) {
> +                     if (!test_bit_le(i, empty_nat_bits) ||
> +                                     test_bit_le(i, full_nat_bits)) {
> +                             err = -1;
> +                             goto out;
> +                     }
> +             } else if (valid == NAT_ENTRY_PER_BLOCK) {
> +                     if (test_bit_le(i, empty_nat_bits) ||
> +                                     !test_bit_le(i, full_nat_bits)) {
> +                             err = -1;
> +                             goto out;
> +                     }
> +             } else {
> +                     if (test_bit_le(i, empty_nat_bits) ||
> +                                     test_bit_le(i, full_nat_bits)) {
> +                             err = -1;
> +                             goto out;
> +                     }
> +             }

Can clean up by replacing test_bit_le(i, ...) with added empty/full variables?

empty = test_bit_le(i, empty_nat_bits);
full = test_bit_le(i, full_nat_bits);

Anyway, it looks good to me.

Reviewed-by: Chao Yu <yuch...@huawei.com>

Thanks,

> +     }
> +out:
> +     free(nat_bits);
> +     if (!err) {
> +             MSG(0, "Info: Checked valid nat_bits in checkpoint\n");
> +     } else {
> +             c.bug_on = 1;
> +             MSG(0, "Info: Corrupted valid nat_bits in checkpoint\n");
> +     }
> +     return err;
> +}
> +
>  int init_node_manager(struct f2fs_sb_info *sbi)
>  {
>       struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
> @@ -2394,28 +2466,9 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
>       }
>  
>       /* Check nat_bits */
> -     if (c.func != DUMP && is_set_ckpt_flags(cp, CP_NAT_BITS_FLAG)) {
> -             u_int32_t nat_bits_bytes, nat_bits_blocks;
> -             __le64 *kaddr;
> -             u_int32_t blk;
> -
> -             blk = get_sb(cp_blkaddr) + (1 << get_sb(log_blocks_per_seg));
> -             if (sbi->cur_cp == 2)
> -                     blk += 1 << get_sb(log_blocks_per_seg);
> -
> -             nat_bits_bytes = get_sb(segment_count_nat) << 5;
> -             nat_bits_blocks = F2FS_BYTES_TO_BLK((nat_bits_bytes << 1) + 8 +
> -                             F2FS_BLKSIZE - 1);
> -             blk -= nat_bits_blocks;
> -
> -             kaddr = malloc(PAGE_SIZE);
> -             ret = dev_read_block(kaddr, blk);
> -             ASSERT(ret >= 0);
> -             if (*kaddr != get_cp_crc(cp))
> +     if (c.func == FSCK && is_set_ckpt_flags(cp, CP_NAT_BITS_FLAG)) {
> +             if (check_nat_bits(sbi, sb, cp) && c.fix_on)
>                       write_nat_bits(sbi, sb, cp, sbi->cur_cp);
> -             else
> -                     MSG(0, "Info: Found valid nat_bits in checkpoint\n");
> -             free(kaddr);
>       }
>       return 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