diff options
Diffstat (limited to 'drivers/md/dm-io.c')
-rw-r--r-- | drivers/md/dm-io.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 3842ac738f98..db404a0f7e2c 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/device-mapper.h> | 10 | #include <linux/device-mapper.h> |
11 | 11 | ||
12 | #include <linux/bio.h> | 12 | #include <linux/bio.h> |
13 | #include <linux/completion.h> | ||
13 | #include <linux/mempool.h> | 14 | #include <linux/mempool.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
@@ -32,7 +33,7 @@ struct dm_io_client { | |||
32 | struct io { | 33 | struct io { |
33 | unsigned long error_bits; | 34 | unsigned long error_bits; |
34 | atomic_t count; | 35 | atomic_t count; |
35 | struct task_struct *sleeper; | 36 | struct completion *wait; |
36 | struct dm_io_client *client; | 37 | struct dm_io_client *client; |
37 | io_notify_fn callback; | 38 | io_notify_fn callback; |
38 | void *context; | 39 | void *context; |
@@ -121,8 +122,8 @@ static void dec_count(struct io *io, unsigned int region, int error) | |||
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); |
123 | 124 | ||
124 | if (io->sleeper) | 125 | if (io->wait) |
125 | wake_up_process(io->sleeper); | 126 | complete(io->wait); |
126 | 127 | ||
127 | else { | 128 | else { |
128 | unsigned long r = io->error_bits; | 129 | unsigned long r = io->error_bits; |
@@ -387,6 +388,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, | |||
387 | */ | 388 | */ |
388 | volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1]; | 389 | volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1]; |
389 | struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io)); | 390 | struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io)); |
391 | DECLARE_COMPLETION_ONSTACK(wait); | ||
390 | 392 | ||
391 | if (num_regions > 1 && (rw & RW_MASK) != WRITE) { | 393 | if (num_regions > 1 && (rw & RW_MASK) != WRITE) { |
392 | WARN_ON(1); | 394 | WARN_ON(1); |
@@ -395,7 +397,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, | |||
395 | 397 | ||
396 | io->error_bits = 0; | 398 | io->error_bits = 0; |
397 | atomic_set(&io->count, 1); /* see dispatch_io() */ | 399 | atomic_set(&io->count, 1); /* see dispatch_io() */ |
398 | io->sleeper = current; | 400 | io->wait = &wait; |
399 | io->client = client; | 401 | io->client = client; |
400 | 402 | ||
401 | io->vma_invalidate_address = dp->vma_invalidate_address; | 403 | io->vma_invalidate_address = dp->vma_invalidate_address; |
@@ -403,15 +405,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, | |||
403 | 405 | ||
404 | dispatch_io(rw, num_regions, where, dp, io, 1); | 406 | dispatch_io(rw, num_regions, where, dp, io, 1); |
405 | 407 | ||
406 | while (1) { | 408 | wait_for_completion_io(&wait); |
407 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
408 | |||
409 | if (!atomic_read(&io->count)) | ||
410 | break; | ||
411 | |||
412 | io_schedule(); | ||
413 | } | ||
414 | set_current_state(TASK_RUNNING); | ||
415 | 409 | ||
416 | if (error_bits) | 410 | if (error_bits) |
417 | *error_bits = io->error_bits; | 411 | *error_bits = io->error_bits; |
@@ -434,7 +428,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, | |||
434 | io = mempool_alloc(client->pool, GFP_NOIO); | 428 | io = mempool_alloc(client->pool, GFP_NOIO); |
435 | io->error_bits = 0; | 429 | io->error_bits = 0; |
436 | atomic_set(&io->count, 1); /* see dispatch_io() */ | 430 | atomic_set(&io->count, 1); /* see dispatch_io() */ |
437 | io->sleeper = NULL; | 431 | io->wait = NULL; |
438 | io->client = client; | 432 | io->client = client; |
439 | io->callback = fn; | 433 | io->callback = fn; |
440 | io->context = context; | 434 | io->context = context; |