aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2016-05-27 10:47:02 -0400
committerMike Snitzer <snitzer@redhat.com>2016-05-27 11:48:12 -0400
commit4ed89c97b0706477b822ea2182827640c0cec486 (patch)
treedf75cdc4f972e864a639303d27d12ab6a41b8dba /drivers/md/dm-crypt.c
parent202bae52934d4eb79ffaebf49f49b1cc64d8e40b (diff)
downloadlinux-next-4ed89c97b0706477b822ea2182827640c0cec486.tar.gz
dm crypt: fix error with too large bios
Notice: this object is not reachable from any branch.
When dm-crypt processes writes, it allocates a new bio in crypt_alloc_buffer(). The bio is allocated from a bio_set and it can have at most BIO_MAX_PAGES vector entries, however the incoming bio can be larger if it was allocated by other means. For example, bcache creates bios larger than BIO_MAX_PAGES (leaning on late bio-splitting). But if the incoming bio is larger than BIO_MAX_PAGES bio_alloc_bioset() fails and an error is returned. To avoid the error, we test for too large bio in crypt_map() and use dm_accept_partial_bio() to split the bio. dm_accept_partial_bio() trims the current bio to the desired size and requests that DM core send another bio with the rest of the data. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org # v3.16+ Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Notice: this object is not reachable from any branch.
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 4f3cb35549446..53d9a771e21a7 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1910,6 +1910,10 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
struct dm_crypt_io *io;
struct crypt_config *cc = ti->private;
+ if (unlikely(bio->bi_iter.bi_size > BIO_MAX_SIZE) &&
+ (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD | REQ_WRITE)) == REQ_WRITE)
+ dm_accept_partial_bio(bio, BIO_MAX_SIZE >> SECTOR_SHIFT);
+
/*
* If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues.
* - for REQ_FLUSH device-mapper core ensures that no IO is in-flight