Skip to content

Commit 0256994

Browse files
committed
Merge tag 'for-6.11/block-post-20240722' of git://git.kernel.dk/linux
Pull block integrity mapping updates from Jens Axboe: "A set of cleanups and fixes for the block integrity support. Sent separately from the main block changes from last week, as they depended on later fixes in the 6.10-rc cycle" * tag 'for-6.11/block-post-20240722' of git://git.kernel.dk/linux: block: don't free the integrity payload in bio_integrity_unmap_free_user block: don't free submitter owned integrity payload on I/O completion block: call bio_integrity_unmap_free_user from blk_rq_unmap_user block: don't call bio_uninit from bio_endio block: also return bio_integrity_payload * from stubs block: split integrity support out of bio.h
2 parents dd018c2 + 74cc150 commit 0256994

File tree

11 files changed

+222
-229
lines changed

11 files changed

+222
-229
lines changed

block/bio-integrity.c

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ void blk_flush_integrity(void)
2222
flush_workqueue(kintegrityd_wq);
2323
}
2424

25-
static void __bio_integrity_free(struct bio_set *bs,
26-
struct bio_integrity_payload *bip)
25+
/**
26+
* bio_integrity_free - Free bio integrity payload
27+
* @bio: bio containing bip to be freed
28+
*
29+
* Description: Free the integrity portion of a bio.
30+
*/
31+
void bio_integrity_free(struct bio *bio)
2732
{
33+
struct bio_integrity_payload *bip = bio_integrity(bio);
34+
struct bio_set *bs = bio->bi_pool;
35+
2836
if (bs && mempool_initialized(&bs->bio_integrity_pool)) {
2937
if (bip->bip_vec)
3038
bvec_free(&bs->bvec_integrity_pool, bip->bip_vec,
@@ -33,6 +41,8 @@ static void __bio_integrity_free(struct bio_set *bs,
3341
} else {
3442
kfree(bip);
3543
}
44+
bio->bi_integrity = NULL;
45+
bio->bi_opf &= ~REQ_INTEGRITY;
3646
}
3747

3848
/**
@@ -86,7 +96,10 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
8696

8797
return bip;
8898
err:
89-
__bio_integrity_free(bs, bip);
99+
if (bs && mempool_initialized(&bs->bio_integrity_pool))
100+
mempool_free(bip, &bs->bio_integrity_pool);
101+
else
102+
kfree(bip);
90103
return ERR_PTR(-ENOMEM);
91104
}
92105
EXPORT_SYMBOL(bio_integrity_alloc);
@@ -118,63 +131,26 @@ static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip)
118131
bio_integrity_unpin_bvec(copy, nr_vecs, true);
119132
}
120133

121-
static void bio_integrity_unmap_user(struct bio_integrity_payload *bip)
122-
{
123-
bool dirty = bio_data_dir(bip->bip_bio) == READ;
124-
125-
if (bip->bip_flags & BIP_COPY_USER) {
126-
if (dirty)
127-
bio_integrity_uncopy_user(bip);
128-
kfree(bvec_virt(bip->bip_vec));
129-
return;
130-
}
131-
132-
bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt, dirty);
133-
}
134-
135134
/**
136-
* bio_integrity_free - Free bio integrity payload
137-
* @bio: bio containing bip to be freed
135+
* bio_integrity_unmap_user - Unmap user integrity payload
136+
* @bio: bio containing bip to be unmapped
138137
*
139-
* Description: Used to free the integrity portion of a bio. Usually
140-
* called from bio_free().
138+
* Unmap the user mapped integrity portion of a bio.
141139
*/
142-
void bio_integrity_free(struct bio *bio)
140+
void bio_integrity_unmap_user(struct bio *bio)
143141
{
144142
struct bio_integrity_payload *bip = bio_integrity(bio);
145-
struct bio_set *bs = bio->bi_pool;
146143

147-
if (bip->bip_flags & BIP_INTEGRITY_USER)
148-
return;
149-
if (bip->bip_flags & BIP_BLOCK_INTEGRITY)
144+
if (bip->bip_flags & BIP_COPY_USER) {
145+
if (bio_data_dir(bio) == READ)
146+
bio_integrity_uncopy_user(bip);
150147
kfree(bvec_virt(bip->bip_vec));
151-
152-
__bio_integrity_free(bs, bip);
153-
bio->bi_integrity = NULL;
154-
bio->bi_opf &= ~REQ_INTEGRITY;
155-
}
156-
157-
/**
158-
* bio_integrity_unmap_free_user - Unmap and free bio user integrity payload
159-
* @bio: bio containing bip to be unmapped and freed
160-
*
161-
* Description: Used to unmap and free the user mapped integrity portion of a
162-
* bio. Submitter attaching the user integrity buffer is responsible for
163-
* unmapping and freeing it during completion.
164-
*/
165-
void bio_integrity_unmap_free_user(struct bio *bio)
166-
{
167-
struct bio_integrity_payload *bip = bio_integrity(bio);
168-
struct bio_set *bs = bio->bi_pool;
169-
170-
if (WARN_ON_ONCE(!(bip->bip_flags & BIP_INTEGRITY_USER)))
171148
return;
172-
bio_integrity_unmap_user(bip);
173-
__bio_integrity_free(bs, bip);
174-
bio->bi_integrity = NULL;
175-
bio->bi_opf &= ~REQ_INTEGRITY;
149+
}
150+
151+
bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt,
152+
bio_data_dir(bio) == READ);
176153
}
177-
EXPORT_SYMBOL(bio_integrity_unmap_free_user);
178154

179155
/**
180156
* bio_integrity_add_page - Attach integrity metadata
@@ -274,7 +250,7 @@ static int bio_integrity_copy_user(struct bio *bio, struct bio_vec *bvec,
274250
goto free_bip;
275251
}
276252

277-
bip->bip_flags |= BIP_INTEGRITY_USER | BIP_COPY_USER;
253+
bip->bip_flags |= BIP_COPY_USER;
278254
bip->bip_iter.bi_sector = seed;
279255
bip->bip_vcnt = nr_vecs;
280256
return 0;
@@ -295,7 +271,6 @@ static int bio_integrity_init_user(struct bio *bio, struct bio_vec *bvec,
295271
return PTR_ERR(bip);
296272

297273
memcpy(bip->bip_vec, bvec, nr_vecs * sizeof(*bvec));
298-
bip->bip_flags |= BIP_INTEGRITY_USER;
299274
bip->bip_iter.bi_sector = seed;
300275
bip->bip_iter.bi_size = len;
301276
bip->bip_vcnt = nr_vecs;
@@ -503,6 +478,8 @@ static void bio_integrity_verify_fn(struct work_struct *work)
503478
struct bio *bio = bip->bip_bio;
504479

505480
blk_integrity_verify(bio);
481+
482+
kfree(bvec_virt(bip->bip_vec));
506483
bio_integrity_free(bio);
507484
bio_endio(bio);
508485
}
@@ -523,13 +500,13 @@ bool __bio_integrity_endio(struct bio *bio)
523500
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
524501
struct bio_integrity_payload *bip = bio_integrity(bio);
525502

526-
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
527-
(bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->csum_type) {
503+
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && bi->csum_type) {
528504
INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
529505
queue_work(kintegrityd_wq, &bip->bip_work);
530506
return false;
531507
}
532508

509+
kfree(bvec_virt(bip->bip_vec));
533510
bio_integrity_free(bio);
534511
return true;
535512
}

block/bio.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
#include <linux/mm.h>
66
#include <linux/swap.h>
7-
#include <linux/bio.h>
7+
#include <linux/bio-integrity.h>
88
#include <linux/blkdev.h>
99
#include <linux/uio.h>
1010
#include <linux/iocontext.h>
@@ -1630,8 +1630,18 @@ void bio_endio(struct bio *bio)
16301630
goto again;
16311631
}
16321632

1633-
/* release cgroup info */
1634-
bio_uninit(bio);
1633+
#ifdef CONFIG_BLK_CGROUP
1634+
/*
1635+
* Release cgroup info. We shouldn't have to do this here, but quite
1636+
* a few callers of bio_init fail to call bio_uninit, so we cover up
1637+
* for that here at least for now.
1638+
*/
1639+
if (bio->bi_blkg) {
1640+
blkg_put(bio->bi_blkg);
1641+
bio->bi_blkg = NULL;
1642+
}
1643+
#endif
1644+
16351645
if (bio->bi_end_io)
16361646
bio->bi_end_io(bio);
16371647
}

