aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-io.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:33:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:33:49 -0400
commit6f97b220f414e3599ea5374905ba6d0dc47d63b0 (patch)
tree79b268ea6efcd417d923fdbc1aed7bc0fce15554 /drivers/md/dm-io.c
parent4b7227ca321ccf447cdc04538687c895db8b77f5 (diff)
parente3dcc5a387fc38e9c3c6c4f857cd9a7f71a8553a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
* git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm: (24 commits) dm crypt: add documentation dm: remove md argument from specific_minor dm table: remove unused dm_create_error_table dm table: drop void suspend_targets return dm: unplug queues in threads dm raid1: use timer dm: move include files dm kcopyd: rename dm: expose macros dm kcopyd: remove redundant client counting dm kcopyd: private mempool dm kcopyd: per device dm log: make module use tracking internal dm log: move register functions dm log: clean interface dm kcopyd: clean interface dm io: clean interface dm io: rename error to error_bits dm snapshot: store pointer to target instance dm log: move dirty region log code into separate module ...
Diffstat (limited to 'drivers/md/dm-io.c')
-rw-r--r--drivers/md/dm-io.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 8f25f628ef16..4789c42d9a3a 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -5,13 +5,14 @@
5 * This file is released under the GPL. 5 * This file is released under the GPL.
6 */ 6 */
7 7
8#include "dm-io.h" 8#include "dm.h"
9 9
10#include <linux/bio.h> 10#include <linux/bio.h>
11#include <linux/mempool.h> 11#include <linux/mempool.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/dm-io.h>
15 16
16struct dm_io_client { 17struct dm_io_client {
17 mempool_t *pool; 18 mempool_t *pool;
@@ -20,7 +21,7 @@ struct dm_io_client {
20 21
21/* FIXME: can we shrink this ? */ 22/* FIXME: can we shrink this ? */
22struct io { 23struct io {
23 unsigned long error; 24 unsigned long error_bits;
24 atomic_t count; 25 atomic_t count;
25 struct task_struct *sleeper; 26 struct task_struct *sleeper;
26 struct dm_io_client *client; 27 struct dm_io_client *client;
@@ -107,14 +108,14 @@ static inline unsigned bio_get_region(struct bio *bio)
107static void dec_count(struct io *io, unsigned int region, int error) 108static void dec_count(struct io *io, unsigned int region, int error)
108{ 109{
109 if (error) 110 if (error)
110 set_bit(region, &io->error); 111 set_bit(region, &io->error_bits);
111 112
112 if (atomic_dec_and_test(&io->count)) { 113 if (atomic_dec_and_test(&io->count)) {
113 if (io->sleeper) 114 if (io->sleeper)
114 wake_up_process(io->sleeper); 115 wake_up_process(io->sleeper);
115 116
116 else { 117 else {
117 unsigned long r = io->error; 118 unsigned long r = io->error_bits;
118 io_notify_fn fn = io->callback; 119 io_notify_fn fn = io->callback;
119 void *context = io->context; 120 void *context = io->context;
120 121
@@ -271,7 +272,7 @@ static void km_dp_init(struct dpages *dp, void *data)
271/*----------------------------------------------------------------- 272/*-----------------------------------------------------------------
272 * IO routines that accept a list of pages. 273 * IO routines that accept a list of pages.
273 *---------------------------------------------------------------*/ 274 *---------------------------------------------------------------*/
274static void do_region(int rw, unsigned int region, struct io_region *where, 275static void do_region(int rw, unsigned region, struct dm_io_region *where,
275 struct dpages *dp, struct io *io) 276 struct dpages *dp, struct io *io)
276{ 277{
277 struct bio *bio; 278 struct bio *bio;
@@ -320,7 +321,7 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
320} 321}
321 322
322static void dispatch_io(int rw, unsigned int num_regions, 323static void dispatch_io(int rw, unsigned int num_regions,
323 struct io_region *where, struct dpages *dp, 324 struct dm_io_region *where, struct dpages *dp,
324 struct io *io, int sync) 325 struct io *io, int sync)
325{ 326{
326 int i; 327 int i;
@@ -347,17 +348,17 @@ static void dispatch_io(int rw, unsigned int num_regions,
347} 348}
348 349
349static int sync_io(struct dm_io_client *client, unsigned int num_regions, 350static int sync_io(struct dm_io_client *client, unsigned int num_regions,
350 struct io_region *where, int rw, struct dpages *dp, 351 struct dm_io_region *where, int rw, struct dpages *dp,
351 unsigned long *error_bits) 352 unsigned long *error_bits)
352{ 353{
353 struct io io; 354 struct io io;
354 355
355 if (num_regions > 1 && rw != WRITE) { 356 if (num_regions > 1 && (rw & RW_MASK) != WRITE) {
356 WARN_ON(1); 357 WARN_ON(1);
357 return -EIO; 358 return -EIO;
358 } 359 }
359 360
360 io.error = 0; 361 io.error_bits = 0;
361 atomic_set(&io.count, 1); /* see dispatch_io() */ 362 atomic_set(&io.count, 1); /* see dispatch_io() */
362 io.sleeper = current; 363 io.sleeper = current;
363 io.client = client; 364 io.client = client;
@@ -378,25 +379,25 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
378 return -EINTR; 379 return -EINTR;
379 380
380 if (error_bits) 381 if (error_bits)
381 *error_bits = io.error; 382 *error_bits = io.error_bits;
382 383
383 return io.error ? -EIO : 0; 384 return io.error_bits ? -EIO : 0;
384} 385}
385 386
386static int async_io(struct dm_io_client *client, unsigned int num_regions, 387static int async_io(struct dm_io_client *client, unsigned int num_regions,
387 struct io_region *where, int rw, struct dpages *dp, 388 struct dm_io_region *where, int rw, struct dpages *dp,
388 io_notify_fn fn, void *context) 389 io_notify_fn fn, void *context)
389{ 390{
390 struct io *io; 391 struct io *io;
391 392
392 if (num_regions > 1 && rw != WRITE) { 393 if (num_regions > 1 && (rw & RW_MASK) != WRITE) {
393 WARN_ON(1); 394 WARN_ON(1);
394 fn(1, context); 395 fn(1, context);
395 return -EIO; 396 return -EIO;
396 } 397 }
397 398
398 io = mempool_alloc(client->pool, GFP_NOIO); 399 io = mempool_alloc(client->pool, GFP_NOIO);
399 io->error = 0; 400 io->error_bits = 0;
400 atomic_set(&io->count, 1); /* see dispatch_io() */ 401 atomic_set(&io->count, 1); /* see dispatch_io() */
401 io->sleeper = NULL; 402 io->sleeper = NULL;
402 io->client = client; 403 io->client = client;
@@ -435,10 +436,15 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp)
435} 436}
436 437
437/* 438/*
438 * New collapsed (a)synchronous interface 439 * New collapsed (a)synchronous interface.
440 *
441 * If the IO is asynchronous (i.e. it has notify.fn), you must either unplug
442 * the queue with blk_unplug() some time later or set the BIO_RW_SYNC bit in
443 * io_req->bi_rw. If you fail to do one of these, the IO will be submitted to
444 * the disk after q->unplug_delay, which defaults to 3ms in blk-settings.c.
439 */ 445 */
440int dm_io(struct dm_io_request *io_req, unsigned num_regions, 446int dm_io(struct dm_io_request *io_req, unsigned num_regions,
441 struct io_region *where, unsigned long *sync_error_bits) 447 struct dm_io_region *where, unsigned long *sync_error_bits)
442{ 448{
443 int r; 449 int r;
444 struct dpages dp; 450 struct dpages dp;