f2fs: speed up defragment on sparse file
authorChao Yu <yuchao0@huawei.com>
Wed, 10 Jan 2018 10:18:52 +0000 (18:18 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 22 Jan 2018 22:56:46 +0000 (14:56 -0800)
We have supported to get next page offset with valid mapping crossing
hole in f2fs_map_blocks, utilizing it to speed up defragment on sparse
file.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/file.c

index 28a3328..81fd482 100644 (file)
@@ -1017,8 +1017,12 @@ next_block:
                                        *map->m_next_pgofs = pgofs + 1;
                                goto sync_out;
                        }
-                       if (flag != F2FS_GET_BLOCK_FIEMAP)
+                       if (flag != F2FS_GET_BLOCK_FIEMAP) {
+                               /* for defragment case */
+                               if (map->m_next_pgofs)
+                                       *map->m_next_pgofs = pgofs + 1;
                                goto sync_out;
+                       }
                }
        }
 
index 58c9e3d..9553f80 100644 (file)
@@ -2071,10 +2071,10 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
                                        struct f2fs_defragment *range)
 {
        struct inode *inode = file_inode(filp);
-       struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
-                       .m_next_extent = NULL, .m_seg_type = NO_CHECK_TYPE };
+       struct f2fs_map_blocks map = { .m_next_extent = NULL,
+                                       .m_seg_type = NO_CHECK_TYPE };
        struct extent_info ei = {0,0,0};
-       pgoff_t pg_start, pg_end;
+       pgoff_t pg_start, pg_end, next_pgofs;
        unsigned int blk_per_seg = sbi->blocks_per_seg;
        unsigned int total = 0, sec_num;
        block_t blk_end = 0;
@@ -2108,6 +2108,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
        }
 
        map.m_lblk = pg_start;
+       map.m_next_pgofs = &next_pgofs;
 
        /*
         * lookup mapping info in dnode page cache, skip defragmenting if all
@@ -2121,7 +2122,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
                        goto out;
 
                if (!(map.m_flags & F2FS_MAP_FLAGS)) {
-                       map.m_lblk++;
+                       map.m_lblk = next_pgofs;
                        continue;
                }
 
@@ -2166,7 +2167,7 @@ do_map:
                        goto clear_out;
 
                if (!(map.m_flags & F2FS_MAP_FLAGS)) {
-                       map.m_lblk++;
+                       map.m_lblk = next_pgofs;
                        continue;
                }