summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-09-17 20:18:24 +0100
committerMark Brown <broonie@kernel.org>2026-09-17 20:18:25 +0100
commit66c8b6b56c0906544ddfa39b0c0de52b485a0a2b (patch)
treecfe7fe92b314eb4471d7f6903dcfdabeafb24f7a /include
parent90602fcefb17ec6e5db8af042beab48e16995931 (diff)
parent2dd9768a37dbb99398c5e332485dbb107ac397c8 (diff)
downloadlinux-next-66c8b6b56c0906544ddfa39b0c0de52b485a0a2b.tar.gz
linux-next-66c8b6b56c0906544ddfa39b0c0de52b485a0a2b.zip
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git
Diffstat (limited to 'include')
-rw-r--r--include/linux/bio-integrity.h3
-rw-r--r--include/linux/bio.h17
-rw-r--r--include/linux/blkdev.h19
-rw-r--r--include/linux/io_uring.h32
-rw-r--r--include/linux/io_uring/cmd.h34
-rw-r--r--include/linux/io_uring_types.h2
-rw-r--r--include/linux/iomap.h38
7 files changed, 125 insertions, 20 deletions
diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
index 0ea2a8bf7efb..a954c97be0b3 100644
--- a/include/linux/bio-integrity.h
+++ b/include/linux/bio-integrity.h
@@ -151,7 +151,6 @@ void bio_integrity_setup_default(struct bio *bio);
unsigned int fs_bio_integrity_alloc(struct bio *bio);
void fs_bio_integrity_free(struct bio *bio);
void fs_bio_integrity_generate(struct bio *bio);
-int fs_bio_integrity_verify(struct bio *bio, sector_t sector,
- unsigned int size);
+int fs_bio_integrity_verify(struct bio *bio, struct bvec_iter *data_iter);
#endif /* _LINUX_BIO_INTEGRITY_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index bb3235497e67..75f8086351c0 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -256,6 +256,12 @@ static inline struct folio *bio_first_folio_all(struct bio *bio)
return page_folio(bio_first_page_all(bio));
}
+static inline struct bio_vec *bio_last_bvec_all(struct bio *bio)
+{
+ WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
+ return &bio->bi_io_vec[bio->bi_vcnt - 1];
+}
+
/**
* struct folio_iter - State for iterating all folios in a bio.
* @folio: The current folio we're iterating. NULL after the last folio.
@@ -479,6 +485,7 @@ static inline void bio_init_inline(struct bio *bio, struct block_device *bdev,
extern void bio_uninit(struct bio *);
void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf);
void bio_reuse(struct bio *bio, blk_opf_t opf);
+void bio_prepare_reissue(struct bio *bio, struct block_device *bdev);
void bio_chain(struct bio *, struct bio *);
void bio_await(struct bio *bio, void *priv,
void (*submit)(struct bio *bio, void *priv));
@@ -516,16 +523,18 @@ int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
size_t len, enum req_op op);
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
- unsigned mem_align_mask, unsigned len_align_mask);
+ unsigned maxlen, unsigned mem_align_mask,
+ unsigned len_align_mask);
bool bio_iov_iter_set(struct bio *bio, const struct iov_iter *iter);
void __bio_release_pages(struct bio *bio, bool mark_dirty);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
-int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen,
- size_t minsize);
-void bio_iov_iter_unbounce(struct bio *bio, bool is_error, bool mark_dirty);
+int bio_alloc_bounce_folios(struct bio *bio, size_t total_len, size_t minsize);
+void bio_free_folios(struct bio *bio);
+int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
+ size_t maxlen, size_t minsize);
extern void bio_copy_data(struct bio *dst, struct bio *src);
extern void bio_free_pages(struct bio *bio);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4f7905c3412b..d003a9d2d1f6 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -191,14 +191,17 @@ struct gendisk {
#ifdef CONFIG_BLK_DEV_ZONED
/*
* Zoned block device information. Reads of this information must be
- * protected with blk_queue_enter() / blk_queue_exit(). Modifying this
- * information is only allowed while no requests are being processed.
- * See also blk_mq_freeze_queue() and blk_mq_unfreeze_queue().
+ * protected with blk_queue_enter() / blk_queue_exit() or by holding a
+ * lock on zone_revalidate_mutex. blk_revalidate_disk_zones() may modify
+ * this information while no requests are being processed (disk queue
+ * frozen with blk_mq_freeze_queue()) and while holding a lock on
+ * zone_revalidate_mutex.
*/
+ struct mutex zone_revalidate_mutex;
unsigned int nr_zones;
unsigned int zone_capacity;
unsigned int last_zone_capacity;
- u8 __rcu *zones_cond;
+ u8 __rcu *zones_state;
unsigned int zone_wplugs_hash_bits;
atomic_t nr_zone_wplugs;
spinlock_t zone_wplugs_hash_lock;
@@ -1816,9 +1819,11 @@ static inline int bio_split_rw_at(struct bio *bio,
*/
static inline unsigned int max_integrity_io_size(struct queue_limits *lim)
{
- return min_t(unsigned int, lim->max_segment_size,
- (BLK_INTEGRITY_MAX_SIZE / lim->integrity.metadata_size) <<
- lim->integrity.interval_exp);
+ u64 max_intervals;
+
+ max_intervals = BLK_INTEGRITY_MAX_SIZE / lim->integrity.metadata_size;
+ return min_t(u64, lim->max_segment_size,
+ max_intervals << lim->integrity.interval_exp);
}
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index d1aa4edfc2a5..505caa99c621 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -2,10 +2,42 @@
#ifndef _LINUX_IO_URING_H
#define _LINUX_IO_URING_H
+#include <linux/io_uring_types.h>
#include <linux/sched.h>
#include <linux/xarray.h>
#include <uapi/linux/io_uring.h>
+static inline void req_set_fail(struct io_kiocb *req)
+{
+ req->flags |= REQ_F_FAIL;
+ if (req->flags & REQ_F_CQE_SKIP) {
+ req->flags &= ~REQ_F_CQE_SKIP;
+ req->flags |= REQ_F_SKIP_LINK_CQES;
+ }
+}
+
+static inline void io_req_set_res(struct io_kiocb *req, s32 res, u32 cflags)
+{
+ req->cqe.res = res;
+ req->cqe.flags = cflags;
+}
+
+static inline u32 ctx_cqe32_flags(struct io_ring_ctx *ctx)
+{
+ if (ctx->flags & IORING_SETUP_CQE_MIXED)
+ return IORING_CQE_F_32;
+ return 0;
+}
+
+static inline void io_req_set_res32(struct io_kiocb *req, s32 res, u32 cflags,
+ __u64 extra1, __u64 extra2)
+{
+ req->cqe.res = res;
+ req->cqe.flags = cflags | ctx_cqe32_flags(req->ctx);
+ req->big_cqe.extra1 = extra1;
+ req->big_cqe.extra2 = extra2;
+}
+
#if defined(CONFIG_IO_URING)
void __io_uring_cancel(bool cancel_all);
void __io_uring_free(struct task_struct *tsk);
diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h
index 42801f0b6456..e18d4af62e1a 100644
--- a/include/linux/io_uring/cmd.h
+++ b/include/linux/io_uring/cmd.h
@@ -3,6 +3,7 @@
#define _LINUX_IO_URING_CMD_H
#include <uapi/linux/io_uring.h>
+#include <linux/io_uring.h>
#include <linux/io_uring_types.h>
#include <linux/blk-mq.h>
@@ -41,6 +42,24 @@ static inline void io_uring_cmd_private_sz_check(size_t cmd_sz)
((pdu_type *)&(cmd)->pdu) \
)
+static inline void io_uring_cmd_set_res(struct io_uring_cmd *cmd, s32 ret)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+}
+
+static inline void io_uring_cmd_set_res32(struct io_uring_cmd *cmd, s32 ret, u64 res2)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res32(req, ret, 0, res2, 0);
+}
+
#if defined(CONFIG_IO_URING)
int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter,
@@ -56,11 +75,12 @@ int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
* Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd
* and the corresponding io_uring request.
*
+ * io_uring_cmd_set_res()/io_uring_cmd_set_res32() must be called first.
+ *
* Note: the caller should never hard code @issue_flags and is only allowed
* to pass the mask provided by the core io_uring code.
*/
-void __io_uring_cmd_done(struct io_uring_cmd *cmd, s32 ret, u64 res2,
- unsigned issue_flags, bool is_cqe32);
+void __io_uring_cmd_done(struct io_uring_cmd *, unsigned issue_flags);
void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
io_req_tw_func_t task_work_cb,
@@ -116,8 +136,8 @@ static inline int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
{
return -EOPNOTSUPP;
}
-static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd, s32 ret,
- u64 ret2, unsigned issue_flags, bool is_cqe32)
+static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd,
+ unsigned issue_flags)
{
}
static inline void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
@@ -205,13 +225,15 @@ static inline void *io_uring_cmd_ctx_handle(struct io_uring_cmd *cmd)
static inline void io_uring_cmd_done(struct io_uring_cmd *ioucmd, s32 ret,
unsigned issue_flags)
{
- return __io_uring_cmd_done(ioucmd, ret, 0, issue_flags, false);
+ io_uring_cmd_set_res(ioucmd, ret);
+ __io_uring_cmd_done(ioucmd, issue_flags);
}
static inline void io_uring_cmd_done32(struct io_uring_cmd *ioucmd, s32 ret,
u64 res2, unsigned issue_flags)
{
- return __io_uring_cmd_done(ioucmd, ret, res2, issue_flags, true);
+ io_uring_cmd_set_res32(ioucmd, ret, res2);
+ __io_uring_cmd_done(ioucmd, issue_flags);
}
#endif /* _LINUX_IO_URING_CMD_H */
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index 39629ee77b91..90fea94ad202 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -522,6 +522,8 @@ struct io_ring_ctx {
/* protected by ->completion_lock */
unsigned nr_req_allocated;
+ /* pending SEND_ZC notifications, protected by ->uring_lock */
+ unsigned nr_notifs;
#ifdef CONFIG_NET_RX_BUSY_POLL
struct list_head napi_list; /* track busy poll napi_id */
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index bc7ae6327dbf..59718f73c15a 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -483,13 +483,35 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
#define IOMAP_IOEND_BOUNDARY (1U << 2)
/* is direct I/O */
#define IOMAP_IOEND_DIRECT (1U << 3)
+/* generate integrity (PI) information */
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+#define IOMAP_IOEND_INTEGRITY (1U << 4)
+#else
+#define IOMAP_IOEND_INTEGRITY 0
+#endif /* CONFIG_BLK_DEV_INTEGRITY */
/*
* Flags that if set on either ioend prevent the merge of two ioends.
* (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way)
*/
#define IOMAP_IOEND_NOMERGE_FLAGS \
- (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT)
+ (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT | \
+ IOMAP_IOEND_INTEGRITY)
+
+/* ioend flags directly implied by iomap flags */
+static inline u16 iomap_ioend_flags(const struct iomap *iomap)
+{
+ unsigned int flags = 0;
+
+ if (iomap->type == IOMAP_UNWRITTEN)
+ flags |= IOMAP_IOEND_UNWRITTEN;
+ if (iomap->flags & IOMAP_F_SHARED)
+ flags |= IOMAP_IOEND_SHARED;
+ if (iomap->flags & IOMAP_F_INTEGRITY)
+ flags |= IOMAP_IOEND_INTEGRITY;
+
+ return flags;
+}
/*
* Structure for writeback I/O completions.
@@ -500,6 +522,7 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
struct iomap_ioend {
struct list_head io_list; /* next ioend in chain */
u16 io_flags; /* IOMAP_IOEND_* */
+ u32 io_bvec_offset; /* offset into first bvec */
struct inode *io_inode; /* file being written to */
size_t io_size; /* size of the extent */
atomic_t io_remaining; /* completetion defer count */
@@ -517,6 +540,13 @@ static inline struct iomap_ioend *iomap_ioend_from_bio(struct bio *bio)
return container_of(bio, struct iomap_ioend, io_bio);
}
+#define BVEC_ITER_IOEND(_ioend) \
+{ \
+ .bi_sector = (_ioend)->io_sector, \
+ .bi_size = (_ioend)->io_size, \
+ .bi_offset = (_ioend)->io_bvec_offset, \
+}
+
struct iomap_writeback_ops {
/*
* Performs writeback on the passed in range
@@ -565,6 +595,7 @@ void iomap_finish_ioends(struct iomap_ioend *ioend, int error);
void iomap_ioend_try_merge(struct iomap_ioend *ioend,
struct list_head *more_ioends);
void iomap_sort_ioends(struct list_head *ioend_list);
+int iomap_ioend_integrity_verify(struct iomap_ioend *ioend);
ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio,
loff_t pos, loff_t end_pos, unsigned int dirty_len);
int iomap_ioend_writeback_submit(struct iomap_writepage_ctx *wpc, int error);
@@ -577,6 +608,11 @@ void iomap_finish_folio_write(struct inode *inode, struct folio *folio,
int iomap_writeback_folio(struct iomap_writepage_ctx *wpc, struct folio *folio);
int iomap_writepages(struct iomap_writepage_ctx *wpc);
+void iomap_bounce_read(struct iomap_ioend *orig_ioend, unsigned int minsize,
+ void (*submit_ioend)(struct iomap_ioend *ioend));
+void iomap_bounce_read_end_io(struct iomap_ioend *ioend, struct bio *orig_bio,
+ int error);
+
struct iomap_read_folio_ctx {
const struct iomap_read_ops *ops;
struct folio *cur_folio;