Skip to content

Commit a312e17

Browse files
committed
Merge tag 'for-6.14/io_uring-20250119' of git://git.kernel.dk/linux
Pull io_uring updates from Jens Axboe: "Not a lot in terms of features this time around, mostly just cleanups and code consolidation: - Support for PI meta data read/write via io_uring, with NVMe and SCSI covered - Cleanup the per-op structure caching, making it consistent across various command types - Consolidate the various user mapped features into a concept called regions, making the various users of that consistent - Various cleanups and fixes" * tag 'for-6.14/io_uring-20250119' of git://git.kernel.dk/linux: (56 commits) io_uring/fdinfo: fix io_uring_show_fdinfo() misuse of ->d_iname io_uring: reuse io_should_terminate_tw() for cmds io_uring: Factor out a function to parse restrictions io_uring/rsrc: require cloned buffers to share accounting contexts io_uring: simplify the SQPOLL thread check when cancelling requests io_uring: expose read/write attribute capability io_uring/rw: don't gate retry on completion context io_uring/rw: handle -EAGAIN retry at IO completion time io_uring/rw: use io_rw_recycle() from cleanup path io_uring/rsrc: simplify the bvec iter count calculation io_uring: ensure io_queue_deferred() is out-of-line io_uring/rw: always clear ->bytes_done on io_async_rw setup io_uring/rw: use NULL for rw->free_iovec assigment io_uring/rw: don't mask in f_iocb_flags io_uring/msg_ring: Drop custom destructor io_uring: Move old async data allocation helper to header io_uring/rw: Allocate async data through helper io_uring/net: Allocate msghdr async data through helper io_uring/uring_cmd: Allocate async data through generic helper io_uring/poll: Allocate apoll with generic alloc_cache helper ...
2 parents 1cbfb82 + 561e3a0 commit a312e17

32 files changed

+845
-776
lines changed

block/bio-integrity.c

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,18 @@ static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs,
118118

119119
static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip)
120120
{
121-
unsigned short nr_vecs = bip->bip_max_vcnt - 1;
122-
struct bio_vec *copy = &bip->bip_vec[1];
123-
size_t bytes = bip->bip_iter.bi_size;
124-
struct iov_iter iter;
121+
unsigned short orig_nr_vecs = bip->bip_max_vcnt - 1;
122+
struct bio_vec *orig_bvecs = &bip->bip_vec[1];
123+
struct bio_vec *bounce_bvec = &bip->bip_vec[0];
124+
size_t bytes = bounce_bvec->bv_len;
125+
struct iov_iter orig_iter;
125126
int ret;
126127

127-
iov_iter_bvec(&iter, ITER_DEST, copy, nr_vecs, bytes);
128-
ret = copy_to_iter(bvec_virt(bip->bip_vec), bytes, &iter);
128+
iov_iter_bvec(&orig_iter, ITER_DEST, orig_bvecs, orig_nr_vecs, bytes);
129+
ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter);
129130
WARN_ON_ONCE(ret != bytes);
130131

131-
bio_integrity_unpin_bvec(copy, nr_vecs, true);
132+
bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs, true);
132133
}
133134

