summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYunlei He2017-03-02 03:36:20 +0100
committerJaegeuk Kim2017-03-22 03:34:23 +0100
commit3d6a650febdd762c90fe477aa53b9413fd7d97df (patch)
tree0ecbe28982f52c008e4adb9e4612f6c422e7171d /fs
parentf2fs: allocate a bio for discarding when actually issuing it (diff)
downloadkernel-qcow2-linux-3d6a650febdd762c90fe477aa53b9413fd7d97df.tar.gz
kernel-qcow2-linux-3d6a650febdd762c90fe477aa53b9413fd7d97df.tar.xz
kernel-qcow2-linux-3d6a650febdd762c90fe477aa53b9413fd7d97df.zip
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')
-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 85c34d4fcf3e..c5a5258f71c5 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);