block/blk-map.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,9 @@ int blk_rq_unmap_user(struct bio *bio)
757757
bio_release_pages(bio, bio_data_dir(bio) == READ);
758758
}
759759

760+
if (bio_integrity(bio))
761+
bio_integrity_unmap_user(bio);
762+
760763
next_bio = bio;
761764
bio = bio->bi_next;
762765
blk_mq_map_bio_put(next_bio);

block/blk.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef BLK_INTERNAL_H
33
#define BLK_INTERNAL_H
44

5+
#include <linux/bio-integrity.h>
56
#include <linux/blk-crypto.h>
67
#include <linux/memblock.h> /* for max_pfn/max_low_pfn */
78
#include <linux/sched/sysctl.h>
@@ -201,11 +202,20 @@ static inline unsigned int blk_queue_get_max_sectors(struct request *rq)
201202

202203
#ifdef CONFIG_BLK_DEV_INTEGRITY
203204
void blk_flush_integrity(void);
204-
bool __bio_integrity_endio(struct bio *);
205205
void bio_integrity_free(struct bio *bio);
206+
207+
/*
208+
* Integrity payloads can either be owned by the submitter, in which case
209+
* bio_uninit will free them, or owned and generated by the block layer,
210+
* in which case we'll verify them here (for reads) and free them before
211+
* the bio is handed back to the submitted.
212+
*/
213+
bool __bio_integrity_endio(struct bio *bio);
206214
static inline bool bio_integrity_endio(struct bio *bio)
207215
{
208-
if (bio_integrity(bio))
216+
struct bio_integrity_payload *bip = bio_integrity(bio);
217+
218+
if (bip && (bip->bip_flags & BIP_BLOCK_INTEGRITY))
209219
return __bio_integrity_endio(bio);
210220
return true;
211221
}

