f2fs: add to account direct IO
Chao Yu
maintainerPATCH v2 1/1 f2fs: add to account direct IO
From: Chao Yu <[email protected]>
This patch adds f2fs_dio_submit_bio() to hook submit_io/end_io functions in direct IO path, in order to account DIO.
Later, we will add this count into is_idle() to let background GC/Discard thread be aware of DIO.
Signed-off-by Chao Yu <[email protected]>
---
v2:
- access bio->bi_status instead of dead bio->bi_error.
fs/f2fs/data.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- fs/f2fs/debug.c | 4 ++++ fs/f2fs/f2fs.h | 10 ++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-)
fs/f2fs/data.c +50 -1
@@ -2604,6 +2604,53 @@ static int check_direct_IO(struct inode *inode, struct iov_iter *iter,return 0 ; } +static void f2fs_dio_end_io (struct bio *bio) +{ +struct f2fs_private_dio *dio = bio->bi_private; + +dec_page_count (F2FS_I_SB (dio->inode), + dio->write ?F2FS_DIO_WRITE :F2FS_DIO_READ ); + + bio->bi_private = dio->orig_private; + bio->bi_end_io = dio->orig_end_io; + +kfree (dio); + +bio_endio (bio); +} + +static void f2fs_dio_submit_bio (struct bio *bio,struct inode *inode, +loff_t file_offset) +{ +struct f2fs_private_dio *dio; +bool write = (bio_op (bio) ==REQ_OP_WRITE ); +int err; + + dio =f2fs_kzalloc (F2FS_I_SB (inode), +sizeof (struct f2fs_private_dio ),GFP_NOFS ); +if (!dio) { + err = -ENOMEM ; + goto out; + } + + dio->inode = inode; + dio->orig_end_io = bio->bi_end_io; + dio->orig_private = bio->bi_private; + dio->write = write; + + bio->bi_end_io = f2fs_dio_end_io; + bio->bi_private = dio; + +inc_page_count (F2FS_I_SB (inode), + write ?F2FS_DIO_WRITE :F2FS_DIO_READ ); + +submit_bio (bio); +return ; +out: + bio->bi_status =BLK_STS_IOERR ; +bio_endio (bio); +} +static ssize_t f2fs_direct_IO (struct kiocb *iocb,struct iov_iter *iter) {struct address_space *mapping = iocb->ki_filp->f_mapping;
@@ -2650,7 +2697,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)down_read (&fi->i_gc_rwsem[READ ]); } - err =blockdev_direct_IO (iocb, inode, iter, get_data_block_dio); + err =__blockdev_direct_IO (iocb, inode, inode->i_sb->s_bdev, + iter, get_data_block_dio,NULL , f2fs_dio_submit_bio, +DIO_LOCKING |DIO_SKIP_HOLES );if (do_opu)up_read (&fi->i_gc_rwsem[READ ]);
fs/f2fs/debug.c +4 -0
@@ -53,6 +53,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->vw_cnt =atomic_read (&sbi->vw_cnt); si->max_aw_cnt =atomic_read (&sbi->max_aw_cnt); si->max_vw_cnt =atomic_read (&sbi->max_vw_cnt); + si->nr_dio_read =get_pages (sbi,F2FS_DIO_READ ); + si->nr_dio_write =get_pages (sbi,F2FS_DIO_WRITE ); si->nr_wb_cp_data =get_pages (sbi,F2FS_WB_CP_DATA ); si->nr_wb_data =get_pages (sbi,F2FS_WB_DATA ); si->nr_rd_data =get_pages (sbi,F2FS_RD_DATA );
@@ -374,6 +376,8 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); +seq_printf (s," - DIO (R: %4d, W: %4d)\n" , + si->nr_dio_read, si->nr_dio_write);seq_printf (s," - IO_R (Data: %4d, Node: %4d, Meta: %4d\n" , si->nr_rd_data, si->nr_rd_node, si->nr_rd_meta); seq_printf(s, " - IO_W (CP: %4d, Data: %4d, Flush: (%4d %4d %4d), "
fs/f2fs/f2fs.h +10 -0
@@ -951,6 +951,8 @@ enum count_type {F2FS_RD_DATA ,F2FS_RD_NODE ,F2FS_RD_META , +F2FS_DIO_WRITE , +F2FS_DIO_READ , NR_COUNT_TYPE, };
@@ -1340,6 +1342,13 @@ struct f2fs_sb_info {__u32 s_chksum_seed; }; +struct f2fs_private_dio { +struct inode *inode; +void *orig_private; +bio_end_io_t *orig_end_io; +bool write; +}; +#ifdef CONFIG_F2FS_FAULT_INJECTION #define f2fs_show_injection_info (type) \ printk_ratelimited("%sF2FS-fs : inject %s in %s of %pF\n", \
@@ -3163,6 +3172,7 @@ struct f2fs_stat_info {int total_count, utilization;int bg_gc, nr_wb_cp_data, nr_wb_data;int nr_rd_data, nr_rd_node, nr_rd_meta; +int nr_dio_read, nr_dio_write;unsigned int io_skip_bggc, other_skip_bggc;int nr_flushing, nr_flushed, flush_list_empty;int nr_discarding, nr_discarded;
Signature · 1 line
2.18.0