summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorYunlei He <heyunlei@huawei.com>2017-03-02 10:36:20 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2017-03-21 22:34:23 -0400
commit3d6a650febdd762c90fe477aa53b9413fd7d97df (patch)
tree0ecbe28982f52c008e4adb9e4612f6c422e7171d /fs/f2fs/segment.c
parentc81abe34fe1ec5e60e5cba6adc912d30e44cc40d (diff)
downloadop-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.c22
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);
OpenPOWER on IntegriCloud