aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaeho Jeong <daehojeong@google.com>2021-06-15 11:44:49 -0700
committerJaegeuk Kim <jaegeuk@kernel.org>2021-06-23 09:02:46 -0700
commit76d2a9199f447d3f9c0fa7e09a7f9ae19e86bb74 (patch)
tree2a26c84e2db3d9f0ffc18fea093afed99fe968a9
parent8d464ee16fe369d1ad2f514a68a30e57ec80d765 (diff)
downloadf2fs-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.h8
-rw-r--r--fsck/mount.c8
-rw-r--r--fsck/segment.c105
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"