Split target suspend hook into presuspend and postsuspend. --- diff/drivers/md/dm-mpath.c 2004-11-10 15:14:02.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2004-11-10 15:14:08.000000000 +0000 @@ -1010,7 +1010,7 @@ * Suspend can't complete until all the I/O is processed so if * the last path failed we will now error any queued I/O. */ -static void multipath_suspend(struct dm_target *ti) +static void multipath_presuspend(struct dm_target *ti) { struct multipath *m = (struct multipath *) ti->private; unsigned long flags; @@ -1213,7 +1213,7 @@ .dtr = multipath_dtr, .map = multipath_map, .end_io = multipath_end_io, - .suspend = multipath_suspend, + .presuspend = multipath_presuspend, .resume = multipath_resume, .status = multipath_status, .message = multipath_message, --- diff/drivers/md/dm-raid1.c 2004-10-19 16:47:25.000000000 +0100 +++ source/drivers/md/dm-raid1.c 2004-11-10 15:14:08.000000000 +0000 @@ -1158,10 +1158,11 @@ return 0; } -static void mirror_suspend(struct dm_target *ti) +static void mirror_postsuspend(struct dm_target *ti) { struct mirror_set *ms = (struct mirror_set *) ti->private; struct dirty_log *log = ms->rh.log; + rh_stop_recovery(&ms->rh); if (log->type->suspend && log->type->suspend(log)) /* FIXME: need better error handling */ @@ -1220,7 +1221,7 @@ .dtr = mirror_dtr, .map = mirror_map, .end_io = mirror_end_io, - .suspend = mirror_suspend, + .postsuspend = mirror_postsuspend, .resume = mirror_resume, .status = mirror_status, }; --- diff/drivers/md/dm-table.c 2004-11-10 15:06:36.000000000 +0000 +++ source/drivers/md/dm-table.c 2004-11-10 15:14:08.000000000 +0000 @@ -849,15 +849,18 @@ return t->mode; } -void dm_table_suspend_targets(struct dm_table *t) +void dm_table_suspend_targets(struct dm_table *t, unsigned postsuspend) { int i; for (i = 0; i < t->num_targets; i++) { struct dm_target *ti = t->targets + i; - if (ti->type->suspend) - ti->type->suspend(ti); + if (postsuspend) { + if (ti->type->postsuspend) + ti->type->postsuspend(ti); + } else if (ti->type->presuspend) + ti->type->presuspend(ti); } } --- diff/drivers/md/dm.c 2004-11-10 15:08:04.000000000 +0000 +++ source/drivers/md/dm.c 2004-11-10 15:14:08.000000000 +0000 @@ -929,8 +929,10 @@ struct dm_table *map = dm_get_table(md); if (atomic_dec_and_test(&md->holders)) { - if (!test_bit(DMF_SUSPENDED, &md->flags) && map) - dm_table_suspend_targets(map); + if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { + dm_table_suspend_targets(map, 0); + dm_table_suspend_targets(map, 1); + } __unbind(md); free_dev(md); } @@ -1067,6 +1069,7 @@ /* unplug */ map = dm_get_table(md); if (map) { + dm_table_suspend_targets(map, 0); dm_table_unplug_all(map); dm_table_put(map); } @@ -1100,7 +1103,7 @@ map = dm_get_table(md); if (map) - dm_table_suspend_targets(map); + dm_table_suspend_targets(map, 1); dm_table_put(map); up_write(&md->lock); --- diff/drivers/md/dm.h 2004-11-10 15:08:04.000000000 +0000 +++ source/drivers/md/dm.h 2004-11-10 15:14:08.000000000 +0000 @@ -115,7 +115,7 @@ unsigned int dm_table_get_num_targets(struct dm_table *t); struct list_head *dm_table_get_devices(struct dm_table *t); int dm_table_get_mode(struct dm_table *t); -void dm_table_suspend_targets(struct dm_table *t); +void dm_table_suspend_targets(struct dm_table *t, unsigned postsuspend); void dm_table_resume_targets(struct dm_table *t); int dm_table_any_congested(struct dm_table *t, int bdi_bits); void dm_table_unplug_all(struct dm_table *t); --- diff/include/linux/device-mapper.h 2004-11-10 15:05:36.000000000 +0000 +++ source/include/linux/device-mapper.h 2004-11-10 15:14:08.000000000 +0000 @@ -52,7 +52,8 @@ struct bio *bio, int error, union map_info *map_context); -typedef void (*dm_suspend_fn) (struct dm_target *ti); +typedef void (*dm_presuspend_fn) (struct dm_target *ti); +typedef void (*dm_postsuspend_fn) (struct dm_target *ti); typedef void (*dm_resume_fn) (struct dm_target *ti); typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, @@ -82,7 +83,8 @@ dm_dtr_fn dtr; dm_map_fn map; dm_endio_fn end_io; - dm_suspend_fn suspend; + dm_presuspend_fn presuspend; + dm_postsuspend_fn postsuspend; dm_resume_fn resume; dm_status_fn status; dm_message_fn message;