diff options
| author | Milan Broz <mbroz@redhat.com> | 2008-02-07 21:10:30 -0500 |
|---|---|---|
| committer | Alasdair G Kergon <agk@redhat.com> | 2008-02-07 21:10:30 -0500 |
| commit | 46125c1c90882e17f856f1ba30440efea9135e80 (patch) | |
| tree | e1175d29ec1985a220bfb07c0d6fa6cc83c44f15 | |
| parent | 94d6351e147231b2c5a9512d69693ee8ac0c204d (diff) | |
dm: refactor dm_suspend completion wait
Move completion wait to separate function
Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
| -rw-r--r-- | drivers/md/dm.c | 43 |
1 files changed, 27 insertions, 16 deletions
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) | |||
| 1259 | } | 1259 | } |
| 1260 | EXPORT_SYMBOL_GPL(dm_put); | 1260 | EXPORT_SYMBOL_GPL(dm_put); |
| 1261 | 1261 | ||
| 1262 | static int dm_wait_for_completion(struct mapped_device *md) | ||
| 1263 | { | ||
| 1264 | int r = 0; | ||
| 1265 | |||
| 1266 | while (1) { | ||
| 1267 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1268 | |||
| 1269 | smp_mb(); | ||
| 1270 | if (!atomic_read(&md->pending)) | ||
| 1271 | break; | ||
| 1272 | |||
| 1273 | if (signal_pending(current)) { | ||
| 1274 | r = -EINTR; | ||
| 1275 | break; | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | io_schedule(); | ||
| 1279 | } | ||
| 1280 | set_current_state(TASK_RUNNING); | ||
| 1281 | |||
| 1282 | return r; | ||
| 1283 | } | ||
| 1284 | |||
| 1262 | /* | 1285 | /* |
| 1263 | * Process the deferred bios | 1286 | * Process the deferred bios |
| 1264 | */ | 1287 | */ |
| @@ -1357,7 +1380,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
| 1357 | { | 1380 | { |
| 1358 | struct dm_table *map = NULL; | 1381 | struct dm_table *map = NULL; |
| 1359 | DECLARE_WAITQUEUE(wait, current); | 1382 | DECLARE_WAITQUEUE(wait, current); |
| 1360 | int pending, r = 0; | 1383 | int r = 0; |
| 1361 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; | 1384 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; |
| 1362 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; | 1385 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; |
| 1363 | 1386 | ||
| @@ -1414,20 +1437,9 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
| 1414 | dm_table_unplug_all(map); | 1437 | dm_table_unplug_all(map); |
| 1415 | 1438 | ||
| 1416 | /* | 1439 | /* |
| 1417 | * Then we wait for the already mapped ios to | 1440 | * Wait for the already-mapped ios to complete. |
| 1418 | * complete. | ||
| 1419 | */ | 1441 | */ |
| 1420 | while (1) { | 1442 | r = dm_wait_for_completion(md); |
| 1421 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1422 | |||
| 1423 | smp_mb(); | ||
| 1424 | pending = atomic_read(&md->pending); | ||
| 1425 | if (!pending || signal_pending(current)) | ||
| 1426 | break; | ||
| 1427 | |||
| 1428 | io_schedule(); | ||
| 1429 | } | ||
| 1430 | set_current_state(TASK_RUNNING); | ||
| 1431 | 1443 | ||
| 1432 | down_write(&md->io_lock); | 1444 | down_write(&md->io_lock); |
| 1433 | remove_wait_queue(&md->wait, &wait); | 1445 | remove_wait_queue(&md->wait, &wait); |
| @@ -1437,13 +1449,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
| 1437 | up_write(&md->io_lock); | 1449 | up_write(&md->io_lock); |
| 1438 | 1450 | ||
| 1439 | /* were we interrupted ? */ | 1451 | /* were we interrupted ? */ |
| 1440 | if (pending) { | 1452 | if (r < 0) { |
| 1441 | down_write(&md->io_lock); | 1453 | down_write(&md->io_lock); |
| 1442 | __flush_deferred_io(md); | 1454 | __flush_deferred_io(md); |
| 1443 | up_write(&md->io_lock); | 1455 | up_write(&md->io_lock); |
| 1444 | 1456 | ||
| 1445 | unlock_fs(md); | 1457 | unlock_fs(md); |
| 1446 | r = -EINTR; | ||
| 1447 | goto out; /* pushback list is already flushed, so skip flush */ | 1458 | goto out; /* pushback list is already flushed, so skip flush */ |
| 1448 | } | 1459 | } |
| 1449 | 1460 | ||
