lkml.org 
[lkml]   [2023]   [Aug]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5/6] block: use iomap for writes to block devices
    Date
    Use iomap in buffer_head compat mode to write to block devices.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
    Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
    Reviewed-by: Hannes Reinecke <hare@suse.de>
    ---
    block/Kconfig | 1 +
    block/fops.c | 31 +++++++++++++++++++++++++++++--
    2 files changed, 30 insertions(+), 2 deletions(-)

    diff --git a/block/Kconfig b/block/Kconfig
    index 86122e459fe046..1a13ef0b1ca10c 100644
    --- a/block/Kconfig
    +++ b/block/Kconfig
    @@ -5,6 +5,7 @@
    menuconfig BLOCK
    bool "Enable the block layer" if EXPERT
    default y
    + select FS_IOMAP
    select SBITMAP
    help
    Provide block layer support for the kernel.
    diff --git a/block/fops.c b/block/fops.c
    index f0b822c28ddfe2..063ece37d44e44 100644
    --- a/block/fops.c
    +++ b/block/fops.c
    @@ -15,6 +15,7 @@
    #include <linux/falloc.h>
    #include <linux/suspend.h>
    #include <linux/fs.h>
    +#include <linux/iomap.h>
    #include <linux/module.h>
    #include "blk.h"

    @@ -386,6 +387,27 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
    return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages));
    }

    +static int blkdev_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
    + unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
    +{
    + struct block_device *bdev = I_BDEV(inode);
    + loff_t isize = i_size_read(inode);
    +
    + iomap->bdev = bdev;
    + iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev));
    + if (iomap->offset >= isize)
    + return -EIO;
    + iomap->type = IOMAP_MAPPED;
    + iomap->addr = iomap->offset;
    + iomap->length = isize - iomap->offset;
    + iomap->flags |= IOMAP_F_BUFFER_HEAD;
    + return 0;
    +}
    +
    +static const struct iomap_ops blkdev_iomap_ops = {
    + .iomap_begin = blkdev_iomap_begin,
    +};
    +
    static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
    {
    return block_write_full_page(page, blkdev_get_block, wbc);
    @@ -556,6 +578,11 @@ blkdev_direct_write(struct kiocb *iocb, struct iov_iter *from)
    return written;
    }

    +static ssize_t blkdev_buffered_write(struct kiocb *iocb, struct iov_iter *from)
    +{
    + return iomap_file_buffered_write(iocb, from, &blkdev_iomap_ops);
    +}
    +
    /*
    * Write data to the block device. Only intended for the block device itself
    * and the raw driver which basically is a fake block device.
    @@ -605,9 +632,9 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
    ret = blkdev_direct_write(iocb, from);
    if (ret >= 0 && iov_iter_count(from))
    ret = direct_write_fallback(iocb, from, ret,
    - generic_perform_write(iocb, from));
    + blkdev_buffered_write(iocb, from));
    } else {
    - ret = generic_perform_write(iocb, from);
    + ret = blkdev_buffered_write(iocb, from);
    }

    if (ret > 0)
    --
    2.39.2
    \
     
     \ /
      Last update: 2023-08-01 19:23    [W:3.701 / U:0.896 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site