Skip to content

Commit b3c4e7b

Browse files
bvanasschekawasaki
authored andcommitted
block: Rework splitting of encrypted bios
Modify splitting of encrypted bios as follows: - Stop calling blk_crypto_bio_prep() for bio-based block drivers that do not call bio_split_to_limits(). - For request-based block drivers and for bio-based block drivers that call bio_split_to_limits(), call blk_crypto_bio_prep() after bio splitting happened instead of before bio splitting happened. - In bio_split_rw(), restrict the bio size to the smaller size of what is supported by the block driver and the crypto fallback code. The advantages of these changes are as follows: - This patch fixes write errors on zoned storage caused by out-of-order submission of bios. This out-of-order submission happens if both the crypto fallback code and bio_split_to_limits() split a bio. - Less code duplication. The crypto fallback code now calls bio_split_to_limits() instead of open-coding it. Signed-off-by: Bart Van Assche <[email protected]>
1 parent 1983192 commit b3c4e7b

4 files changed

Lines changed: 25 additions & 35 deletions

File tree

block/blk-core.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,6 @@ static void __submit_bio(struct bio *bio)
626626
/* If plug is not used, add new plug here to cache nsecs time. */
627627
struct blk_plug plug;
628628

629-
if (unlikely(!blk_crypto_bio_prep(&bio)))
630-
return;
631-
632629
blk_start_plug(&plug);
633630

634631
if (!bdev_test_flag(bio->bi_bdev, BD_HAS_SUBMIT_BIO)) {

block/blk-crypto-fallback.c

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ blk_crypto_fallback_alloc_cipher_req(struct blk_crypto_keyslot *slot,
214214
* the bio size supported by the encryption fallback code. This function
215215
* calculates the upper limit for the bio size.
216216
*/
217-
static unsigned int blk_crypto_max_io_size(struct bio *bio)
217+
unsigned int blk_crypto_max_io_size(struct bio *bio)
218218
{
219219
unsigned int i = 0;
220220
unsigned int num_sectors = 0;
@@ -230,29 +230,6 @@ static unsigned int blk_crypto_max_io_size(struct bio *bio)
230230
return num_sectors;
231231
}
232232

233-
static bool blk_crypto_fallback_split_bio_if_needed(struct bio **bio_ptr)
234-
{
235-
struct bio *bio = *bio_ptr;
236-
unsigned int num_sectors;
237-
238-
num_sectors = blk_crypto_max_io_size(bio);
239-
if (num_sectors < bio_sectors(bio)) {
240-
struct bio *split_bio;
241-
242-
split_bio = bio_split(bio, num_sectors, GFP_NOIO,
243-
&crypto_bio_split);
244-
if (IS_ERR(split_bio)) {
245-
bio->bi_status = BLK_STS_RESOURCE;
246-
return false;
247-
}
248-
bio_chain(split_bio, bio);
249-
submit_bio_noacct(bio);
250-
*bio_ptr = split_bio;
251-
}
252-
253-
return true;
254-
}
255-
256233
union blk_crypto_iv {
257234
__le64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
258235
u8 bytes[BLK_CRYPTO_MAX_IV_SIZE];
@@ -289,9 +266,12 @@ static bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr)
289266
bool ret = false;
290267
blk_status_t blk_st;
291268

292-
/* Split the bio if it's too big for single page bvec */
293-
if (!blk_crypto_fallback_split_bio_if_needed(bio_ptr))
269+
/* Verify that bio splitting has occurred. */
270+
if (WARN_ON_ONCE(bio_sectors(*bio_ptr) >
271+
blk_crypto_max_io_size(*bio_ptr))) {
272+
(*bio_ptr)->bi_status = BLK_STS_IOERR;
294273
return false;
274+
}
295275

296276
src_bio = *bio_ptr;
297277
bc = src_bio->bi_crypt_context;
@@ -488,10 +468,8 @@ static void blk_crypto_fallback_decrypt_endio(struct bio *bio)
488468
*
489469
* @bio_ptr: pointer to the bio to prepare
490470
*
491-
* If bio is doing a WRITE operation, this splits the bio into two parts if it's
492-
* too big (see blk_crypto_fallback_split_bio_if_needed()). It then allocates a
493-
* bounce bio for the first part, encrypts it, and updates bio_ptr to point to
494-
* the bounce bio.
471+
* For WRITE operations, a bounce bio is allocated, encrypted, and *bio_ptr is
472+
* updated to point to the bounce bio.
495473
*
496474
* For a READ operation, we mark the bio for decryption by using bi_private and
497475
* bi_end_io.

block/blk-crypto-internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr);
223223

224224
int blk_crypto_fallback_evict_key(const struct blk_crypto_key *key);
225225

226+
unsigned int blk_crypto_max_io_size(struct bio *bio);
227+
226228
#else /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */
227229

228230
static inline int
@@ -245,6 +247,11 @@ blk_crypto_fallback_evict_key(const struct blk_crypto_key *key)
245247
return 0;
246248
}
247249

250+
static inline unsigned int blk_crypto_max_io_size(struct bio *bio)
251+
{
252+
return UINT_MAX;
253+
}
254+
248255
#endif /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */
249256

250257
#endif /* __LINUX_BLK_CRYPTO_INTERNAL_H */

block/blk-merge.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/blk-integrity.h>
1010
#include <linux/part_stat.h>
1111
#include <linux/blk-cgroup.h>
12+
#include <linux/blk-crypto.h>
1213

1314
#include <trace/events/block.h>
1415

@@ -124,9 +125,13 @@ static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
124125
trace_block_split(split, bio->bi_iter.bi_sector);
125126
WARN_ON_ONCE(bio_zone_write_plugging(bio));
126127
submit_bio_noacct(bio);
127-
return split;
128+
129+
bio = split;
128130
}
129131

132+
if (unlikely(!blk_crypto_bio_prep(&bio)))
133+
return NULL;
134+
130135
return bio;
131136
error:
132137
bio->bi_status = errno_to_blk_status(split_sectors);
@@ -355,9 +360,12 @@ EXPORT_SYMBOL_GPL(bio_split_rw_at);
355360
struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
356361
unsigned *nr_segs)
357362
{
363+
u32 max_sectors =
364+
min(get_max_io_size(bio, lim), blk_crypto_max_io_size(bio));
365+
358366
return bio_submit_split(bio,
359367
bio_split_rw_at(bio, lim, nr_segs,
360-
get_max_io_size(bio, lim) << SECTOR_SHIFT));
368+
(u64)max_sectors << SECTOR_SHIFT));
361369
}
362370

363371
/*

0 commit comments

Comments
 (0)