在 2026/4/29 15:44, Chao Yu 写道:
On 4/23/26 11:42, liujinbao1 wrote:
From: liujinbao1 <[email protected]>

F2FS did not collect iostat statistics for direct IO reads and writes,
hook submit_io to bind an iostat context and record the submission
timestamp, replace bi_end_io to collect IO latency on completion and
then call back to the original iomap_dio_bio_end_io(), to add iostat
tracking support for F2FS DIO.

Not sure, do we need to distinguish the latency of DIO from buffered IO?

We don't need to distinguish DIO latency from buffered IO. The latency is measured from

bio submit to end_io, so there should be little difference between them. I will correct commit.



Signed-off-by: shengyong1 <[email protected]>
Signed-off-by: liujinbao1 <[email protected]>
---
  fs/f2fs/file.c   | 27 +++++++++++++++++++++++++++
  fs/f2fs/iostat.c |  2 +-
  2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 2c4880f24b54..fcf725931fd8 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -4774,6 +4774,16 @@ static bool f2fs_should_use_dio(struct inode *inode, struct kiocb *iocb,
      return true;
  }
  +static void f2fs_dio_end_bio(struct bio *bio)
+{
+    struct bio_iostat_ctx *iostat_ctx = bio->bi_private;
+    void *orig_bi_private = iostat_ctx->post_read_ctx;
+
+    iostat_update_and_unbind_ctx(bio);
+    bio->bi_private = orig_bi_private;
+    iomap_dio_bio_end_io(bio);
+}
+
  static int f2fs_dio_read_end_io(struct kiocb *iocb, ssize_t size, int error,
                  unsigned int flags)
  {
@@ -4786,8 +4796,21 @@ static int f2fs_dio_read_end_io(struct kiocb *iocb, ssize_t size, int error,
      return 0;
  }
  +static void f2fs_dio_read_submit_io(const struct iomap_iter *iter,
+                    struct bio *bio, loff_t file_offset)
+{
+    struct f2fs_sb_info *sbi = F2FS_I_SB(iter->inode);
+    void *bi_private = bio->bi_private;
+
+    iostat_alloc_and_bind_ctx(sbi, bio, bi_private);
+    iostat_update_submit_ctx(bio, DATA);
+    bio->bi_end_io = f2fs_dio_end_bio;
+    blk_crypto_submit_bio(bio);
+}
+
  static const struct iomap_dio_ops f2fs_iomap_dio_read_ops = {
      .end_io = f2fs_dio_read_end_io,
+    .submit_io = f2fs_dio_read_submit_io,
  };
    static ssize_t f2fs_dio_read_iter(struct kiocb *iocb, struct iov_iter *to) @@ -5064,8 +5087,12 @@ static void f2fs_dio_write_submit_io(const struct iomap_iter *iter,
      struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
      enum log_type type = f2fs_rw_hint_to_seg_type(sbi, inode->i_write_hint);
      enum temp_type temp = f2fs_get_segment_temp(sbi, type);
+    void *bi_private = bio->bi_private;
        bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp);
+    iostat_alloc_and_bind_ctx(sbi, bio, bi_private);
+    iostat_update_submit_ctx(bio, DATA);
+    bio->bi_end_io = f2fs_dio_end_bio;
      blk_crypto_submit_bio(bio);

There are duplicated codes in f2fs_dio_write_submit_io() and f2fs_dio_read_submit_io(),
can we introduce a common function to wrap those codes?
OK,thanks

Thanks,

  }
  diff --git a/fs/f2fs/iostat.c b/fs/f2fs/iostat.c
index f8703038e1d8..57d2c3e68a1b 100644
--- a/fs/f2fs/iostat.c
+++ b/fs/f2fs/iostat.c
@@ -218,7 +218,7 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx,
      struct iostat_lat_info *io_lat = sbi->iostat_io_lat;
      unsigned long flags;
  -    if (!sbi->iostat_enable)
+    if (!sbi->iostat_enable || iostat_ctx->submit_ts == 0)
          return;
        ts_diff = jiffies - iostat_ctx->submit_ts;



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to