diff mbox series

[3/3] f2fs: improve discard handling with multi-device volumes

Message ID 20190316001308.18115-4-damien.lemoal@wdc.com (mailing list archive)
State New, archived
Headers show
Series f2fs: bug fix and improvement | expand

Commit Message

Damien Le Moal March 16, 2019, 12:13 a.m. UTC
f2fs_hw_support_discard() only tests if the super block device supports
discard. However, for a multi-device volume, not all disks used may
support discard. Improve the check performed to test all devices of
the volume and report discard as supported if at least one device of
the volume supports discard. To implement this, introduce the helper
function f2fs_bdev_support_discard(), which returns true for zoned block
devices (where discard is processed as a zone reset) and for regular
disks supporting the discard command.

f2fs_bdev_support_discard() is also used in __queue_discard_cmd() to
handle discard command issuing for a particular device of the volume.
That is, prevent issuing a discard command for block devices that do
not support it.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 fs/f2fs/f2fs.h    | 16 +++++++++++++++-
 fs/f2fs/segment.c |  8 ++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

Comments

Chao Yu March 19, 2019, 11:02 a.m. UTC | #1
On 2019/3/16 8:13, Damien Le Moal wrote:
> f2fs_hw_support_discard() only tests if the super block device supports
> discard. However, for a multi-device volume, not all disks used may
> support discard. Improve the check performed to test all devices of
> the volume and report discard as supported if at least one device of
> the volume supports discard. To implement this, introduce the helper
> function f2fs_bdev_support_discard(), which returns true for zoned block
> devices (where discard is processed as a zone reset) and for regular
> disks supporting the discard command.
> 
> f2fs_bdev_support_discard() is also used in __queue_discard_cmd() to
> handle discard command issuing for a particular device of the volume.
> That is, prevent issuing a discard command for block devices that do
> not support it.
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>

Reviewed-by: Chao Yu <yuchao0@huawei.com>

Thanks,
diff mbox series

Patch

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 576e637ef568..db4564c6531d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3527,9 +3527,23 @@  static inline bool f2fs_hw_should_discard(struct f2fs_sb_info *sbi)
 	return f2fs_sb_has_blkzoned(sbi);
 }
 
+static inline bool f2fs_bdev_support_discard(struct block_device *bdev)
+{
+	return blk_queue_discard(bdev_get_queue(bdev)) ||
+	       bdev_is_zoned(bdev);
+}
+
 static inline bool f2fs_hw_support_discard(struct f2fs_sb_info *sbi)
 {
-	return blk_queue_discard(bdev_get_queue(sbi->sb->s_bdev));
+	int i;
+
+	if (!f2fs_is_multi_device(sbi))
+		return f2fs_bdev_support_discard(sbi->sb->s_bdev);
+
+	for (i = 0; i < sbi->s_ndevs; i++)
+		if (f2fs_bdev_support_discard(FDEV(i).bdev))
+			return true;
+	return false;
 }
 
 static inline bool f2fs_realtime_discard_enable(struct f2fs_sb_info *sbi)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f40148b735d7..9b320dd1c9d7 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1342,6 +1342,9 @@  static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
 {
 	block_t lblkstart = blkstart;
 
+	if (!f2fs_bdev_support_discard(bdev))
+		return 0;
+
 	trace_f2fs_queue_discard(bdev, blkstart, blklen);
 
 	if (f2fs_is_multi_device(sbi)) {
@@ -1728,8 +1731,6 @@  static int __f2fs_issue_discard_zone(struct f2fs_sb_info *sbi,
 	}
 
 	/* For conventional zones, use regular discard if supported */
-	if (!blk_queue_discard(bdev_get_queue(bdev)))
-		return 0;
 	return __queue_discard_cmd(sbi, bdev, lblkstart, blklen);
 }
 #endif
@@ -1738,8 +1739,7 @@  static int __issue_discard_async(struct f2fs_sb_info *sbi,
 		struct block_device *bdev, block_t blkstart, block_t blklen)
 {
 #ifdef CONFIG_BLK_DEV_ZONED
-	if (f2fs_sb_has_blkzoned(sbi) &&
-				bdev_zoned_model(bdev) != BLK_ZONED_NONE)
+	if (f2fs_sb_has_blkzoned(sbi) && bdev_is_zoned(bdev))
 		return __f2fs_issue_discard_zone(sbi, bdev, blkstart, blklen);
 #endif
 	return __queue_discard_cmd(sbi, bdev, blkstart, blklen);