diff options
author | Yunlei He <heyunlei@huawei.com> | 2017-03-02 10:36:20 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2017-03-21 22:34:23 -0400 |
commit | 3d6a650febdd762c90fe477aa53b9413fd7d97df (patch) | |
tree | 0ecbe28982f52c008e4adb9e4612f6c422e7171d /fs/f2fs/segment.c | |
parent | c81abe34fe1ec5e60e5cba6adc912d30e44cc40d (diff) | |
download | op-kernel-dev-3d6a650febdd762c90fe477aa53b9413fd7d97df.zip op-kernel-dev-3d6a650febdd762c90fe477aa53b9413fd7d97df.tar.gz |
f2fs: add a punch discard command function
This patch add a function to punch discard command if one segment
reuse before discard. Split this segment from multi-segments discard
range, and discard the left bigger range.
Signed-off-by: Yunlei He <heyunlei@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r-- | fs/f2fs/segment.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 85c34d4..c5a5258 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -759,6 +759,25 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, return 0; } +static void __punch_discard_cmd(struct f2fs_sb_info *sbi, + struct discard_cmd *dc, block_t blkaddr) +{ + block_t end_block = START_BLOCK(sbi, GET_SEGNO(sbi, blkaddr) + 1); + + if (dc->state == D_DONE || dc->lstart + dc->len <= end_block) { + __remove_discard_cmd(sbi, dc); + return; + } + + if (blkaddr - dc->lstart < dc->lstart + dc->len - end_block) { + dc->start += (end_block - dc->lstart); + dc->len -= (end_block - dc->lstart); + dc->lstart = end_block; + } else { + dc->len = blkaddr - dc->lstart; + } +} + /* This should be covered by global mutex, &sit_i->sentry_lock */ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) { @@ -781,8 +800,7 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) if (dc->lstart <= blkaddr && blkaddr < dc->lstart + dc->len) { if (dc->state == D_SUBMIT) wait_for_completion_io(&dc->wait); - else - __remove_discard_cmd(sbi, dc); + __punch_discard_cmd(sbi, dc, blkaddr); } } blk_finish_plug(&plug); |