mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 22:22:51 -04:00
Merge patch series "io_uring / dio metadata fixes"
Christoph Hellwig <hch@lst.de> says: Hi all, while trying to add XFS support for passing through metadata I ran into a few issues with how that support is wire up for the current block device use cases, and this fixes it. * patches from https://lore.kernel.org/20250819082517.2038819-1-hch@lst.de: block: don't silently ignore metadata for sync read/write fs: add a FMODE_ flag to indicate IOCB_HAS_METADATA availability Link: https://lore.kernel.org/20250819082517.2038819-1-hch@lst.de Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
13
block/fops.c
13
block/fops.c
@@ -7,6 +7,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/blk-integrity.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/mpage.h>
|
||||
#include <linux/uio.h>
|
||||
@@ -54,7 +55,6 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
|
||||
struct bio bio;
|
||||
ssize_t ret;
|
||||
|
||||
WARN_ON_ONCE(iocb->ki_flags & IOCB_HAS_METADATA);
|
||||
if (nr_pages <= DIO_INLINE_BIO_VECS)
|
||||
vecs = inline_vecs;
|
||||
else {
|
||||
@@ -131,7 +131,7 @@ static void blkdev_bio_end_io(struct bio *bio)
|
||||
if (bio->bi_status && !dio->bio.bi_status)
|
||||
dio->bio.bi_status = bio->bi_status;
|
||||
|
||||
if (!is_sync && (dio->iocb->ki_flags & IOCB_HAS_METADATA))
|
||||
if (bio_integrity(bio))
|
||||
bio_integrity_unmap_user(bio);
|
||||
|
||||
if (atomic_dec_and_test(&dio->ref)) {
|
||||
@@ -233,7 +233,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
|
||||
}
|
||||
bio->bi_opf |= REQ_NOWAIT;
|
||||
}
|
||||
if (!is_sync && (iocb->ki_flags & IOCB_HAS_METADATA)) {
|
||||
if (iocb->ki_flags & IOCB_HAS_METADATA) {
|
||||
ret = bio_integrity_map_iter(bio, iocb->private);
|
||||
if (unlikely(ret))
|
||||
goto fail;
|
||||
@@ -301,7 +301,7 @@ static void blkdev_bio_end_io_async(struct bio *bio)
|
||||
ret = blk_status_to_errno(bio->bi_status);
|
||||
}
|
||||
|
||||
if (iocb->ki_flags & IOCB_HAS_METADATA)
|
||||
if (bio_integrity(bio))
|
||||
bio_integrity_unmap_user(bio);
|
||||
|
||||
iocb->ki_complete(iocb, ret);
|
||||
@@ -422,7 +422,8 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
||||
}
|
||||
|
||||
nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1);
|
||||
if (likely(nr_pages <= BIO_MAX_VECS)) {
|
||||
if (likely(nr_pages <= BIO_MAX_VECS &&
|
||||
!(iocb->ki_flags & IOCB_HAS_METADATA))) {
|
||||
if (is_sync_kiocb(iocb))
|
||||
return __blkdev_direct_IO_simple(iocb, iter, bdev,
|
||||
nr_pages);
|
||||
@@ -687,6 +688,8 @@ static int blkdev_open(struct inode *inode, struct file *filp)
|
||||
|
||||
if (bdev_can_atomic_write(bdev))
|
||||
filp->f_mode |= FMODE_CAN_ATOMIC_WRITE;
|
||||
if (blk_get_integrity(bdev->bd_disk))
|
||||
filp->f_mode |= FMODE_HAS_METADATA;
|
||||
|
||||
ret = bdev_open(bdev, mode, filp->private_data, NULL, filp);
|
||||
if (ret)
|
||||
|
||||
@@ -149,7 +149,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
||||
/* Expect random access pattern */
|
||||
#define FMODE_RANDOM ((__force fmode_t)(1 << 12))
|
||||
|
||||
/* FMODE_* bit 13 */
|
||||
/* Supports IOCB_HAS_METADATA */
|
||||
#define FMODE_HAS_METADATA ((__force fmode_t)(1 << 13))
|
||||
|
||||
/* File is opened with O_PATH; almost nothing can be done with it */
|
||||
#define FMODE_PATH ((__force fmode_t)(1 << 14))
|
||||
|
||||
@@ -886,6 +886,9 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type)
|
||||
if (req->flags & REQ_F_HAS_METADATA) {
|
||||
struct io_async_rw *io = req->async_data;
|
||||
|
||||
if (!(file->f_mode & FMODE_HAS_METADATA))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* We have a union of meta fields with wpq used for buffered-io
|
||||
* in io_async_rw, so fail it here.
|
||||
|
||||
Reference in New Issue
Block a user