Browse Source

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>
Yunlei He 8 years ago
parent
commit
3d6a650feb
1 changed files with 20 additions and 2 deletions
  1. 20 2
      fs/f2fs/segment.c

+ 20 - 2
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);