Skip to content

Commit e038ee6

Browse files
Anuj Guptaaxboe
Anuj Gupta
authored andcommitted
block: unmap and free user mapped integrity via submitter
The user mapped intergity is copied back and unpinned by bio_integrity_free which is a low-level routine. Do it via the submitter rather than doing it in the low-level block layer code, to split the submitter side from the consumer side of the bio. Signed-off-by: Anuj Gupta <[email protected]> Signed-off-by: Kanchan Joshi <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent d0321c8 commit e038ee6

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

block/bio-integrity.c

+24-2
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,38 @@ void bio_integrity_free(struct bio *bio)
144144
struct bio_integrity_payload *bip = bio_integrity(bio);
145145
struct bio_set *bs = bio->bi_pool;
146146

147+
if (bip->bip_flags & BIP_INTEGRITY_USER)
148+
return;
147149
if (bip->bip_flags & BIP_BLOCK_INTEGRITY)
148150
kfree(bvec_virt(bip->bip_vec));
149-
else if (bip->bip_flags & BIP_INTEGRITY_USER)
150-
bio_integrity_unmap_user(bip);
151151

152152
__bio_integrity_free(bs, bip);
153153
bio->bi_integrity = NULL;
154154
bio->bi_opf &= ~REQ_INTEGRITY;
155155
}
156156

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)))
171+
return;
172+
bio_integrity_unmap_user(bip);
173+
__bio_integrity_free(bs, bip);
174+
bio->bi_integrity = NULL;
175+
bio->bi_opf &= ~REQ_INTEGRITY;
176+
}
177+
EXPORT_SYMBOL(bio_integrity_unmap_free_user);
178+
157179
/**
158180
* bio_integrity_add_page - Attach integrity metadata
159181
* @bio: bio to update

drivers/nvme/host/ioctl.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,
111111
return req;
112112
}
113113

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+
114121
static int nvme_map_user_request(struct request *req, u64 ubuffer,
115122
unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
116123
u32 meta_seed, struct io_uring_cmd *ioucmd, unsigned int flags)
@@ -157,7 +164,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
157164

158165
out_unmap:
159166
if (bio)
160-
blk_rq_unmap_user(bio);
167+
nvme_unmap_bio(bio);
161168
out:
162169
blk_mq_free_request(req);
163170
return ret;
@@ -195,7 +202,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
195202
if (result)
196203
*result = le64_to_cpu(nvme_req(req)->result.u64);
197204
if (bio)
198-
blk_rq_unmap_user(bio);
205+
nvme_unmap_bio(bio);
199206
blk_mq_free_request(req);
200207

201208
if (effects)
@@ -406,7 +413,7 @@ static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd,
406413
struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
407414

408415
if (pdu->bio)
409-
blk_rq_unmap_user(pdu->bio);
416+
nvme_unmap_bio(pdu->bio);
410417
io_uring_cmd_done(ioucmd, pdu->status, pdu->result, issue_flags);
411418
}
412419

@@ -432,7 +439,7 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
432439
*/
433440
if (blk_rq_is_poll(req)) {
434441
if (pdu->bio)
435-
blk_rq_unmap_user(pdu->bio);
442+
nvme_unmap_bio(pdu->bio);
436443
io_uring_cmd_iopoll_done(ioucmd, pdu->result, pdu->status);
437444
} else {
438445
io_uring_cmd_do_in_task_lazy(ioucmd, nvme_uring_task_cb);

include/linux/bio.h

+4
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ static inline bool bioset_initialized(struct bio_set *bs)
731731
bip_for_each_vec(_bvl, _bio->bi_integrity, _iter)
732732

733733
int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t len, u32 seed);
734+
void bio_integrity_unmap_free_user(struct bio *bio);
734735
extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
735736
extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
736737
extern bool bio_integrity_prep(struct bio *);
@@ -807,6 +808,9 @@ static inline int bio_integrity_map_user(struct bio *bio, void __user *ubuf,
807808
{
808809
return -EINVAL;
809810
}
811+
static inline void bio_integrity_unmap_free_user(struct bio *bio)
812+
{
813+
}
810814

811815
#endif /* CONFIG_BLK_DEV_INTEGRITY */
812816

0 commit comments

Comments
 (0)