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>
Sat, 27 Jan 2018 21:30:18 +0000 (13:30 -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 742f4ae40d067398d4c0cb54f7e3cd5bb2361cae..f3911c19b8025ab6822815d41cc2755d0fbfb323 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 2e1d53fe3d88e75916f2f0f6deebd6dcf40c93ae..976ae163bfaefed985b180016eb80b982b155d0e 100644 (file)
@@ -2070,10 +2070,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;
@@ -2107,6 +2107,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
@@ -2120,7 +2121,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;
                }
 
@@ -2165,7 +2166,7 @@ do_map:
                        goto clear_out;
 
                if (!(map.m_flags & F2FS_MAP_FLAGS)) {
-                       map.m_lblk++;
+                       map.m_lblk = next_pgofs;
                        continue;
                }