f2fs-tools: fix stat update in sload/fsck
authorChao Yu <yuchao0@huawei.com>
Mon, 5 Aug 2019 09:44:06 +0000 (17:44 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 27 Aug 2019 21:51:05 +0000 (14:51 -0700)
Change logic as below:
- fix to account block/node/inode stats correctly in reserve_new_block()
- check overflow in reserve_new_block()
- move stat update from f2fs_alloc_nid() to reserve_new_block()
- adjust write_checkpoint() to update stat for sload/fsck

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fsck/dir.c
fsck/fsck.c
fsck/fsck.h
fsck/mount.c
fsck/node.c
fsck/segment.c
fsck/xattr.c

index 0984d26..5f4f75e 100644 (file)
@@ -363,7 +363,7 @@ static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
        test_and_set_bit_le(1, dent_blk->dentry_bitmap);
 
        set_summary(&sum, ino, 0, ni.version);
-       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA);
+       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA, 0);
        ASSERT(!ret);
 
        ret = dev_write_block(dent_blk, blkaddr);
@@ -399,7 +399,7 @@ static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
        memcpy(data_blk, symname, symlen);
 
        set_summary(&sum, ino, 0, ni.version);
-       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA);
+       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA, 1);
        ASSERT(!ret);
 
        ret = dev_write_block(data_blk, blkaddr);
@@ -673,7 +673,7 @@ int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
        child = calloc(BLOCK_SZ, 1);
        ASSERT(child);
 
-       f2fs_alloc_nid(sbi, &de->ino, 1);
+       f2fs_alloc_nid(sbi, &de->ino);
 
        init_inode_block(sbi, child, de);
 
@@ -690,7 +690,7 @@ int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
 
        /* write child */
        set_summary(&sum, de->ino, 0, ni.version);
-       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE);
+       ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
        ASSERT(!ret);
 
        /* update nat info */
index 2afbd2c..2ae3bd5 100644 (file)
@@ -2093,6 +2093,9 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
        int ret;
        u_int32_t crc = 0;
 
+       /* should call from fsck */
+       ASSERT(c.func == FSCK);
+
        if (is_set_ckpt_flags(cp, CP_ORPHAN_PRESENT_FLAG)) {
                orphan_blks = __start_sum_addr(sbi) - 1;
                flags |= CP_ORPHAN_PRESENT_FLAG;
index 45f6517..f7ddf50 100644 (file)
@@ -242,11 +242,11 @@ int f2fs_sload(struct f2fs_sb_info *);
 
 /* segment.c */
 int reserve_new_block(struct f2fs_sb_info *, block_t *,
-                                       struct f2fs_summary *, int);
+                                       struct f2fs_summary *, int, bool);
 int new_data_block(struct f2fs_sb_info *, void *,
                                        struct dnode_of_data *, int);
 int f2fs_build_file(struct f2fs_sb_info *, struct dentry *);
-void f2fs_alloc_nid(struct f2fs_sb_info *, nid_t *, int);
+void f2fs_alloc_nid(struct f2fs_sb_info *, nid_t *);
 void set_data_blkaddr(struct dnode_of_data *);
 block_t new_node_block(struct f2fs_sb_info *,
                                        struct dnode_of_data *, unsigned int);
index 95bbe0f..409d129 100644 (file)
@@ -2673,7 +2673,17 @@ void write_checkpoint(struct f2fs_sb_info *sbi)
        }
 
        set_cp(free_segment_count, get_free_segments(sbi));
-       set_cp(valid_block_count, sbi->total_valid_block_count);
+       if (c.func == FSCK) {
+               struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+               set_cp(valid_block_count, fsck->chk.valid_blk_cnt);
+               set_cp(valid_node_count, fsck->chk.valid_node_cnt);
+               set_cp(valid_inode_count, fsck->chk.valid_inode_cnt);
+       } else {
+               set_cp(valid_block_count, sbi->total_valid_block_count);
+               set_cp(valid_node_count, sbi->total_valid_node_count);
+               set_cp(valid_inode_count, sbi->total_valid_inode_count);
+       }
        set_cp(cp_pack_total_block_count, 8 + orphan_blks + get_sb(cp_payload));
 
        flags = update_nat_bits_flags(sb, cp, flags);
index 882f355..6bb5484 100644 (file)
 #include "fsck.h"
 #include "node.h"
 
