Re: [f2fs-dev] [PATCH] f2fs: honor per-I/O write streams for direct writes

Jaegeuk Kim via Linux-f2fs-devel <[email protected]>
Newsgroups net.sourceforge.lists.linux-f2fs-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 05/22, Wenjie Qi wrote:
> io_uring can pass a per-I/O write stream through kiocb->ki_write_stream,
> and block direct I/O propagates that value to bio->bi_write_stream.
> 
> F2FS added FDP stream mapping for DATA writes, but its direct write
> submit hook always rewrites bio->bi_write_stream from the inode write
> hint and F2FS temperature. As a result, a direct write with an explicit
> io_uring write_stream is submitted to the F2FS-selected stream instead
> of the user-requested stream.
> 
> Validate an explicit write stream before starting F2FS direct I/O, pass
> the kiocb through the iomap private pointer, and preserve the per-I/O
> stream in the direct write bio. When no per-I/O stream is supplied, keep
> using the existing F2FS temperature-to-stream mapping.
> 
> Fixes: 42f7a7a50a33 ("f2fs: map data writes to FDP streams")
> Signed-off-by: Wenjie Qi <[email protected]>
> ---
>  fs/f2fs/file.c | 30 +++++++++++++++++++++++++++---
>  1 file changed, 27 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 71385ca4163d..20d6e7ab7416 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -5074,17 +5074,36 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error,
>  	return 0;
>  }
>  
> +static bool f2fs_valid_write_stream(struct f2fs_sb_info *sbi, u8 write_stream)
> +{
> +	int i;
> +
> +	if (!write_stream)
> +		return true;
> +	if (!f2fs_is_multi_device(sbi))
> +		return write_stream <= bdev_max_write_streams(sbi->sb->s_bdev);
> +
> +	for (i = 0; i < sbi->s_ndevs; i++)
> +		if (write_stream > bdev_max_write_streams(FDEV(i).bdev))
> +			return false;
> +	return true;
> +}
> +
>  static void f2fs_dio_write_submit_io(const struct iomap_iter *iter,
>  					struct bio *bio, loff_t file_offset)
>  {
>  	struct inode *inode = iter->inode;
>  	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> +	struct kiocb *iocb = iter->private;
>  	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);
>  
>  	bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp);
> -	bio->bi_write_stream =
> -		f2fs_io_type_to_write_stream(bio->bi_bdev, DATA, temp);
> +	if (iocb->ki_write_stream)
> +		bio->bi_write_stream = iocb->ki_write_stream;
> +	else
> +		bio->bi_write_stream =
> +			f2fs_io_type_to_write_stream(bio->bi_bdev, DATA, temp);

Let me apply as below.

        bio->bi_write_stream =
+               iocb->ki_write_stream ? iocb->ki_write_stream :
                f2fs_io_type_to_write_stream(bio->bi_bdev, DATA, temp);


>  	blk_crypto_submit_bio(bio);
>  }
>  
> @@ -5122,6 +5141,11 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from,
>  
>  	trace_f2fs_direct_IO_enter(inode, iocb, count, WRITE);
>  
> +	if (!f2fs_valid_write_stream(sbi, iocb->ki_write_stream)) {
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
>  	if (iocb->ki_flags & IOCB_NOWAIT) {
>  		/* f2fs_convert_inline_inode() and block allocation can block */
>  		if (f2fs_has_inline_data(inode) ||
> @@ -5159,7 +5183,7 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from,
>  	if (pos + count > inode->i_size)
>  		dio_flags |= IOMAP_DIO_FORCE_WAIT;
>  	dio = __iomap_dio_rw(iocb, from, &f2fs_iomap_ops,
> -			     &f2fs_iomap_dio_write_ops, dio_flags, NULL, 0);
> +			     &f2fs_iomap_dio_write_ops, dio_flags, iocb, 0);
>  	if (IS_ERR_OR_NULL(dio)) {
>  		ret = PTR_ERR_OR_ZERO(dio);
>  		if (ret == -ENOTBLK)
> 
> base-commit: 520760b9f9156bf9698de38dc44c614fad68a1f9
> -- 
> 2.43.0
> 


_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.