Add queue/fail_if_no_paths messages & functionality.
--- diff/drivers/md/dm-mpath.c	2004-10-29 21:04:24.000000000 +0100
+++ source/drivers/md/dm-mpath.c	2004-10-29 21:06:44.000000000 +0100
@@ -55,6 +55,7 @@
 	struct list_head priority_groups;
 	unsigned pg_init_required;	/* pg_init needs calling? */
 	unsigned queue_io;		/* Must we queue all I/O? */
+	unsigned queue_if_no_paths;	/* Queue I/O if last path fails? */
 
 	spinlock_t lock;
 	unsigned nr_valid_paths;
@@ -242,7 +243,7 @@
 {
 	unsigned long flags;
 	struct path *path;
-	unsigned must_queue;
+	unsigned must_queue = 0;
 
 	spin_lock_irqsave(&m->lock, flags);
 
@@ -251,28 +252,30 @@
 	    (!m->queue_io && (m->current_count && --m->current_count == 0)))
 		__choose_path(m);
 
-	must_queue = m->queue_io;
 	path = m->current_path;
 
+	if ((path && m->queue_io) || (!path && m->queue_if_no_paths))
+		must_queue = 1;
+
 	spin_unlock_irqrestore(&m->lock, flags);
 
-	if (!path)
-		return -EIO;
+	if (must_queue) {
+		/* queue for the daemon to resubmit */
+		spin_lock_irqsave(&m->lock, flags);
+		bio_list_add(&m->queued_ios, bio);
+		if (m->pg_init_required || !m->queue_io)
+			schedule_work(&m->process_queued_ios);
+		spin_unlock_irqrestore(&m->lock, flags);
 
-	if (!must_queue) {
-		mpio->path = path;
-		bio->bi_bdev = mpio->path->dev->bdev;
-		return 1;	/* Mapped successfully */
+		return 0;		/* Queued */
 	}
 
-	/* queue for the daemon to resubmit */
-	spin_lock_irqsave(&m->lock, flags);
-	bio_list_add(&m->queued_ios, bio);
-	if (m->pg_init_required || !m->queue_io)
-		schedule_work(&m->process_queued_ios);
-	spin_unlock_irqrestore(&m->lock, flags);
+	if (!path)
+		return -EIO;
 
-	return 0;		/* Queued */
+	mpio->path = path;
+	bio->bi_bdev = mpio->path->dev->bdev;
+	return 1;	/* Mapped successfully */
 }
 
 /*-----------------------------------------------------------------
@@ -313,7 +316,7 @@
 	struct multipath *m = (struct multipath *) data;
 	struct hw_handler *hwh = &m->hw_handler;
 	struct path *path;
-	unsigned init_required, must_queue;
+	unsigned init_required, must_queue = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&m->lock, flags);
@@ -322,7 +325,9 @@
 		__choose_path(m);
 
 	path = m->current_path;
-	must_queue = m->queue_io;
+
+	if ((path && m->queue_io) || (!path && m->queue_if_no_paths))
+		must_queue = 1;
 
 	init_required = m->pg_init_required;
 	if (init_required)
@@ -334,10 +339,8 @@
 		hwh->type->pg_init(hwh, path->pg->bypassed, path,
 				   path->dev->bdev);
 
-	if (path && must_queue)
-		return;
-
-	dispatch_queued_ios(m);
+	if (!must_queue)
+		dispatch_queued_ios(m);
 }
 
 /*
@@ -692,8 +695,9 @@
 	m = path->pg->m;
 
 	spin_lock(&m->lock);
-	m->nr_valid_paths++;
 	m->current_path = NULL;
+	if (!m->nr_valid_paths++)
+		schedule_work(&m->process_queued_ios);
 	spin_unlock(&m->lock);
 
 	schedule_work(&m->trigger_event);
@@ -925,6 +929,19 @@
 	return 0;
 }
 
+static int queue_if_no_paths(struct multipath *m, unsigned queue_if_no_paths)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&m->lock, flags);
+	m->queue_if_no_paths = queue_if_no_paths;
+	if (!m->queue_if_no_paths)
+		schedule_work(&m->process_queued_ios);
+	spin_unlock_irqrestore(&m->lock, flags);
+
+	return 0;
+}
+
 #define MESG_STR(x) x, sizeof(x)
 
 static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
@@ -934,6 +951,13 @@
 	struct multipath *m = (struct multipath *) ti->private;
 	action_fn action;
 
+	if (argc == 1) {
+		if (!strnicmp(argv[0], MESG_STR("queue_if_no_paths")))
+			return queue_if_no_paths(m, 1);
+		else if (!strnicmp(argv[0], MESG_STR("fail_if_no_paths")))
+			return queue_if_no_paths(m, 0);
+	}
+
 	if (argc != 2)
 		goto error;
 
