Tell pg_init_fn whether PG is already bypassed, and if it is and the function fails, insist that the path gets failed. --- diff/drivers/md/dm-hw-handler.h 2004-10-29 15:39:19.000000000 +0100 +++ source/drivers/md/dm-hw-handler.h 2004-10-29 15:39:50.000000000 +0100 @@ -25,8 +25,8 @@ typedef int (*hwh_ctr_fn) (struct hw_handler *hwh, unsigned arc, char **argv); typedef void (*hwh_dtr_fn) (struct hw_handler *hwh); -typedef void (*hwh_pg_init_fn) (struct hw_handler *hwh, struct path *path, - struct block_device *bdev); +typedef void (*hwh_pg_init_fn) (struct hw_handler *hwh, unsigned bypassed, + struct path *path, struct block_device *bdev); typedef unsigned (*hwh_err_fn) (struct hw_handler *hwh, struct bio *bio); typedef int (*hwh_status_fn) (struct hw_handler *hwh, status_type_t type, --- diff/drivers/md/dm-mpath.c 2004-10-29 15:39:44.000000000 +0100 +++ source/drivers/md/dm-mpath.c 2004-10-29 15:39:50.000000000 +0100 @@ -313,7 +313,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, bypassed; unsigned long flags; spin_lock_irqsave(&m->lock, flags); @@ -322,6 +322,7 @@ __choose_path(m); path = m->current_path; + bypassed = path->pg->bypass; must_queue = m->queue_io; init_required = m->pg_init_required; @@ -331,7 +332,7 @@ spin_unlock_irqrestore(&m->lock, flags); if (init_required) - hwh->type->pg_init(hwh, path, path->dev->bdev); + hwh->type->pg_init(hwh, bypassed, path, path->dev->bdev); if (path && must_queue) return; @@ -772,6 +773,10 @@ struct multipath *m = pg->m; unsigned long flags; + /* We insist on failing the path if the PG is already bypassed. */ + if (err_flags && pg->bypass) + err_flags |= MP_FAIL_PATH; + if (err_flags & MP_FAIL_PATH) fail_path(path);