134135
/**
@@ -301,16 +302,15 @@ static unsigned int bvec_from_pages(struct bio_vec *bvec, struct page **pages,
301302
return nr_bvecs;
302303
}
303304

304-
int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t bytes)
305+
int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter)
305306
{
306307
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
307308
unsigned int align = blk_lim_dma_alignment_and_pad(&q->limits);
308309
struct page *stack_pages[UIO_FASTIOV], **pages = stack_pages;
309310
struct bio_vec stack_vec[UIO_FASTIOV], *bvec = stack_vec;
311+
size_t offset, bytes = iter->count;
310312
unsigned int direction, nr_bvecs;
311-
struct iov_iter iter;
312313
int ret, nr_vecs;
313-
size_t offset;
314314
bool copy;
315315

316316
if (bio_integrity(bio))
@@ -323,8 +323,7 @@ int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t bytes)
323323
else
324324
direction = ITER_SOURCE;
325325

326-
iov_iter_ubuf(&iter, direction, ubuf, bytes);
327-
nr_vecs = iov_iter_npages(&iter, BIO_MAX_VECS + 1);
326+
nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS + 1);
328327
if (nr_vecs > BIO_MAX_VECS)
329328
return -E2BIG;
330329
if (nr_vecs > UIO_FASTIOV) {
@@ -334,8 +333,8 @@ int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t bytes)
334333
pages = NULL;
335334
}
336335

337-
copy = !iov_iter_is_aligned(&iter, align, align);
338-
ret = iov_iter_extract_pages(&iter, &pages, bytes, nr_vecs, 0, &offset);
336+
copy = !iov_iter_is_aligned(iter, align, align);
337+
ret = iov_iter_extract_pages(iter, &pages, bytes, nr_vecs, 0, &offset);
339338
if (unlikely(ret < 0))
340339
goto free_bvec;
341340

@@ -365,6 +364,55 @@ int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t bytes)
365364
return ret;
366365
}
367366

367+
static void bio_uio_meta_to_bip(struct bio *bio, struct uio_meta *meta)
368+
{
369+
struct bio_integrity_payload *bip = bio_integrity(bio);
370+
371+
if (meta->flags & IO_INTEGRITY_CHK_GUARD)
372+
bip->bip_flags |= BIP_CHECK_GUARD;
373+
if (meta->flags & IO_INTEGRITY_CHK_APPTAG)
374+
bip->bip_flags |= BIP_CHECK_APPTAG;
375+
if (meta->flags & IO_INTEGRITY_CHK_REFTAG)
376+
bip->bip_flags |= BIP_CHECK_REFTAG;
377+
378+
bip->app_tag = meta->app_tag;
379+
}
380+
381+
int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta)
382+
{
383+
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
384+
unsigned int integrity_bytes;
385+
int ret;
386+
struct iov_iter it;
387+
388+
if (!bi)
389+
return -EINVAL;
390+
/*
391+
* original meta iterator can be bigger.
392+
* process integrity info corresponding to current data buffer only.
393+
*/
394+
it = meta->iter;
395+
integrity_bytes = bio_integrity_bytes(bi, bio_sectors(bio));
396+
if (it.count < integrity_bytes)
397+
return -EINVAL;
398+
399+
/* should fit into two bytes */
400+
BUILD_BUG_ON(IO_INTEGRITY_VALID_FLAGS >= (1 << 16));
401+
402+
if (meta->flags && (meta->flags & ~IO_INTEGRITY_VALID_FLAGS))
403+
return -EINVAL;
404+
405+
it.count = integrity_bytes;
406+
ret = bio_integrity_map_user(bio, &it);
407+
if (!ret) {
408+
bio_uio_meta_to_bip(bio, meta);
409+
bip_set_seed(bio_integrity(bio), meta->seed);
410+
iov_iter_advance(&meta->iter, integrity_bytes);
411+
meta->seed += bio_integrity_intervals(bi, bio_sectors(bio));
412+
}
413+
return ret;
414+
}
415+
368416
/**
369417
* bio_integrity_prep - Prepare bio for integrity I/O
370418
* @bio: bio to prepare
@@ -435,6 +483,11 @@ bool bio_integrity_prep(struct bio *bio)
435483
if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
436484
bip->bip_flags |= BIP_IP_CHECKSUM;
437485

486+
/* describe what tags to check in payload */
487+
if (bi->csum_type)
488+
bip->bip_flags |= BIP_CHECK_GUARD;
489+
if (bi->flags & BLK_INTEGRITY_REF_TAG)
490+
bip->bip_flags |= BIP_CHECK_REFTAG;
438491
if (bio_integrity_add_page(bio, virt_to_page(buf), len,
439492
offset_in_page(buf)) < len) {
440493
printk(KERN_ERR "could not attach integrity payload\n");
@@ -559,7 +612,8 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
559612

560613
bip->bip_vec = bip_src->bip_vec;
561614
bip->bip_iter = bip_src->bip_iter;
562-
bip->bip_flags = bip_src->bip_flags & ~BIP_BLOCK_INTEGRITY;
615+
bip->bip_flags = bip_src->bip_flags & BIP_CLONE_FLAGS;
616+
bip->app_tag = bip_src->app_tag;
563617

564618
return 0;
565619
}

