diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-13 15:53:30 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-13 15:53:30 -0800 |
commit | 7e5b95f1baaabd93271c7b27b7e3c803a9aaa0dd (patch) | |
tree | e00de6d3a1c482b10fb4892bfed97eff1a9fff44 /drivers/md/dm.c | |
parent | 58e20d8d344b0ee083febb18c2b021d2427e56ca (diff) | |
parent | 8a57dfc6f943c92b861c9a19b0c86ddcb2aba768 (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:
dm: avoid destroying table in dm_any_congested
dm: move pending queue wake_up end_io_acct
dm mpath: warn if args ignored
dm mpath: avoid attempting to activate null path
dm stripe: fix init failure
dm raid1: flush workqueue before destruction
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6963ad14840..c99e4728ff4 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -375,7 +375,7 @@ static void start_io_acct(struct dm_io *io) dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); } -static int end_io_acct(struct dm_io *io) +static void end_io_acct(struct dm_io *io) { struct mapped_device *md = io->md; struct bio *bio = io->bio; @@ -391,7 +391,9 @@ static int end_io_acct(struct dm_io *io) dm_disk(md)->part0.in_flight = pending = atomic_dec_return(&md->pending); - return !pending; + /* nudge anyone waiting on suspend queue */ + if (!pending) + wake_up(&md->wait); } /* @@ -499,9 +501,7 @@ static void dec_pending(struct dm_io *io, int error) spin_unlock_irqrestore(&io->md->pushback_lock, flags); } - if (end_io_acct(io)) - /* nudge anyone waiting on suspend queue */ - wake_up(&io->md->wait); + end_io_acct(io); if (io->error != DM_ENDIO_REQUEUE) { blk_add_trace_bio(io->md->queue, io->bio, @@ -937,16 +937,24 @@ static void dm_unplug_all(struct request_queue *q) static int dm_any_congested(void *congested_data, int bdi_bits) { - int r; - struct mapped_device *md = (struct mapped_device *) congested_data; - struct dm_table *map = dm_get_table(md); + int r = bdi_bits; + struct mapped_device *md = congested_data; + struct dm_table *map; - if (!map || test_bit(DMF_BLOCK_IO, &md->flags)) - r = bdi_bits; - else - r = dm_table_any_congested(map, bdi_bits); + atomic_inc(&md->pending); + + if (!test_bit(DMF_BLOCK_IO, &md->flags)) { + map = dm_get_table(md); + if (map) { + r = dm_table_any_congested(map, bdi_bits); + dm_table_put(map); + } + } + + if (!atomic_dec_return(&md->pending)) + /* nudge anyone waiting on suspend queue */ + wake_up(&md->wait); - dm_table_put(map); return r; } |