From 7e5c1e830b2310359a4cfbbf89895dde4abd996a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:09:49 +0000 Subject: dm: add missing memory barrier to dm_suspend Add memory barrier to fix atomic_read of pending value. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f2d24eb3208c..466a6bf0742f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1410,6 +1410,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) while (1) { set_current_state(TASK_INTERRUPTIBLE); + smp_mb(); if (!atomic_read(&md->pending) || signal_pending(current)) break; -- cgit v1.2.2 From b9249e556877643b940e4543824a3de5c85bce49 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Fri, 8 Feb 2008 02:09:51 +0000 Subject: dm: mark function lists static Add a couple of statics. Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 466a6bf0742f..5f0f559d3b92 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -181,7 +181,7 @@ static void local_exit(void) DMINFO("cleaned up"); } -int (*_inits[])(void) __initdata = { +static int (*_inits[])(void) __initdata = { local_init, dm_target_init, dm_linear_init, @@ -189,7 +189,7 @@ int (*_inits[])(void) __initdata = { dm_interface_init, }; -void (*_exits[])(void) = { +static void (*_exits[])(void) = { local_exit, dm_target_exit, dm_linear_exit, -- cgit v1.2.2 From e61290a4a23c3f85f883f0c8cc7c967501f82a57 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 8 Feb 2008 02:10:08 +0000 Subject: dm: convert suspend_lock semaphore to mutex Replace semaphore with mutex. Signed-off-by: Daniel Walker Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 5f0f559d3b92..d16bb5b80789 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -73,7 +73,7 @@ union map_info *dm_get_mapinfo(struct bio *bio) struct mapped_device { struct rw_semaphore io_lock; - struct semaphore suspend_lock; + struct mutex suspend_lock; spinlock_t pushback_lock; rwlock_t map_lock; atomic_t holders; @@ -994,7 +994,7 @@ static struct mapped_device *alloc_dev(int minor) memset(md, 0, sizeof(*md)); init_rwsem(&md->io_lock); - init_MUTEX(&md->suspend_lock); + mutex_init(&md->suspend_lock); spin_lock_init(&md->pushback_lock); rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); @@ -1282,7 +1282,7 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) { int r = -EINVAL; - down(&md->suspend_lock); + mutex_lock(&md->suspend_lock); /* device must be suspended */ if (!dm_suspended(md)) @@ -1297,7 +1297,7 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) r = __bind(md, table); out: - up(&md->suspend_lock); + mutex_unlock(&md->suspend_lock); return r; } @@ -1353,7 +1353,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; - down(&md->suspend_lock); + mutex_lock(&md->suspend_lock); if (dm_suspended(md)) goto out_unlock; @@ -1475,7 +1475,7 @@ out: dm_table_put(map); out_unlock: - up(&md->suspend_lock); + mutex_unlock(&md->suspend_lock); return r; } @@ -1485,7 +1485,7 @@ int dm_resume(struct mapped_device *md) struct bio *def; struct dm_table *map = NULL; - down(&md->suspend_lock); + mutex_lock(&md->suspend_lock); if (!dm_suspended(md)) goto out; @@ -1521,7 +1521,7 @@ int dm_resume(struct mapped_device *md) out: dm_table_put(map); - up(&md->suspend_lock); + mutex_unlock(&md->suspend_lock); return r; } -- cgit v1.2.2 From 6ed7ade89657e71da3afa7cb13ad25570a95dd9d Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:10:19 +0000 Subject: dm: tidy alloc_dev labels Tidy labels in alloc_dev to make later patches more clear. No functional change in this patch. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d16bb5b80789..52427e15189b 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -982,7 +982,7 @@ static struct mapped_device *alloc_dev(int minor) } if (!try_module_get(THIS_MODULE)) - goto bad0; + goto bad_module_get; /* get a minor number for the dev */ if (minor == DM_ANY_MINOR) @@ -990,7 +990,7 @@ static struct mapped_device *alloc_dev(int minor) else r = specific_minor(md, minor); if (r < 0) - goto bad1; + goto bad_minor; memset(md, 0, sizeof(*md)); init_rwsem(&md->io_lock); @@ -1006,7 +1006,7 @@ static struct mapped_device *alloc_dev(int minor) md->queue = blk_alloc_queue(GFP_KERNEL); if (!md->queue) - goto bad1_free_minor; + goto bad_queue; md->queue->queuedata = md; md->queue->backing_dev_info.congested_fn = dm_any_congested; @@ -1017,11 +1017,11 @@ static struct mapped_device *alloc_dev(int minor) md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); if (!md->io_pool) - goto bad2; + goto bad_io_pool; md->tio_pool = mempool_create_slab_pool(MIN_IOS, _tio_cache); if (!md->tio_pool) - goto bad3; + goto bad_tio_pool; md->bs = bioset_create(16, 16); if (!md->bs) @@ -1029,7 +1029,7 @@ static struct mapped_device *alloc_dev(int minor) md->disk = alloc_disk(1); if (!md->disk) - goto bad4; + goto bad_disk; atomic_set(&md->pending, 0); init_waitqueue_head(&md->wait); @@ -1053,19 +1053,19 @@ static struct mapped_device *alloc_dev(int minor) return md; - bad4: +bad_disk: bioset_free(md->bs); - bad_no_bioset: +bad_no_bioset: mempool_destroy(md->tio_pool); - bad3: +bad_tio_pool: mempool_destroy(md->io_pool); - bad2: +bad_io_pool: blk_cleanup_queue(md->queue); - bad1_free_minor: +bad_queue: free_minor(minor); - bad1: +bad_minor: module_put(THIS_MODULE); - bad0: +bad_module_get: kfree(md); return NULL; } -- cgit v1.2.2 From 6d6f10df890df8be69edd4db32dc8ce09f311bb8 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:10:22 +0000 Subject: dm: refactor deferred bio_list processing Refactor deferred bio_list processing. - use separate _merge_pushback_list function - move deferred bio list pick up to flush function - use bio_list_pop instead of bio_list_get - simplify noflush flag use No real functional change in this patch. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 67 +++++++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 38 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 52427e15189b..c1ad7d77dbcd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1262,19 +1262,27 @@ EXPORT_SYMBOL_GPL(dm_put); /* * Process the deferred bios */ -static void __flush_deferred_io(struct mapped_device *md, struct bio *c) +static void __flush_deferred_io(struct mapped_device *md) { - struct bio *n; + struct bio *c; - while (c) { - n = c->bi_next; - c->bi_next = NULL; + while ((c = bio_list_pop(&md->deferred))) { if (__split_bio(md, c)) bio_io_error(c); - c = n; } } +static void __merge_pushback_list(struct mapped_device *md) +{ + unsigned long flags; + + spin_lock_irqsave(&md->pushback_lock, flags); + clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); + bio_list_merge_head(&md->deferred, &md->pushback); + bio_list_init(&md->pushback); + spin_unlock_irqrestore(&md->pushback_lock, flags); +} + /* * Swap in a new table (destroying old one). */ @@ -1346,9 +1354,7 @@ static void unlock_fs(struct mapped_device *md) int dm_suspend(struct mapped_device *md, unsigned suspend_flags) { struct dm_table *map = NULL; - unsigned long flags; DECLARE_WAITQUEUE(wait, current); - struct bio *def; int r = -EINVAL; int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; @@ -1378,16 +1384,16 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) r = -ENOMEM; goto flush_and_out; } - } - /* - * Flush I/O to the device. - * noflush supersedes do_lockfs, because lock_fs() needs to flush I/Os. - */ - if (do_lockfs && !noflush) { - r = lock_fs(md); - if (r) - goto out; + /* + * Flush I/O to the device. noflush supersedes do_lockfs, + * because lock_fs() needs to flush I/Os. + */ + if (do_lockfs) { + r = lock_fs(md); + if (r) + goto out; + } } /* @@ -1421,20 +1427,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) down_write(&md->io_lock); remove_wait_queue(&md->wait, &wait); - if (noflush) { - spin_lock_irqsave(&md->pushback_lock, flags); - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); - bio_list_merge_head(&md->deferred, &md->pushback); - bio_list_init(&md->pushback); - spin_unlock_irqrestore(&md->pushback_lock, flags); - } + if (noflush) + __merge_pushback_list(md); /* were we interrupted ? */ r = -EINTR; if (atomic_read(&md->pending)) { clear_bit(DMF_BLOCK_IO, &md->flags); - def = bio_list_get(&md->deferred); - __flush_deferred_io(md, def); + __flush_deferred_io(md); up_write(&md->io_lock); unlock_fs(md); goto out; /* pushback list is already flushed, so skip flush */ @@ -1454,15 +1454,8 @@ flush_and_out: * flush them before return. */ down_write(&md->io_lock); - - spin_lock_irqsave(&md->pushback_lock, flags); - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); - bio_list_merge_head(&md->deferred, &md->pushback); - bio_list_init(&md->pushback); - spin_unlock_irqrestore(&md->pushback_lock, flags); - - def = bio_list_get(&md->deferred); - __flush_deferred_io(md, def); + __merge_pushback_list(md); + __flush_deferred_io(md); up_write(&md->io_lock); } @@ -1482,7 +1475,6 @@ out_unlock: int dm_resume(struct mapped_device *md) { int r = -EINVAL; - struct bio *def; struct dm_table *map = NULL; mutex_lock(&md->suspend_lock); @@ -1500,8 +1492,7 @@ int dm_resume(struct mapped_device *md) down_write(&md->io_lock); clear_bit(DMF_BLOCK_IO, &md->flags); - def = bio_list_get(&md->deferred); - __flush_deferred_io(md, def); + __flush_deferred_io(md); up_write(&md->io_lock); unlock_fs(md); -- cgit v1.2.2 From 73d410c0137f63c6597e9763c81e5f4d015e9940 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:10:25 +0000 Subject: dm: tidy dm_suspend Tidy dm_suspend function - change return value logic in dm_suspend - use atomic_read only once. - move DMF_BLOCK_IO clearing into one place Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c1ad7d77dbcd..5191954a18b2 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1270,6 +1270,8 @@ static void __flush_deferred_io(struct mapped_device *md) if (__split_bio(md, c)) bio_io_error(c); } + + clear_bit(DMF_BLOCK_IO, &md->flags); } static void __merge_pushback_list(struct mapped_device *md) @@ -1355,14 +1357,16 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) { struct dm_table *map = NULL; DECLARE_WAITQUEUE(wait, current); - int r = -EINVAL; + int pending, r = 0; int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; mutex_lock(&md->suspend_lock); - if (dm_suspended(md)) + if (dm_suspended(md)) { + r = -EINVAL; goto out_unlock; + } map = dm_get_table(md); @@ -1417,7 +1421,8 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) set_current_state(TASK_INTERRUPTIBLE); smp_mb(); - if (!atomic_read(&md->pending) || signal_pending(current)) + pending = atomic_read(&md->pending); + if (!pending || signal_pending(current)) break; io_schedule(); @@ -1431,12 +1436,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) __merge_pushback_list(md); /* were we interrupted ? */ - r = -EINTR; - if (atomic_read(&md->pending)) { - clear_bit(DMF_BLOCK_IO, &md->flags); + if (pending) { __flush_deferred_io(md); up_write(&md->io_lock); + unlock_fs(md); + r = -EINTR; goto out; /* pushback list is already flushed, so skip flush */ } up_write(&md->io_lock); @@ -1445,8 +1450,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) set_bit(DMF_SUSPENDED, &md->flags); - r = 0; - flush_and_out: if (r && noflush) { /* @@ -1490,8 +1493,6 @@ int dm_resume(struct mapped_device *md) goto out; down_write(&md->io_lock); - clear_bit(DMF_BLOCK_IO, &md->flags); - __flush_deferred_io(md); up_write(&md->io_lock); -- cgit v1.2.2 From 94d6351e147231b2c5a9512d69693ee8ac0c204d Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:10:27 +0000 Subject: dm: split dm_suspend io_lock hold into two Change io_locking to allow processing flush in separate thread. Because we have DMF_BLOCK_IO already set, any possible new ios are queued in dm_requests now. In the case of interrupting previous wait there can be more ios queued (we unlocked io_lock for a while) but this is safe. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 5191954a18b2..11f422ecfda0 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1434,9 +1434,11 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) if (noflush) __merge_pushback_list(md); + up_write(&md->io_lock); /* were we interrupted ? */ if (pending) { + down_write(&md->io_lock); __flush_deferred_io(md); up_write(&md->io_lock); @@ -1444,7 +1446,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) r = -EINTR; goto out; /* pushback list is already flushed, so skip flush */ } - up_write(&md->io_lock); dm_table_postsuspend_targets(map); -- cgit v1.2.2 From 46125c1c90882e17f856f1ba30440efea9135e80 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:10:30 +0000 Subject: dm: refactor dm_suspend completion wait Move completion wait to separate function Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 11f422ecfda0..9ca012e639a8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1259,6 +1259,29 @@ void dm_put(struct mapped_device *md) } EXPORT_SYMBOL_GPL(dm_put); +static int dm_wait_for_completion(struct mapped_device *md) +{ + int r = 0; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + smp_mb(); + if (!atomic_read(&md->pending)) + break; + + if (signal_pending(current)) { + r = -EINTR; + break; + } + + io_schedule(); + } + set_current_state(TASK_RUNNING); + + return r; +} + /* * Process the deferred bios */ @@ -1357,7 +1380,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) { struct dm_table *map = NULL; DECLARE_WAITQUEUE(wait, current); - int pending, r = 0; + int r = 0; int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; @@ -1414,20 +1437,9 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) dm_table_unplug_all(map); /* - * Then we wait for the already mapped ios to - * complete. + * Wait for the already-mapped ios to complete. */ - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - - smp_mb(); - pending = atomic_read(&md->pending); - if (!pending || signal_pending(current)) - break; - - io_schedule(); - } - set_current_state(TASK_RUNNING); + r = dm_wait_for_completion(md); down_write(&md->io_lock); remove_wait_queue(&md->wait, &wait); @@ -1437,13 +1449,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) up_write(&md->io_lock); /* were we interrupted ? */ - if (pending) { + if (r < 0) { down_write(&md->io_lock); __flush_deferred_io(md); up_write(&md->io_lock); unlock_fs(md); - r = -EINTR; goto out; /* pushback list is already flushed, so skip flush */ } -- cgit v1.2.2 From 304f3f6a58301316da612d7bf21d9abe1369d456 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Feb 2008 02:11:17 +0000 Subject: dm: move deferred bio flushing to workqueue Add a single-thread workqueue for each mapped device and move flushing of the lists of pushback and deferred bios to this new workqueue. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'drivers/md/dm.c') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9ca012e639a8..6617ce4af095 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -71,6 +71,19 @@ union map_info *dm_get_mapinfo(struct bio *bio) #define DMF_DELETING 4 #define DMF_NOFLUSH_SUSPENDING 5 +/* + * Work processed by per-device workqueue. + */ +struct dm_wq_req { + enum { + DM_WQ_FLUSH_ALL, + DM_WQ_FLUSH_DEFERRED, + } type; + struct work_struct work; + struct mapped_device *md; + void *context; +}; + struct mapped_device { struct rw_semaphore io_lock; struct mutex suspend_lock; @@ -95,6 +108,11 @@ struct mapped_device { struct bio_list deferred; struct bio_list pushback; + /* + * Processing queue (flush/barriers) + */ + struct workqueue_struct *wq; + /* * The current mapping. */ @@ -1044,6 +1062,10 @@ static struct mapped_device *alloc_dev(int minor) add_disk(md->disk); format_dev_t(md->name, MKDEV(_major, minor)); + md->wq = create_singlethread_workqueue("kdmflush"); + if (!md->wq) + goto bad_thread; + /* Populate the mapping, nobody knows we exist yet */ spin_lock(&_minor_lock); old_md = idr_replace(&_minor_idr, md, minor); @@ -1053,6 +1075,8 @@ static struct mapped_device *alloc_dev(int minor) return md; +bad_thread: + put_disk(md->disk); bad_disk: bioset_free(md->bs); bad_no_bioset: @@ -1080,6 +1104,7 @@ static void free_dev(struct mapped_device *md) unlock_fs(md); bdput(md->suspended_bdev); } + destroy_workqueue(md->wq); mempool_destroy(md->tio_pool); mempool_destroy(md->io_pool); bioset_free(md->bs); @@ -1308,6 +1333,44 @@ static void __merge_pushback_list(struct mapped_device *md) spin_unlock_irqrestore(&md->pushback_lock, flags); } +static void dm_wq_work(struct work_struct *work) +{ + struct dm_wq_req *req = container_of(work, struct dm_wq_req, work); + struct mapped_device *md = req->md; + + down_write(&md->io_lock); + switch (req->type) { + case DM_WQ_FLUSH_ALL: + __merge_pushback_list(md); + /* pass through */ + case DM_WQ_FLUSH_DEFERRED: + __flush_deferred_io(md); + break; + default: + DMERR("dm_wq_work: unrecognised work type %d", req->type); + BUG(); + } + up_write(&md->io_lock); +} + +static void dm_wq_queue(struct mapped_device *md, int type, void *context, + struct dm_wq_req *req) +{ + req->type = type; + req->md = md; + req->context = context; + INIT_WORK(&req->work, dm_wq_work); + queue_work(md->wq, &req->work); +} + +static void dm_queue_flush(struct mapped_device *md, int type, void *context) +{ + struct dm_wq_req req; + + dm_wq_queue(md, type, context, &req); + flush_workqueue(md->wq); +} + /* * Swap in a new table (destroying old one). */ @@ -1450,9 +1513,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) /* were we interrupted ? */ if (r < 0) { - down_write(&md->io_lock); - __flush_deferred_io(md); - up_write(&md->io_lock); + dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL); unlock_fs(md); goto out; /* pushback list is already flushed, so skip flush */ @@ -1463,16 +1524,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) set_bit(DMF_SUSPENDED, &md->flags); flush_and_out: - if (r && noflush) { + if (r && noflush) /* * Because there may be already I/Os in the pushback list, * flush them before return. */ - down_write(&md->io_lock); - __merge_pushback_list(md); - __flush_deferred_io(md); - up_write(&md->io_lock); - } + dm_queue_flush(md, DM_WQ_FLUSH_ALL, NULL); out: if (r && md->suspended_bdev) { @@ -1504,9 +1561,7 @@ int dm_resume(struct mapped_device *md) if (r) goto out; - down_write(&md->io_lock); - __flush_deferred_io(md); - up_write(&md->io_lock); + dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL); unlock_fs(md); -- cgit v1.2.2