block/blk-integrity.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,16 @@ EXPORT_SYMBOL(blk_rq_map_integrity_sg);
115115
int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
116116
ssize_t bytes)
117117
{
118-
int ret = bio_integrity_map_user(rq->bio, ubuf, bytes);
118+
int ret;
119+
struct iov_iter iter;
120+
unsigned int direction;
119121

122+
if (op_is_write(req_op(rq)))
123+
direction = ITER_DEST;
124+
else
125+
direction = ITER_SOURCE;
126+
iov_iter_ubuf(&iter, direction, ubuf, bytes);
127+
ret = bio_integrity_map_user(rq->bio, &iter);
120128
if (ret)
121129
return ret;
122130

block/fops.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
5454
struct bio bio;
5555
ssize_t ret;
5656

57+
WARN_ON_ONCE(iocb->ki_flags & IOCB_HAS_METADATA);
5758
if (nr_pages <= DIO_INLINE_BIO_VECS)
5859
vecs = inline_vecs;
5960
else {
@@ -124,12 +125,16 @@ static void blkdev_bio_end_io(struct bio *bio)
124125
{
125126
struct blkdev_dio *dio = bio->bi_private;
126127
bool should_dirty = dio->flags & DIO_SHOULD_DIRTY;
128+
bool is_sync = dio->flags & DIO_IS_SYNC;
127129

128130
if (bio->bi_status && !dio->bio.bi_status)
129131
dio->bio.bi_status = bio->bi_status;
130132

133+
if (!is_sync && (dio->iocb->ki_flags & IOCB_HAS_METADATA))
134+
bio_integrity_unmap_user(bio);
135+
131136
if (atomic_dec_and_test(&dio->ref)) {
132-
if (!(dio->flags & DIO_IS_SYNC)) {
137+
if (!is_sync) {
133138
struct kiocb *iocb = dio->iocb;
134139
ssize_t ret;
135140

@@ -221,14 +226,16 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
221226
* a retry of this from blocking context.
222227
*/
223228
if (unlikely(iov_iter_count(iter))) {
224-
bio_release_pages(bio, false);
225-
bio_clear_flag(bio, BIO_REFFED);
226-
bio_put(bio);
227-
blk_finish_plug(&plug);
228-
return -EAGAIN;
229+
ret = -EAGAIN;
230+
goto fail;
229231
}
230232
bio->bi_opf |= REQ_NOWAIT;
231233
}
234+
if (!is_sync && (iocb->ki_flags & IOCB_HAS_METADATA)) {
235+
ret = bio_integrity_map_iter(bio, iocb->private);
236+
if (unlikely(ret))
237+
goto fail;
238+
}
232239

233240
if (is_read) {
234241
if (dio->flags & DIO_SHOULD_DIRTY)
@@ -269,6 +276,12 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
269276

270277
bio_put(&dio->bio);
271278
return ret;
279+
fail:
280+
bio_release_pages(bio, false);
281+
bio_clear_flag(bio, BIO_REFFED);
282+
bio_put(bio);
283+
blk_finish_plug(&plug);
284+
return ret;
272285
}
273286

274287
static void blkdev_bio_end_io_async(struct bio *bio)
@@ -286,6 +299,9 @@ static void blkdev_bio_end_io_async(struct bio *bio)
286299
ret = blk_status_to_errno(bio->bi_status);
287300
}
288301

302+
if (iocb->ki_flags & IOCB_HAS_METADATA)
303+
bio_integrity_unmap_user(bio);
304+
289305
iocb->ki_complete(iocb, ret);
290306

291307
if (dio->flags & DIO_SHOULD_DIRTY) {
@@ -330,10 +346,8 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
330346
bio_iov_bvec_set(bio, iter);
331347
} else {
332348
ret = bio_iov_iter_get_pages(bio, iter);
333-
if (unlikely(ret)) {
334-
bio_put(bio);
335-
return ret;
336-
}
349+
if (unlikely(ret))
350+
goto out_bio_put;
337351
}
338352
dio->size = bio->bi_iter.bi_size;
339353

@@ -346,6 +360,13 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
346360
task_io_account_write(bio->bi_iter.bi_size);
347361
}
348362

363+
if (iocb->ki_flags & IOCB_HAS_METADATA) {
364+
ret = bio_integrity_map_iter(bio, iocb->private);
365+
WRITE_ONCE(iocb->private, NULL);
366+
if (unlikely(ret))
367+
goto out_bio_put;
368+
}
369+
349370
if (iocb->ki_flags & IOCB_ATOMIC)
350371
bio->bi_opf |= REQ_ATOMIC;
351372

@@ -360,6 +381,10 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
360381
submit_bio(bio);
361382
}
362383
return -EIOCBQUEUED;
384+
385+
out_bio_put:
386+
bio_put(bio);
387+
return ret;
363388
}
364389

365390
static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)

drivers/nvme/host/core.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,12 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
885885
return BLK_STS_OK;
886886
}
887887

888+
static void nvme_set_app_tag(struct request *req, struct nvme_command *cmnd)
889+
{
890+
cmnd->rw.lbat = cpu_to_le16(bio_integrity(req->bio)->app_tag);
891+
cmnd->rw.lbatm = cpu_to_le16(0xffff);
892+
}
893+
888894
static void nvme_set_ref_tag(struct nvme_ns *ns, struct nvme_command *cmnd,
889895
struct request *req)
890896
{
@@ -1017,18 +1023,17 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
10171023
control |= NVME_RW_PRINFO_PRACT;
10181024
}
10191025

