summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2018-01-10 18:18:51 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2018-02-07 18:05:52 -0800
commitb203c58dfd5538d1a7f99737db6d3653b7601c82 (patch)
treedfc8e944c957e965d5554d7f58154281614ef779 /fs
parentd49132d45cb07dc77904bf9b6501df2dd77b251b (diff)
f2fs: fix to caclulate required free section correctly
When calculating required free section during file defragmenting, we should skip holes in file, otherwise we will probably fail to defrag sparse file with large size. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/file.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index de0a167c8238..56f6b21cd9a9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2101,10 +2101,12 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
continue;
}
- if (blk_end && blk_end != map.m_pblk) {
+ if (blk_end && blk_end != map.m_pblk)
fragmented = true;
- break;
- }
+
+ /* record total count of block that we're going to move */
+ total += map.m_len;
+
blk_end = map.m_pblk + map.m_len;
map.m_lblk += map.m_len;
@@ -2113,10 +2115,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
if (!fragmented)
goto out;
- map.m_lblk = pg_start;
- map.m_len = pg_end - pg_start;
-
- sec_num = (map.m_len + BLKS_PER_SEC(sbi) - 1) / BLKS_PER_SEC(sbi);
+ sec_num = (total + BLKS_PER_SEC(sbi) - 1) / BLKS_PER_SEC(sbi);
/*
* make sure there are enough free section for LFS allocation, this can
@@ -2128,6 +2127,10 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
goto out;
}
+ map.m_lblk = pg_start;
+ map.m_len = pg_end - pg_start;
+ total = 0;
+
while (map.m_lblk < pg_end) {
pgoff_t idx;
int cnt = 0;