summaryrefslogtreecommitdiff
path: root/fs/f2fs
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2018-01-10 13:18:51 +0300
committerJaegeuk Kim <jaegeuk@kernel.org>2018-01-19 09:09:08 +0300
commit25a912e51af7c0761a6d3424640901ded517e201 (patch)
tree93d2e1ed682a596091dcf7709f89d3a65bdbf966 /fs/f2fs
parentf1d2564a7cc9d2f49399094cfe3c46c9d4930b7b (diff)
downloadlinux-25a912e51af7c0761a6d3424640901ded517e201.tar.xz
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/f2fs')
-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 322aab9d91b5..05779077cbf2 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2125,10 +2125,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;
@@ -2137,10 +2139,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
@@ -2152,6 +2151,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;