[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH 1/4] add manual failover support for HP storage works



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);
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]