aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-io.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index db404a0f7e2c..c09359db3a90 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -33,7 +33,6 @@ struct dm_io_client {
33struct io { 33struct io {
34 unsigned long error_bits; 34 unsigned long error_bits;
35 atomic_t count; 35 atomic_t count;
36 struct completion *wait;
37 struct dm_io_client *client; 36 struct dm_io_client *client;
38 io_notify_fn callback; 37 io_notify_fn callback;
39 void *context; 38 void *context;
@@ -112,28 +111,27 @@ static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io,
112 * We need an io object to keep track of the number of bios that 111 * We need an io object to keep track of the number of bios that
113 * have been dispatched for a particular io. 112 * have been dispatched for a particular io.
114 *---------------------------------------------------------------*/ 113 *---------------------------------------------------------------*/
115static void dec_count(struct io *io, unsigned int region, int error) 114static void complete_io(struct io *io)
116{ 115{
117 if (error) 116 unsigned long error_bits = io->error_bits;
118 set_bit(region, &io->error_bits); 117 io_notify_fn fn = io->callback;
118 void *context = io->context;
119 119
120 if (atomic_dec_and_test(&io->count)) { 120 if (io->vma_invalidate_size)
121 if (io->vma_invalidate_size) 121 invalidate_kernel_vmap_range(io->vma_invalidate_address,
122 invalidate_kernel_vmap_range(io->vma_invalidate_address, 122 io->vma_invalidate_size);
123 io->vma_invalidate_size);
124 123
125 if (io->wait) 124 mempool_free(io, io->client->pool);
126 complete(io->wait); 125 fn(error_bits, context);
126}
127 127
128 else { 128static void dec_count(struct io *io, unsigned int region, int error)
129 unsigned long r = io->error_bits; 129{
130 io_notify_fn fn = io->callback; 130 if (error)
131 void *context = io->context; 131 set_bit(region, &io->error_bits);
132 132
133 mempool_free(io, io->client->pool); 133 if (atomic_dec_and_test(&io->count))
134 fn(r, context); 134 complete_io(io);
135 }
136 }
137} 135}
138 136
139static void endio(struct bio *bio, int error) 137static void endio(struct bio *bio, int error)
@@ -376,41 +374,51 @@ static void dispatch_io(int rw, unsigned int num_regions,
376 dec_count(io, 0, 0); 374 dec_count(io, 0, 0);
377} 375}
378 376
377struct sync_io {
378 unsigned long error_bits;
379 struct completion wait;
380};
381
382static void sync_io_complete(unsigned long error, void *context)
383{
384 struct sync_io *sio = context;
385
386 sio->error_bits = error;
387 complete(&sio->wait);
388}
389
379static int sync_io(struct dm_io_client *client, unsigned int num_regions, 390static int sync_io(struct dm_io_client *client, unsigned int num_regions,
380 struct dm_io_region *where, int rw, struct dpages *dp, 391 struct dm_io_region *where, int rw, struct dpages *dp,
381 unsigned long *error_bits) 392 unsigned long *error_bits)
382{ 393{
383 /* 394 struct io *io;
384 * gcc <= 4.3 can't do the alignment for stack variables, so we must 395 struct sync_io sio;
385 * align it on our own.
386 * volatile prevents the optimizer from removing or reusing
387 * "io_" field from the stack frame (allowed in ANSI C).
388 */
389 volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1];
390 struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io));
391 DECLARE_COMPLETION_ONSTACK(wait);
392 396
393 if (num_regions > 1 && (rw & RW_MASK) != WRITE) { 397 if (num_regions > 1 && (rw & RW_MASK) != WRITE) {
394 WARN_ON(1); 398 WARN_ON(1);
395 return -EIO; 399 return -EIO;
396 } 400 }
397 401
402 init_completion(&sio.wait);
403
404 io = mempool_alloc(client->pool, GFP_NOIO);
398 io->error_bits = 0; 405 io->error_bits = 0;
399 atomic_set(&io->count, 1); /* see dispatch_io() */ 406 atomic_set(&io->count, 1); /* see dispatch_io() */
400 io->wait = &wait;
401 io->client = client; 407 io->client = client;
408 io->callback = sync_io_complete;
409 io->context = &sio;
402 410
403 io->vma_invalidate_address = dp->vma_invalidate_address; 411 io->vma_invalidate_address = dp->vma_invalidate_address;
404 io->vma_invalidate_size = dp->vma_invalidate_size; 412 io->vma_invalidate_size = dp->vma_invalidate_size;
405 413
406 dispatch_io(rw, num_regions, where, dp, io, 1); 414 dispatch_io(rw, num_regions, where, dp, io, 1);
407 415
408 wait_for_completion_io(&wait); 416 wait_for_completion_io(&sio.wait);
409 417
410 if (error_bits) 418 if (error_bits)
411 *error_bits = io->error_bits; 419 *error_bits = sio.error_bits;
412 420
413 return io->error_bits ? -EIO : 0; 421 return sio.error_bits ? -EIO : 0;
414} 422}
415 423
416static int async_io(struct dm_io_client *client, unsigned int num_regions, 424static int async_io(struct dm_io_client *client, unsigned int num_regions,
@@ -428,7 +436,6 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,
428 io = mempool_alloc(client->pool, GFP_NOIO); 436 io = mempool_alloc(client->pool, GFP_NOIO);
429 io->error_bits = 0; 437 io->error_bits = 0;
430 atomic_set(&io->count, 1); /* see dispatch_io() */ 438 atomic_set(&io->count, 1); /* see dispatch_io() */
431 io->wait = NULL;
432 io->client = client; 439 io->client = client;
433 io->callback = fn; 440 io->callback = fn;
434 io->context = context; 441 io->context = context;
@@ -481,9 +488,9 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp,
481 * New collapsed (a)synchronous interface. 488 * New collapsed (a)synchronous interface.
482 * 489 *
483 * If the IO is asynchronous (i.e. it has notify.fn), you must either unplug 490 * If the IO is asynchronous (i.e. it has notify.fn), you must either unplug
484 * the queue with blk_unplug() some time later or set REQ_SYNC in 491 * the queue with blk_unplug() some time later or set REQ_SYNC in io_req->bi_rw.
485io_req->bi_rw. If you fail to do one of these, the IO will be submitted to 492 * If you fail to do one of these, the IO will be submitted to the disk after
486 * the disk after q->unplug_delay, which defaults to 3ms in blk-settings.c. 493 * q->unplug_delay, which defaults to 3ms in blk-settings.c.
487 */ 494 */
488int dm_io(struct dm_io_request *io_req, unsigned num_regions, 495int dm_io(struct dm_io_request *io_req, unsigned num_regions,
489 struct dm_io_region *where, unsigned long *sync_error_bits) 496 struct dm_io_region *where, unsigned long *sync_error_bits)