mpath-init-cleanup.patch - just some cleanup from my last patches. It should
applied on top of them.
dm-mpath.c | 61 ++++++++++++++++++++++++++--------------------------
dm-priority-group.c | 12 +++++-----
dm-priority-group.h | 11 +++++----
3 files changed, 44 insertions(+), 40 deletions(-)
diff -arup linux-2.6.7-rc2/drivers/md/dm-mpath.c linux-2.6.7-rc2-pg/drivers/md/dm-mpath.c
--- linux-2.6.7-rc2/drivers/md/dm-mpath.c 2004-06-04 03:58:47.000000000 -0700
+++ linux-2.6.7-rc2-pg/drivers/md/dm-mpath.c 2004-06-04 22:02:51.000000000 -0700
@@ -100,6 +100,7 @@ static struct priority_group *alloc_prio
memset(pg, 0, sizeof(*pg));
INIT_LIST_HEAD(&pg->paths);
+ pg->failed = 0;
return pg;
}
@@ -171,28 +172,33 @@ static void free_multipath(struct multip
kfree(m);
}
-static void __pg_init_complete(struct multipath *m, struct priority_group *pg)
-{
- m->initializing_pg = 0;
- m->current_pg = pg;
- complete_all(&m->init_pg_wait);
- schedule_work(&m->dispatch_failed);
-}
+static int select_group(struct multipath *m);
-void dm_pg_init_complete(struct priority_group *pg)
+void dm_pg_init_complete(struct priority_group *pg, int error)
{
unsigned long flags;
struct multipath *m = pg->m;
spin_lock_irqsave(&m->lock, flags);
- __pg_init_complete(m, pg);
+
+ if (error == DM_PG_FAILED) {
+ pg->failed = 1;
+ if (select_group(m) == DM_PG_INITIALIZING)
+ goto done;
+ } else if (error == DM_PG_SUCCESS) {
+ m->initializing_pg = 0;
+ m->current_pg = pg;
+ }
+
+ complete_all(&m->init_pg_wait);
+ schedule_work(&m->dispatch_failed);
+ done:
spin_unlock_irqrestore(&m->lock, flags);
}
EXPORT_SYMBOL(dm_pg_init_complete);
-static int select_group(struct multipath *m, struct mpath_io *mpio,
- struct bio *bio)
+static int select_group(struct multipath *m)
{
struct priority_group *pg = NULL;
int err;
@@ -202,26 +208,23 @@ static int select_group(struct multipath
init_completion(&m->init_pg_wait);
list_for_each_entry (pg, &m->priority_groups, list) {
+ if (pg->failed)
+ continue;
if (pg->type->init) {
- spin_unlock_irq(&m->lock);
err = pg->type->init(pg);
- spin_lock_irq(&m->lock);
-
if (err == DM_PG_INITIALIZING)
- return DM_PG_INITIALIZING;
- else if (err == DM_PG_FAILED)
+ return err;
+ else if (err == DM_PG_FAILED) {
+ pg->failed = 1;
continue;
+ }
}
-
- mpio->path = pg->ps.type->select_path(&pg->ps, bio,
- &mpio->info);
- if (mpio->path)
- break;
}
- __pg_init_complete(m, mpio->path ? pg : NULL);
- return mpio->path ? DM_PG_SUCCESS : DM_PG_FAILED;
+ m->current_pg = (pg->failed ? NULL : pg);
+ m->initializing_pg = 0;
+ return m->current_pg ? DM_PG_SUCCESS : DM_PG_FAILED;
}
static int select_path(struct multipath *m, struct mpath_io *mpio,
@@ -249,13 +252,11 @@ static int select_path(struct multipath
struct path_selector *ps = &m->current_pg->ps;
mpio->path = ps->type->select_path(ps, bio, &mpio->info);
- if (!mpio->path &&
- (select_group(m, mpio, bio) == DM_PG_INITIALIZING))
- /*
- * while the lock was dropped the
- * initialization might have completed.
- */
- goto retest;
+ if (!mpio->path) {
+ m->current_pg->failed = 1;
+ if (select_group(m) != DM_PG_FAILED)
+ goto retest;
+ }
}
return mpio->path ? 0 : -EIO;
diff -arup linux-2.6.7-rc2/drivers/md/dm-priority-group.c linux-2.6.7-rc2-pg/drivers/md/dm-priority-group.c
--- linux-2.6.7-rc2/drivers/md/dm-priority-group.c 2004-06-04 04:04:17.000000000 -0700
+++ linux-2.6.7-rc2-pg/drivers/md/dm-priority-group.c 2004-06-04 13:54:28.000000000 -0700
@@ -109,7 +109,7 @@ static struct pg_internal *_alloc_priori
return pgi;
}
-int dm_register_priority_group(struct priority_group_type *pgt)
+int dm_register_priority_group_type(struct priority_group_type *pgt)
{
int r = 0;
struct pg_internal *pgi = _alloc_priority_group(pgt);
@@ -129,9 +129,9 @@ int dm_register_priority_group(struct pr
return r;
}
-EXPORT_SYMBOL(dm_register_priority_group);
+EXPORT_SYMBOL(dm_register_priority_group_type);
-int dm_unregister_priority_group(struct priority_group_type *pgt)
+int dm_unregister_priority_group_type(struct priority_group_type *pgt)
{
struct pg_internal *pgi;
@@ -156,7 +156,7 @@ int dm_unregister_priority_group(struct
return 0;
}
-EXPORT_SYMBOL(dm_unregister_priority_group);
+EXPORT_SYMBOL(dm_unregister_priority_group_type);
/*
@@ -345,10 +345,10 @@ static struct priority_group_type gen_pg
int __init dm_register_generic_group(void)
{
- return dm_register_priority_group(&gen_pg);
+ return dm_register_priority_group_type(&gen_pg);
}
void __exit dm_unregister_generic_group(void)
{
- dm_unregister_priority_group(&gen_pg);
+ dm_unregister_priority_group_type(&gen_pg);
}
diff -arup linux-2.6.7-rc2/drivers/md/dm-priority-group.h linux-2.6.7-rc2-pg/drivers/md/dm-priority-group.h
--- linux-2.6.7-rc2/drivers/md/dm-priority-group.h 2004-06-04 04:04:17.000000000 -0700
+++ linux-2.6.7-rc2-pg/drivers/md/dm-priority-group.h 2004-06-04 21:01:40.000000000 -0700
@@ -49,6 +49,8 @@ struct priority_group {
struct list_head paths;
struct list_head list;
+
+ int failed;
};
/*
@@ -61,7 +63,8 @@ typedef void (*pg_dtr_fn) (struct priori
* Allows the pg to initialize itself. It should return one
* of the following return values. If DM_PG_INITIALIZING is
* returned the priority_group must call dm_pg_init_complete
- * when the initializtion has completed.
+ * with either DM_PG_SUCCESS or DM_PG_FAILED when the
+ * initializtion has completed
*/
enum {
DM_PG_SUCCESS,
@@ -69,7 +72,7 @@ enum {
DM_PG_INITIALIZING,
};
-void dm_pg_init_complete(struct priority_group *pg);
+void dm_pg_init_complete(struct priority_group *pg, int error);
typedef int (*pg_init_fn) (struct priority_group *pg);
@@ -112,8 +115,8 @@ struct priority_group_type {
};
-int dm_unregister_priority_group(struct priority_group_type *pgt);
-int dm_register_priority_group(struct priority_group_type *pgt);
+int dm_unregister_priority_group_type(struct priority_group_type *pgt);
+int dm_register_priority_group_type(struct priority_group_type *pgt);
void dm_put_priority_group(struct priority_group_type *pgt);
struct priority_group_type *dm_get_priority_group(const char *name);