aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 28c6ae095c56..6b66ee46b87d 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -398,7 +398,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
398 struct bio *clone; 398 struct bio *clone;
399 unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 399 unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
400 gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; 400 gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
401 unsigned int i; 401 unsigned i, len;
402 struct page *page;
402 403
403 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); 404 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
404 if (!clone) 405 if (!clone)
@@ -407,10 +408,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
407 clone_init(io, clone); 408 clone_init(io, clone);
408 409
409 for (i = 0; i < nr_iovecs; i++) { 410 for (i = 0; i < nr_iovecs; i++) {
410 struct bio_vec *bv = bio_iovec_idx(clone, i); 411 page = mempool_alloc(cc->page_pool, gfp_mask);
411 412 if (!page)
412 bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
413 if (!bv->bv_page)
414 break; 413 break;
415 414
416 /* 415 /*
@@ -421,15 +420,14 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
421 if (i == (MIN_BIO_PAGES - 1)) 420 if (i == (MIN_BIO_PAGES - 1))
422 gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; 421 gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
423 422
424 bv->bv_offset = 0; 423 len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
425 if (size > PAGE_SIZE) 424
426 bv->bv_len = PAGE_SIZE; 425 if (!bio_add_page(clone, page, len, 0)) {
427 else 426 mempool_free(page, cc->page_pool);
428 bv->bv_len = size; 427 break;
428 }
429 429
430 clone->bi_size += bv->bv_len; 430 size -= len;
431 clone->bi_vcnt++;
432 size -= bv->bv_len;
433 } 431 }
434 432
435 if (!clone->bi_size) { 433 if (!clone->bi_size) {
@@ -511,6 +509,9 @@ static void crypt_endio(struct bio *clone, int error)
511 struct crypt_config *cc = io->target->private; 509 struct crypt_config *cc = io->target->private;
512 unsigned read_io = bio_data_dir(clone) == READ; 510 unsigned read_io = bio_data_dir(clone) == READ;
513 511
512 if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error))
513 error = -EIO;
514
514 /* 515 /*
515 * free the processed pages 516 * free the processed pages
516 */ 517 */
@@ -519,10 +520,8 @@ static void crypt_endio(struct bio *clone, int error)
519 goto out; 520 goto out;
520 } 521 }
521 522
522 if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) { 523 if (unlikely(error))
523 error = -EIO;
524 goto out; 524 goto out;
525 }
526 525
527 bio_put(clone); 526 bio_put(clone);
528 kcryptd_queue_crypt(io); 527 kcryptd_queue_crypt(io);