diff options
author | Daeho Jeong <daehojeong@google.com> | 2021-06-15 11:44:49 -0700 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2021-06-23 09:02:46 -0700 |
commit | 76d2a9199f447d3f9c0fa7e09a7f9ae19e86bb74 (patch) | |
tree | 2a26c84e2db3d9f0ffc18fea093afed99fe968a9 | |
parent | 8d464ee16fe369d1ad2f514a68a30e57ec80d765 (diff) | |
download | f2fs-tools-76d2a9199f447d3f9c0fa7e09a7f9ae19e86bb74.tar.gz |
f2fs-tools: add extent cache for each file
This patch adds an extent cache for ro partition.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/f2fs.h | 8 | ||||
-rw-r--r-- | fsck/mount.c | 8 | ||||
-rw-r--r-- | fsck/segment.c | 105 |
3 files changed, 113 insertions, 8 deletions
diff --git a/fsck/f2fs.h b/fsck/f2fs.h index 9c6b0e4..7fb328f 100644 --- a/fsck/f2fs.h +++ b/fsck/f2fs.h @@ -527,6 +527,14 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) return 1; } +static inline bool is_valid_data_blkaddr(block_t blkaddr) +{ + if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR || + blkaddr == COMPRESS_ADDR) + return 0; + return 1; +} + static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno) { int i; diff --git a/fsck/mount.c b/fsck/mount.c index 598410e..1f2d7e0 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -582,14 +582,6 @@ void print_sb_state(struct f2fs_super_block *sb) MSG(0, "\n"); } -static inline bool is_valid_data_blkaddr(block_t blkaddr) -{ - if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR || - blkaddr == COMPRESS_ADDR) - return 0; - return 1; -} - bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) { diff --git a/fsck/segment.c b/fsck/segment.c index 0156690..fe63615 100644 --- a/fsck/segment.c +++ b/fsck/segment.c @@ -450,6 +450,109 @@ u64 f2fs_fix_mutable(struct f2fs_sb_info *sbi, nid_t ino, pgoff_t offset, return 0; } +static inline int is_consecutive(u32 prev_addr, u32 cur_addr) +{ + if (is_valid_data_blkaddr(cur_addr) && (cur_addr == prev_addr + 1)) + return 1; + return 0; +} + +static inline void copy_extent_info(struct extent_info *t_ext, + struct extent_info *s_ext) +{ + t_ext->fofs = s_ext->fofs; + t_ext->blk = s_ext->blk; + t_ext->len = s_ext->len; +} + +static inline void update_extent_info(struct f2fs_node *inode, + struct extent_info *ext) +{ + inode->i.i_ext.fofs = cpu_to_le32(ext->fofs); + inode->i.i_ext.blk_addr = cpu_to_le32(ext->blk); + inode->i.i_ext.len = cpu_to_le32(ext->len); +} + +static void update_largest_extent(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct dnode_of_data dn; + struct node_info ni; + struct f2fs_node *inode; + u32 blkaddr, prev_blkaddr, cur_blk = 0, end_blk; + struct extent_info largest_ext, cur_ext; + u64 remained_blkentries = 0; + u32 cluster_size; + int count; + void *index_node = NULL; + + memset(&dn, 0, sizeof(dn)); + largest_ext.len = cur_ext.len = 0; + + inode = (struct f2fs_node *) calloc(BLOCK_SZ, 1); + ASSERT(inode); + + /* Read inode info */ + get_node_info(sbi, ino, &ni); + ASSERT(dev_read_block(inode, ni.blk_addr) >= 0); + cluster_size = 1 << inode->i.i_log_cluster_size; + + if (inode->i.i_inline & F2FS_INLINE_DATA) + goto exit; + + end_blk = f2fs_max_file_offset(&inode->i) >> F2FS_BLKSIZE_BITS; + + while (cur_blk <= end_blk) { + if (remained_blkentries == 0) { + set_new_dnode(&dn, inode, NULL, ino); + get_dnode_of_data(sbi, &dn, cur_blk, LOOKUP_NODE); + if (index_node) + free(index_node); + index_node = (dn.node_blk == dn.inode_blk) ? + NULL : dn.node_blk; + remained_blkentries = ADDRS_PER_PAGE(sbi, + dn.node_blk, dn.inode_blk); + } + ASSERT(remained_blkentries > 0); + + blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node); + if (cur_ext.len > 0) { + if (is_consecutive(prev_blkaddr, blkaddr)) + cur_ext.len++; + else { + if (cur_ext.len > largest_ext.len) + copy_extent_info(&largest_ext, + &cur_ext); + cur_ext.len = 0; + } + } + + if (cur_ext.len == 0 && is_valid_data_blkaddr(blkaddr)) { + cur_ext.fofs = cur_blk; + cur_ext.len = 1; + cur_ext.blk = blkaddr; + } + + prev_blkaddr = blkaddr; + count = blkaddr == COMPRESS_ADDR ? cluster_size : 1; + cur_blk += count; + dn.ofs_in_node += count; + remained_blkentries -= count; + ASSERT(remained_blkentries >= 0); + } + +exit: + if (cur_ext.len > largest_ext.len) + copy_extent_info(&largest_ext, &cur_ext); + if (largest_ext.len > 0) { + update_extent_info(inode, &largest_ext); + ASSERT(write_inode(inode, ni.blk_addr) >= 0); + } + + if (index_node) + free(index_node); + free(inode); +} + int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de) { int fd, n; @@ -595,6 +698,8 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de) if (n < 0) return -1; + if (!c.compress.enabled || (c.feature & cpu_to_le32(F2FS_FEATURE_RO))) + update_largest_extent(sbi, de->ino); update_free_segments(sbi); MSG(1, "Info: Create %s -> %s\n" |