diff options
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r-- | drivers/md/dm-crypt.c | 31 |
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); |