Commit 0c4b76ba authored by Alasdair G. Kergon's avatar Alasdair G. Kergon Committed by Linus Torvalds

[PATCH] device-mapper: Add presuspend hook

Add optional callback before each device gets suspended (called 'presuspend').
Rename existing callback used by dm-mirror from 'suspend' to 'postsuspend'.

dm-multipath will use the new callback.

(Any kernel module using device-mapper must be recompiled after this patch.)
Signed-Off-By: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e839d388
...@@ -1158,10 +1158,11 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, ...@@ -1158,10 +1158,11 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
return 0; 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 mirror_set *ms = (struct mirror_set *) ti->private;
struct dirty_log *log = ms->rh.log; struct dirty_log *log = ms->rh.log;
rh_stop_recovery(&ms->rh); rh_stop_recovery(&ms->rh);
if (log->type->suspend && log->type->suspend(log)) if (log->type->suspend && log->type->suspend(log))
/* FIXME: need better error handling */ /* FIXME: need better error handling */
...@@ -1220,7 +1221,7 @@ static struct target_type mirror_target = { ...@@ -1220,7 +1221,7 @@ static struct target_type mirror_target = {
.dtr = mirror_dtr, .dtr = mirror_dtr,
.map = mirror_map, .map = mirror_map,
.end_io = mirror_end_io, .end_io = mirror_end_io,
.suspend = mirror_suspend, .postsuspend = mirror_postsuspend,
.resume = mirror_resume, .resume = mirror_resume,
.status = mirror_status, .status = mirror_status,
}; };
......
...@@ -849,18 +849,32 @@ int dm_table_get_mode(struct dm_table *t) ...@@ -849,18 +849,32 @@ int dm_table_get_mode(struct dm_table *t)
return t->mode; return t->mode;
} }
void dm_table_suspend_targets(struct dm_table *t) static void suspend_targets(struct dm_table *t, unsigned postsuspend)
{ {
int i; int i = t->num_targets;
struct dm_target *ti = t->targets;
for (i = 0; i < t->num_targets; i++) { while (i--) {
struct dm_target *ti = t->targets + i; if (postsuspend) {
if (ti->type->postsuspend)
ti->type->postsuspend(ti);
} else if (ti->type->presuspend)
ti->type->presuspend(ti);
if (ti->type->suspend) ti++;
ti->type->suspend(ti);
} }
} }
void dm_table_presuspend_targets(struct dm_table *t)
{
return suspend_targets(t, 0);
}
void dm_table_postsuspend_targets(struct dm_table *t)
{
return suspend_targets(t, 1);
}
void dm_table_resume_targets(struct dm_table *t) void dm_table_resume_targets(struct dm_table *t)
{ {
int i; int i;
......
...@@ -919,8 +919,10 @@ void dm_put(struct mapped_device *md) ...@@ -919,8 +919,10 @@ void dm_put(struct mapped_device *md)
struct dm_table *map = dm_get_table(md); struct dm_table *map = dm_get_table(md);
if (atomic_dec_and_test(&md->holders)) { if (atomic_dec_and_test(&md->holders)) {
if (!test_bit(DMF_SUSPENDED, &md->flags) && map) if (!test_bit(DMF_SUSPENDED, &md->flags) && map) {
dm_table_suspend_targets(map); dm_table_presuspend_targets(map);
dm_table_postsuspend_targets(map);
}
__unbind(md); __unbind(md);
free_dev(md); free_dev(md);
} }
...@@ -1032,7 +1034,11 @@ int dm_suspend(struct mapped_device *md) ...@@ -1032,7 +1034,11 @@ int dm_suspend(struct mapped_device *md)
return -EINVAL; return -EINVAL;
} }
map = dm_get_table(md);
if (map)
dm_table_presuspend_targets(map);
__lock_fs(md); __lock_fs(md);
up_read(&md->lock); up_read(&md->lock);
/* /*
...@@ -1055,7 +1061,6 @@ int dm_suspend(struct mapped_device *md) ...@@ -1055,7 +1061,6 @@ int dm_suspend(struct mapped_device *md)
up_write(&md->lock); up_write(&md->lock);
/* unplug */ /* unplug */
map = dm_get_table(md);
if (map) { if (map) {
dm_table_unplug_all(map); dm_table_unplug_all(map);
dm_table_put(map); dm_table_put(map);
...@@ -1090,7 +1095,7 @@ int dm_suspend(struct mapped_device *md) ...@@ -1090,7 +1095,7 @@ int dm_suspend(struct mapped_device *md)
map = dm_get_table(md); map = dm_get_table(md);
if (map) if (map)
dm_table_suspend_targets(map); dm_table_postsuspend_targets(map);
dm_table_put(map); dm_table_put(map);
up_write(&md->lock); up_write(&md->lock);
......
...@@ -115,7 +115,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); ...@@ -115,7 +115,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
unsigned int dm_table_get_num_targets(struct dm_table *t); unsigned int dm_table_get_num_targets(struct dm_table *t);
struct list_head *dm_table_get_devices(struct dm_table *t); struct list_head *dm_table_get_devices(struct dm_table *t);
int dm_table_get_mode(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_presuspend_targets(struct dm_table *t);
void dm_table_postsuspend_targets(struct dm_table *t);
void dm_table_resume_targets(struct dm_table *t); void dm_table_resume_targets(struct dm_table *t);
int dm_table_any_congested(struct dm_table *t, int bdi_bits); int dm_table_any_congested(struct dm_table *t, int bdi_bits);
void dm_table_unplug_all(struct dm_table *t); void dm_table_unplug_all(struct dm_table *t);
......
...@@ -52,7 +52,8 @@ typedef int (*dm_endio_fn) (struct dm_target *ti, ...@@ -52,7 +52,8 @@ typedef int (*dm_endio_fn) (struct dm_target *ti,
struct bio *bio, int error, struct bio *bio, int error,
union map_info *map_context); 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 void (*dm_resume_fn) (struct dm_target *ti);
typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
...@@ -82,7 +83,8 @@ struct target_type { ...@@ -82,7 +83,8 @@ struct target_type {
dm_dtr_fn dtr; dm_dtr_fn dtr;
dm_map_fn map; dm_map_fn map;
dm_endio_fn end_io; dm_endio_fn end_io;
dm_suspend_fn suspend; dm_presuspend_fn presuspend;
dm_postsuspend_fn postsuspend;
dm_resume_fn resume; dm_resume_fn resume;
dm_status_fn status; dm_status_fn status;
dm_message_fn message; dm_message_fn message;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment