Fill out mpath suspend/resume functions so queued I/O without a path is errored. --- diff/drivers/md/dm-mpath.c 2005-01-12 19:02:42.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2005-01-12 19:13:36.000000000 +0000 @@ -60,6 +60,7 @@ unsigned pg_init_required; /* pg_init needs calling? */ unsigned queue_io; /* Must we queue all I/O? */ unsigned queue_if_no_path; /* Queue I/O if last path fails? */ + unsigned suspended; spinlock_t lock; unsigned nr_valid_paths; @@ -263,7 +264,8 @@ pgpath = m->current_pgpath; - if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path)) + if ((pgpath && m->queue_io) || + (!pgpath && m->queue_if_no_path && !m->suspended)) must_queue = 1; if (was_queued) @@ -351,7 +353,8 @@ pgpath = m->current_pgpath; - if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path)) + if ((pgpath && m->queue_io) || + (!pgpath && m->queue_if_no_path && !m->suspended)) must_queue = 1; init_required = m->pg_init_required; @@ -908,18 +911,30 @@ return r; } +/* + * Suspend can't complete until all the I/O is processed so if + * the last path failed we will now error any queued I/O. + */ static void multipath_presuspend(struct dm_target *ti) { struct multipath *m = (struct multipath *) ti->private; + unsigned long flags; - + spin_lock_irqsave(&m->lock, flags); + m->suspended = 1; + if (m->queue_if_no_path) + schedule_work(&m->process_queued_ios); + spin_unlock_irqrestore(&m->lock, flags); } static void multipath_resume(struct dm_target *ti) { struct multipath *m = (struct multipath *) ti->private; + unsigned long flags; - + spin_lock_irqsave(&m->lock, flags); + m->suspended = 0; + spin_unlock_irqrestore(&m->lock, flags); } /*