diff options
Diffstat (limited to 'drivers/md/dm-io.c')
| -rw-r--r-- | drivers/md/dm-io.c | 56 | 
1 files changed, 26 insertions, 30 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 2a20986a2fe..db404a0f7e2 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -10,6 +10,7 @@  #include <linux/device-mapper.h>  #include <linux/bio.h> +#include <linux/completion.h>  #include <linux/mempool.h>  #include <linux/module.h>  #include <linux/sched.h> @@ -32,7 +33,7 @@ struct dm_io_client {  struct io {  	unsigned long error_bits;  	atomic_t count; -	struct task_struct *sleeper; +	struct completion *wait;  	struct dm_io_client *client;  	io_notify_fn callback;  	void *context; @@ -121,8 +122,8 @@ static void dec_count(struct io *io, unsigned int region, int error)  			invalidate_kernel_vmap_range(io->vma_invalidate_address,  						     io->vma_invalidate_size); -		if (io->sleeper) -			wake_up_process(io->sleeper); +		if (io->wait) +			complete(io->wait);  		else {  			unsigned long r = io->error_bits; @@ -201,26 +202,28 @@ static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offse  /*   * Functions for getting the pages from a bvec.   */ -static void bvec_get_page(struct dpages *dp, -		  struct page **p, unsigned long *len, unsigned *offset) +static void bio_get_page(struct dpages *dp, struct page **p, +			 unsigned long *len, unsigned *offset)  { -	struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr; +	struct bio_vec *bvec = dp->context_ptr;  	*p = bvec->bv_page; -	*len = bvec->bv_len; -	*offset = bvec->bv_offset; +	*len = bvec->bv_len - dp->context_u; +	*offset = bvec->bv_offset + dp->context_u;  } -static void bvec_next_page(struct dpages *dp) +static void bio_next_page(struct dpages *dp)  { -	struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr; +	struct bio_vec *bvec = dp->context_ptr;  	dp->context_ptr = bvec + 1; +	dp->context_u = 0;  } -static void bvec_dp_init(struct dpages *dp, struct bio_vec *bvec) +static void bio_dp_init(struct dpages *dp, struct bio *bio)  { -	dp->get_page = bvec_get_page; -	dp->next_page = bvec_next_page; -	dp->context_ptr = bvec; +	dp->get_page = bio_get_page; +	dp->next_page = bio_next_page; +	dp->context_ptr = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); +	dp->context_u = bio->bi_iter.bi_bvec_done;  }  /* @@ -304,14 +307,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,  					  dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT)));  		bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); -		bio->bi_sector = where->sector + (where->count - remaining); +		bio->bi_iter.bi_sector = where->sector + (where->count - remaining);  		bio->bi_bdev = where->bdev;  		bio->bi_end_io = endio;  		store_io_and_region_in_bio(bio, io, region);  		if (rw & REQ_DISCARD) {  			num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); -			bio->bi_size = num_sectors << SECTOR_SHIFT; +			bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;  			remaining -= num_sectors;  		} else if (rw & REQ_WRITE_SAME) {  			/* @@ -320,7 +323,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,  			dp->get_page(dp, &page, &len, &offset);  			bio_add_page(bio, page, logical_block_size, offset);  			num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining); -			bio->bi_size = num_sectors << SECTOR_SHIFT; +			bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;  			offset = 0;  			remaining -= num_sectors; @@ -385,6 +388,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,  	 */  	volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1];  	struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io)); +	DECLARE_COMPLETION_ONSTACK(wait);  	if (num_regions > 1 && (rw & RW_MASK) != WRITE) {  		WARN_ON(1); @@ -393,7 +397,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,  	io->error_bits = 0;  	atomic_set(&io->count, 1); /* see dispatch_io() */ -	io->sleeper = current; +	io->wait = &wait;  	io->client = client;  	io->vma_invalidate_address = dp->vma_invalidate_address; @@ -401,15 +405,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,  	dispatch_io(rw, num_regions, where, dp, io, 1); -	while (1) { -		set_current_state(TASK_UNINTERRUPTIBLE); - -		if (!atomic_read(&io->count)) -			break; - -		io_schedule(); -	} -	set_current_state(TASK_RUNNING); +	wait_for_completion_io(&wait);  	if (error_bits)  		*error_bits = io->error_bits; @@ -432,7 +428,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,  	io = mempool_alloc(client->pool, GFP_NOIO);  	io->error_bits = 0;  	atomic_set(&io->count, 1); /* see dispatch_io() */ -	io->sleeper = NULL; +	io->wait = NULL;  	io->client = client;  	io->callback = fn;  	io->context = context; @@ -457,8 +453,8 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp,  		list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset);  		break; -	case DM_IO_BVEC: -		bvec_dp_init(dp, io_req->mem.ptr.bvec); +	case DM_IO_BIO: +		bio_dp_init(dp, io_req->mem.ptr.bio);  		break;  	case DM_IO_VMA:  | 
