[dm-devel] [PATCH 3/3] path failure and reinstate events

Mike Anderson andmike at us.ibm.com
Mon Jan 16 08:38:08 UTC 2006


This patch adds a call to init dm_nl during dm init, and calls to dm_nl
functions for path failure / reinstate events.

Signed-off-by: Mike Anderson <andmike at us.ibm.com>

 drivers/md/dm-mpath.c |   34 ++++++++++++++++++++++++++++++++--
 drivers/md/dm.c       |    2 ++
 drivers/md/dm.h       |    1 +
 3 files changed, 35 insertions(+), 2 deletions(-)

Index: sas-2.6-patched/drivers/md/dm.h
===================================================================
--- sas-2.6-patched.orig/drivers/md/dm.h	2006-01-15 22:41:53.000000000 -0800
+++ sas-2.6-patched/drivers/md/dm.h	2006-01-15 22:45:12.000000000 -0800
@@ -14,6 +14,7 @@
 #include <linux/device-mapper.h>
 #include <linux/list.h>
 #include <linux/blkdev.h>
+#include "dm-netlink.h"
 
 #define DM_NAME "device-mapper"
 #define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x)
Index: sas-2.6-patched/drivers/md/dm.c
===================================================================
--- sas-2.6-patched.orig/drivers/md/dm.c	2006-01-15 22:41:53.000000000 -0800
+++ sas-2.6-patched/drivers/md/dm.c	2006-01-15 22:45:12.000000000 -0800
@@ -163,6 +163,7 @@ int (*_inits[])(void) __initdata = {
 	dm_linear_init,
 	dm_stripe_init,
 	dm_interface_init,
+	dm_nl_init,
 };
 
 void (*_exits[])(void) = {
@@ -171,6 +172,7 @@ void (*_exits[])(void) = {
 	dm_linear_exit,
 	dm_stripe_exit,
 	dm_interface_exit,
+	dm_nl_exit,
 };
 
 static int __init dm_init(void)
Index: sas-2.6-patched/drivers/md/dm-mpath.c
===================================================================
--- sas-2.6-patched.orig/drivers/md/dm-mpath.c	2006-01-15 22:41:53.000000000 -0800
+++ sas-2.6-patched/drivers/md/dm-mpath.c	2006-01-15 22:50:23.000000000 -0800
@@ -10,6 +10,7 @@
 #include "dm-hw-handler.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
+#include "dm-netlink.h"
 
 #include <linux/ctype.h>
 #include <linux/init.h>
@@ -80,6 +81,7 @@ struct multipath {
 	unsigned queue_size;
 
 	struct work_struct trigger_event;
+	struct list_head evt_list;
 
 	/*
 	 * We must use a mempool of mpath_io structs so that we
@@ -179,6 +181,7 @@ static struct multipath *alloc_multipath
 		m->queue_io = 1;
 		INIT_WORK(&m->process_queued_ios, process_queued_ios, m);
 		INIT_WORK(&m->trigger_event, trigger_event, m);
+		INIT_LIST_HEAD(&m->evt_list);
 		m->mpio_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
 					      mempool_free_slab, _mpio_cache);
 		if (!m->mpio_pool) {
@@ -426,7 +429,19 @@ out:
  */
 static void trigger_event(void *data)
 {
+	unsigned long flags;
 	struct multipath *m = (struct multipath *) data;
+	struct dm_evt *evt, *next;
+	LIST_HEAD(events);
+
+	spin_lock_irqsave(&m->lock, flags);
+	list_splice_init(&m->evt_list, &events);
+	spin_unlock_irqrestore(&m->lock, flags);
+
+	list_for_each_entry_safe(evt, next, &events, elist) {
+		list_del_init(&evt->elist);
+		dm_send_evt(evt);
+	}
 
 	dm_table_event(m->ti->table);
 }
@@ -798,9 +813,10 @@ static int multipath_map(struct dm_targe
 /*
  * Take a path out of use.
  */
-static int fail_path(struct pgpath *pgpath)
+static int __fail_path(struct pgpath *pgpath, struct bio *bio)
 {
 	unsigned long flags;
+	struct dm_evt *evt;
 	struct multipath *m = pgpath->pg->m;
 
 	spin_lock_irqsave(&m->lock, flags);
@@ -819,6 +835,10 @@ static int fail_path(struct pgpath *pgpa
 	if (pgpath == m->current_pgpath)
 		m->current_pgpath = NULL;
 
+	/* Get error data from bio when available */
+	evt = dm_path_fail_evt(pgpath->path.dev->name, 0);
+	if (evt)
+		list_add(&evt->elist, &m->evt_list);
 	queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -827,6 +847,11 @@ out:
 	return 0;
 }
 
+static int fail_path(struct pgpath *pgpath)
+{
+	return __fail_path(pgpath, NULL);
+}
+
 /*
  * Reinstate a previously-failed path
  */
@@ -834,6 +859,7 @@ static int reinstate_path(struct pgpath 
 {
 	int r = 0;
 	unsigned long flags;
+	struct dm_evt *evt;
 	struct multipath *m = pgpath->pg->m;
 
 	spin_lock_irqsave(&m->lock, flags);
@@ -858,6 +884,10 @@ static int reinstate_path(struct pgpath 
 	if (!m->nr_valid_paths++ && m->queue_size)
 		queue_work(kmultipathd, &m->process_queued_ios);
 
+	evt = dm_path_reinstate_evt(pgpath->path.dev->name);
+	if (evt)
+		list_add(&evt->elist, &m->evt_list);
+
 	queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -1028,7 +1058,7 @@ static int do_end_io(struct multipath *m
 
 	if (mpio->pgpath) {
 		if (err_flags & MP_FAIL_PATH)
-			fail_path(mpio->pgpath);
+			__fail_path(mpio->pgpath, bio);
 
 		if (err_flags & MP_BYPASS_PG)
 			bypass_pg(m, mpio->pgpath->pg, 1);




More information about the dm-devel mailing list