1020-
switch (ns->head->pi_type) {
1021-
case NVME_NS_DPS_PI_TYPE3:
1026+
if (bio_integrity_flagged(req->bio, BIP_CHECK_GUARD))
10221027
control |= NVME_RW_PRINFO_PRCHK_GUARD;
1023-
break;
1024-
case NVME_NS_DPS_PI_TYPE1:
1025-
case NVME_NS_DPS_PI_TYPE2:
1026-
control |= NVME_RW_PRINFO_PRCHK_GUARD |
1027-
NVME_RW_PRINFO_PRCHK_REF;
1028+
if (bio_integrity_flagged(req->bio, BIP_CHECK_REFTAG)) {
1029+
control |= NVME_RW_PRINFO_PRCHK_REF;
10281030
if (op == nvme_cmd_zone_append)
10291031
control |= NVME_RW_APPEND_PIREMAP;
10301032
nvme_set_ref_tag(ns, cmnd, req);
1031-
break;
1033+
}
1034+
if (bio_integrity_flagged(req->bio, BIP_CHECK_APPTAG)) {
1035+
control |= NVME_RW_PRINFO_PRCHK_APP;
1036+
nvme_set_app_tag(req, cmnd);
10321037
}
10331038
}
10341039

drivers/scsi/sd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,14 +809,14 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
809809
if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
810810
scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
811811

812-
if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
812+
if (bio_integrity_flagged(bio, BIP_CHECK_GUARD))
813813
scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
814814
}
815815

816816
if (dif != T10_PI_TYPE3_PROTECTION) { /* DIX/DIF Type 0, 1, 2 */
817817
scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
818818

819-
if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
819+
if (bio_integrity_flagged(bio, BIP_CHECK_REFTAG))
820820
scmd->prot_flags |= SCSI_PROT_REF_CHECK;
821821
}
822822

include/linux/bio-integrity.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
enum bip_flags {
88
BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */
99
BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */
10-
BIP_CTRL_NOCHECK = 1 << 2, /* disable HBA integrity checking */
11-
BIP_DISK_NOCHECK = 1 << 3, /* disable disk integrity checking */
12-
BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */
13-
BIP_COPY_USER = 1 << 5, /* Kernel bounce buffer in use */
10+
BIP_DISK_NOCHECK = 1 << 2, /* disable disk integrity checking */
11+
BIP_IP_CHECKSUM = 1 << 3, /* IP checksum */
12+
BIP_COPY_USER = 1 << 4, /* Kernel bounce buffer in use */
13+
BIP_CHECK_GUARD = 1 << 5, /* guard check */
14+
BIP_CHECK_REFTAG = 1 << 6, /* reftag check */
15+
BIP_CHECK_APPTAG = 1 << 7, /* apptag check */
1416
};
1517

1618
struct bio_integrity_payload {
@@ -21,6 +23,7 @@ struct bio_integrity_payload {
2123
unsigned short bip_vcnt; /* # of integrity bio_vecs */
2224
unsigned short bip_max_vcnt; /* integrity bio_vec slots */
2325
unsigned short bip_flags; /* control flags */
26+
u16 app_tag; /* application tag value */
2427

2528
struct bvec_iter bio_iter; /* for rewinding parent bio */
2629

@@ -30,6 +33,9 @@ struct bio_integrity_payload {
3033
struct bio_vec bip_inline_vecs[];/* embedded bvec array */
3134
};
3235

36+
#define BIP_CLONE_FLAGS (BIP_MAPPED_INTEGRITY | BIP_IP_CHECKSUM | \
37+
BIP_CHECK_GUARD | BIP_CHECK_REFTAG | BIP_CHECK_APPTAG)
38+
3339
#ifdef CONFIG_BLK_DEV_INTEGRITY
3440

3541
#define bip_for_each_vec(bvl, bip, iter) \
@@ -72,7 +78,8 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
7278
unsigned int nr);
7379
int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len,
7480
unsigned int offset);
75-
int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t len);
81+
int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter);
82+
int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta);
7683
void bio_integrity_unmap_user(struct bio *bio);
7784
bool bio_integrity_prep(struct bio *bio);
7885
void bio_integrity_advance(struct bio *bio, unsigned int bytes_done);
@@ -98,8 +105,12 @@ static inline void bioset_integrity_free(struct bio_set *bs)
98105
{
99106
}
100107

101-
static inline int bio_integrity_map_user(struct bio *bio, void __user *ubuf,
102-
ssize_t len)
108+
static inline int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter)
109+
{
110+
return -EINVAL;
111+
}
112+
113+
static inline int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta)
103114
{
104115
return -EINVAL;
105116
}

include/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ struct readahead_control;
349349
#define IOCB_DIO_CALLER_COMP (1 << 22)
350350
/* kiocb is a read or write operation submitted by fs/aio.c. */
351351
#define IOCB_AIO_RW (1 << 23)
352+
#define IOCB_HAS_METADATA (1 << 24)
352353

353354
/* for use in trace events */
354355
#define TRACE_IOCB_STRINGS \

0 commit comments

Comments
 (0)