ADDRS_PER_INODE and ADDRS_PER_BLOCK are macros of a function, and if the
compiler does not optimize the code (-O0 for example), they would be
called in every single loop, which could cause significant performance
drops in some cases.

This scenario has been found before, refer to:
Commit: 1bb669e ("fsck.f2fs: avoid unnecessary recalculation")

To avoid this performance drop as much as possible, I changed the
function to 'inline' definition, which could mitigate such cases in
the future.

Signed-off-by: Wu Bo <[email protected]>
---
v2: Only modify when the macro's return value is fixed in 'for' loops.
---
 fsck/dump.c       |  5 +++--
 fsck/fsck.c       | 12 ++++++++----
 fsck/mount.c      |  4 +++-
 include/f2fs_fs.h | 12 +++++++++++-
 lib/libf2fs.c     | 11 -----------
 5 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index f5c95de..a5f344b 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -495,7 +495,7 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 {
        u32 i = 0;
        u64 ofs = 0;
-       u32 addr_per_block;
+       u32 addr_per_block, addr_per_inode;
        u16 type = le16_to_cpu(node_blk->i.i_mode);
        int ret = 0;
 
@@ -543,9 +543,10 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 
nid,
        }
 
        addr_per_block = ADDRS_PER_BLOCK(&node_blk->i);
+       addr_per_inode = ADDRS_PER_INODE(&node_blk->i);
 
        /* check data blocks in inode */
-       for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
+       for (i = 0; i < addr_per_inode; i++, ofs++)
                dump_data_blk(sbi, ofs * F2FS_BLKSIZE, le32_to_cpu(
                        node_blk->i.i_addr[get_extra_isize(node_blk) + i]), 
type);
 
diff --git a/fsck/fsck.c b/fsck/fsck.c
index db44f9d..1230d7b 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1516,8 +1516,9 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
        bool compressed = i_flags & F2FS_COMPR_FL;
        bool compr_rel = inode->i_inline & F2FS_COMPRESS_RELEASED;
        u32 cluster_size = 1 << inode->i_log_cluster_size;
+       u32 addrs = ADDRS_PER_BLOCK(inode);
 
-       for (idx = 0; idx < ADDRS_PER_BLOCK(inode); idx++, child->pgofs++) {
+       for (idx = 0; idx < addrs; idx++, child->pgofs++) {
                block_t blkaddr = le32_to_cpu(node_blk->dn.addr[idx]);
 
                check_extent_info(child, blkaddr, 0);
@@ -3173,7 +3174,7 @@ static void fsck_disconnect_file_dnode(struct 
f2fs_sb_info *sbi,
 {
        struct f2fs_node *node;
        struct node_info ni;
-       u32 addr;
+       u32 addr, addr_per_block;
        int i, err;
 
        node = calloc(F2FS_BLKSIZE, 1);
@@ -3187,7 +3188,8 @@ static void fsck_disconnect_file_dnode(struct 
f2fs_sb_info *sbi,
        release_block_cnt(sbi, dealloc);
        release_block(sbi, ni.blk_addr, dealloc);
 
-       for (i = 0; i < ADDRS_PER_BLOCK(inode); i++) {
+       addr_per_block = ADDRS_PER_BLOCK(inode);
+       for (i = 0; i < addr_per_block; i++) {
                addr = le32_to_cpu(node->dn.addr[i]);
                if (!addr)
                        continue;
@@ -3302,8 +3304,10 @@ static void fsck_disconnect_file(struct f2fs_sb_info 
*sbi, nid_t ino,
 
        /* clear data counters */
        if (!(node->i.i_inline & (F2FS_INLINE_DATA | F2FS_INLINE_DENTRY))) {
+               u32 addrs = ADDRS_PER_INODE(&node->i);
+
                ofs = get_extra_isize(node);
-               for (i = 0; i < ADDRS_PER_INODE(&node->i); i++) {
+               for (i = 0; i < addrs; i++) {
                        block_t addr = le32_to_cpu(node->i.i_addr[ofs + i]);
                        if (!addr)
                                continue;
diff --git a/fsck/mount.c b/fsck/mount.c
index 6f640a0..990f1e0 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -281,6 +281,7 @@ void print_inode_info(struct f2fs_sb_info *sbi,
        u32 namelen = le32_to_cpu(inode->i_namelen);
        int enc_name = file_enc_name(inode);
        int ofs = get_extra_isize(node);
+       u32 addrs;
 
        pretty_print_filename(inode->i_name, namelen, en, enc_name);
        if (name && en[0]) {
@@ -350,7 +351,8 @@ void print_inode_info(struct f2fs_sb_info *sbi,
                }
        }
 
-       for (i = 0; i < ADDRS_PER_INODE(inode); i++) {
+       addrs = ADDRS_PER_INODE(inode);
+       for (i = 0; i < addrs; i++) {
                block_t blkaddr;
                char *flag = "";
 
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 3095b59..d0877b9 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1660,7 +1660,6 @@ struct f2fs_configuration {
 extern int utf8_to_utf16(char *, const char *, size_t, size_t);
 extern int utf16_to_utf8(char *, const char *, size_t, size_t);
 extern int log_base_2(uint32_t);
-extern unsigned int addrs_per_page(struct f2fs_inode *, bool);
 extern u64 f2fs_max_file_offset(struct f2fs_inode *);
 extern __u32 f2fs_inode_chksum(struct f2fs_node *);
 extern __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *);
@@ -2212,4 +2211,15 @@ static inline bool __time_to_inject(int type, const char 
*func,
        return false;
 }
 
+static inline unsigned int addrs_per_page(struct f2fs_inode *i, bool is_inode)
+{
+       unsigned int addrs = is_inode ? CUR_ADDRS_PER_INODE(i) -
+               get_inline_xattr_addrs(i) : DEF_ADDRS_PER_BLOCK;
+
+       if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
+                       !(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
+               return addrs;
+       return ALIGN_DOWN(addrs, 1 << i->i_log_cluster_size);
+}
+
 #endif /*__F2FS_FS_H */
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 1a496b7..13e4d0d 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -516,17 +516,6 @@ opaque_seq:
        return __f2fs_dentry_hash(name, len);
 }
 
-unsigned int addrs_per_page(struct f2fs_inode *i, bool is_inode)
-{
-       unsigned int addrs = is_inode ? CUR_ADDRS_PER_INODE(i) -
-               get_inline_xattr_addrs(i) : DEF_ADDRS_PER_BLOCK;
-
-       if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
-                       !(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
-               return addrs;
-       return ALIGN_DOWN(addrs, 1 << i->i_log_cluster_size);
-}
-
 u64 f2fs_max_file_offset(struct f2fs_inode *i)
 {
        if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
-- 
2.47.3



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to