block/bounce.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <linux/export.h>
1111
#include <linux/swap.h>
1212
#include <linux/gfp.h>
13-
#include <linux/bio.h>
13+
#include <linux/bio-integrity.h>
1414
#include <linux/pagemap.h>
1515
#include <linux/mempool.h>
1616
#include <linux/blkdev.h>

drivers/md/dm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "dm-uevent.h"
1212
#include "dm-ima.h"
1313

14+
#include <linux/bio-integrity.h>
1415
#include <linux/init.h>
1516
#include <linux/module.h>
1617
#include <linux/mutex.h>

drivers/nvme/host/ioctl.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2011-2014, Intel Corporation.
44
* Copyright (c) 2017-2021 Christoph Hellwig.
55
*/
6+
#include <linux/bio-integrity.h>
67
#include <linux/ptrace.h> /* for force_successful_syscall_return */
78
#include <linux/nvme_ioctl.h>
89
#include <linux/io_uring/cmd.h>
@@ -111,13 +112,6 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,
111112
return req;
112113
}
113114

114-
static void nvme_unmap_bio(struct bio *bio)
115-
{
116-
if (bio_integrity(bio))
117-
bio_integrity_unmap_free_user(bio);
118-
blk_rq_unmap_user(bio);
119-
}
120-
121115
static int nvme_map_user_request(struct request *req, u64 ubuffer,
122116
unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
123117
u32 meta_seed, struct io_uring_cmd *ioucmd, unsigned int flags)
@@ -164,7 +158,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
164158

165159
out_unmap:
166160
if (bio)
167-
nvme_unmap_bio(bio);
161+
blk_rq_unmap_user(bio);
168162
out:
169163
blk_mq_free_request(req);
170164
return ret;
@@ -202,7 +196,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
202196
if (result)
203197
*result = le64_to_cpu(nvme_req(req)->result.u64);
204198
if (bio)
205-
nvme_unmap_bio(bio);
199+
blk_rq_unmap_user(bio);
206200
blk_mq_free_request(req);
207201

208202
if (effects)
@@ -413,7 +407,7 @@ static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd,
413407
struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
414408

415409
if (pdu->bio)
416-
nvme_unmap_bio(pdu->bio);
410+
blk_rq_unmap_user(pdu->bio);
417411
io_uring_cmd_done(ioucmd, pdu->status, pdu->result, issue_flags);
418412
}
419413

@@ -439,7 +433,7 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
439433
*/
440434
if (blk_rq_is_poll(req)) {
441435
if (pdu->bio)
442-
nvme_unmap_bio(pdu->bio);
436+
blk_rq_unmap_user(pdu->bio);
443437
io_uring_cmd_iopoll_done(ioucmd, pdu->result, pdu->status);
444438
} else {
445439
io_uring_cmd_do_in_task_lazy(ioucmd, nvme_uring_task_cb);

drivers/scsi/sd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@
3333
* than the level indicated above to trigger output.
3434
*/
3535

36+
#include <linux/bio-integrity.h>
3637
#include <linux/module.h>
3738
#include <linux/fs.h>
3839
#include <linux/kernel.h>
3940
#include <linux/mm.h>
40-
#include <linux/bio.h>
41+
#include <linux/bio-integrity.h>
4142
#include <linux/hdreg.h>
4243
#include <linux/errno.h>
4344
#include <linux/idr.h>

0 commit comments

Comments
 (0)