-void f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid, int inode)
+void f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
-       struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
-       nid_t i, inode_cnt, node_cnt;
+       nid_t i;
 
        for (i = 0; i < nm_i->max_nid; i++)
                if(f2fs_test_bit(i, nm_i->nid_bitmap) == 0)
@@ -29,12 +28,6 @@ void f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid, int inode)
        ASSERT(i < nm_i->max_nid);
        f2fs_set_bit(i, nm_i->nid_bitmap);
        *nid = i;
-
-       inode_cnt = get_cp(valid_inode_count);
-       node_cnt = get_cp(valid_node_count);
-       if (inode)
-               set_cp(valid_inode_count, inode_cnt + 1);
-       set_cp(valid_node_count, node_cnt + 1);
 }
 
 void set_data_blkaddr(struct dnode_of_data *dn)
@@ -87,7 +80,7 @@ block_t new_node_block(struct f2fs_sb_info *sbi,
 
        get_node_info(sbi, dn->nid, &ni);
        set_summary(&sum, dn->nid, 0, ni.version);
-       ret = reserve_new_block(sbi, &blkaddr, &sum, type);
+       ret = reserve_new_block(sbi, &blkaddr, &sum, type, !ofs);
        if (ret) {
                free(node_blk);
                return 0;
@@ -216,7 +209,7 @@ int get_dnode_of_data(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
                                c.alloc_failed = 1;
                                return -EINVAL;
                        }
-                       f2fs_alloc_nid(sbi, &nids[i], 0);
+                       f2fs_alloc_nid(sbi, &nids[i]);
 
                        dn->nid = nids[i];
 
index 367865a..2d18358 100644 (file)
 #include "node.h"
 
 int reserve_new_block(struct f2fs_sb_info *sbi, block_t *to,
-                       struct f2fs_summary *sum, int type)
+                       struct f2fs_summary *sum, int type, bool is_inode)
 {
        struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
        struct seg_entry *se;
        u64 blkaddr, offset;
        u64 old_blkaddr = *to;
+       bool is_node = IS_NODESEG(type);
 
        if (old_blkaddr == NULL_ADDR) {
                if (c.func == FSCK) {
@@ -30,12 +31,22 @@ int reserve_new_block(struct f2fs_sb_info *sbi, block_t *to,
                                ERR_MSG("Not enough space");
                                return -ENOSPC;
                        }
+                       if (is_node && fsck->chk.valid_node_cnt >=
+                                       sbi->total_valid_node_count) {
+                               ERR_MSG("Not enough space for node block");
+                               return -ENOSPC;
+                       }
                } else {
                        if (sbi->total_valid_block_count >=
                                                sbi->user_block_count) {
                                ERR_MSG("Not enough space");
                                return -ENOSPC;
                        }
+                       if (is_node && sbi->total_valid_node_count >=
+                                               sbi->total_node_count) {
+                               ERR_MSG("Not enough space for node block");
+                               return -ENOSPC;
+                       }
                }
        }
 
@@ -58,10 +69,18 @@ int reserve_new_block(struct f2fs_sb_info *sbi, block_t *to,
 
        if (old_blkaddr == NULL_ADDR) {
                sbi->total_valid_block_count++;
+               if (is_node) {
+                       sbi->total_valid_node_count++;
+                       if (is_inode)
+                               sbi->total_valid_inode_count++;
+               }
                if (c.func == FSCK) {
                        fsck->chk.valid_blk_cnt++;
-                       if (IS_NODESEG(type))
+                       if (is_node) {
                                fsck->chk.valid_node_cnt++;
+                               if (is_inode)
+                                       fsck->chk.valid_inode_cnt++;
+                       }
                }
        }
        se->dirty = 1;
@@ -92,7 +111,7 @@ int new_data_block(struct f2fs_sb_info *sbi, void *block,
 
        get_node_info(sbi, dn->nid, &ni);
        set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
-       ret = reserve_new_block(sbi, &dn->data_blkaddr, &sum, type);
+       ret = reserve_new_block(sbi, &dn->data_blkaddr, &sum, type, 0);
        if (ret) {
                c.alloc_failed = 1;
                return ret;
index 98cbb0c..d51a08a 100644 (file)
@@ -83,7 +83,7 @@ static void write_all_xattrs(struct f2fs_sb_info *sbi,
                return;
 
        if (!xnid) {
-               f2fs_alloc_nid(sbi, &new_nid, 0);
+               f2fs_alloc_nid(sbi, &new_nid);
 
                set_new_dnode(&dn, inode, NULL, new_nid);
                /* NAT entry would be updated by new_node_page. */