|
@@ -398,7 +398,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
|
|
struct bio *clone;
|
|
struct bio *clone;
|
|
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
|
|
gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
|
|
- unsigned int i;
|
|
|
|
|
|
+ unsigned i, len;
|
|
|
|
+ struct page *page;
|
|
|
|
|
|
clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
|
|
clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
|
|
if (!clone)
|
|
if (!clone)
|
|
@@ -407,10 +408,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
|
|
clone_init(io, clone);
|
|
clone_init(io, clone);
|
|
|
|
|
|
for (i = 0; i < nr_iovecs; i++) {
|
|
for (i = 0; i < nr_iovecs; i++) {
|
|
- struct bio_vec *bv = bio_iovec_idx(clone, i);
|
|
|
|
-
|
|
|
|
- bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
|
|
|
|
- if (!bv->bv_page)
|
|
|
|
|
|
+ page = mempool_alloc(cc->page_pool, gfp_mask);
|
|
|
|
+ if (!page)
|
|
break;
|
|
break;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -421,15 +420,14 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
|
|
if (i == (MIN_BIO_PAGES - 1))
|
|
if (i == (MIN_BIO_PAGES - 1))
|
|
gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
|
|
gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
|
|
|
|
|
|
- bv->bv_offset = 0;
|
|
|
|
- if (size > PAGE_SIZE)
|
|
|
|
- bv->bv_len = PAGE_SIZE;
|
|
|
|
- else
|
|
|
|
- bv->bv_len = size;
|
|
|
|
|
|
+ len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
|
|
|
|
+
|
|
|
|
+ if (!bio_add_page(clone, page, len, 0)) {
|
|
|
|
+ mempool_free(page, cc->page_pool);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- clone->bi_size += bv->bv_len;
|
|
|
|
- clone->bi_vcnt++;
|
|
|
|
- size -= bv->bv_len;
|
|
|
|
|
|
+ size -= len;
|
|
}
|
|
}
|
|
|
|
|
|
if (!clone->bi_size) {
|
|
if (!clone->bi_size) {
|