Avoid endio references to invalid pgpath. --- diff/drivers/md/dm-mpath.c 2005-01-12 19:18:36.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2005-01-12 19:18:50.000000000 +0000 @@ -274,6 +274,7 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, unsigned was_queued) { + int r = 1; unsigned long flags; struct pgpath *pgpath; unsigned must_queue = 0; @@ -304,15 +305,23 @@ spin_unlock_irqrestore(&m->lock, flags); - if (must_queue) - return 0; /* Queued */ + if (must_queue) { + r = 0; /* Queued */ + pgpath = NULL; + goto out; + } - if (!pgpath) - return -EIO; + if (!pgpath) { + r = -EIO; + goto out; + } + + /* Mapped successfully */ + bio->bi_bdev = pgpath->path.dev->bdev; +out: mpio->pgpath = pgpath; - bio->bi_bdev = mpio->pgpath->path.dev->bdev; - return 1; /* Mapped successfully */ + return r; } static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path) @@ -966,11 +975,13 @@ if (hwh->type && hwh->type->err) err_flags = hwh->type->err(hwh, bio); - if (err_flags & MP_FAIL_PATH) - fail_path(mpio->pgpath); + if (mpio->pgpath) { + if (err_flags & MP_FAIL_PATH) + fail_path(mpio->pgpath); - if (err_flags & MP_BYPASS_PG) - bypass_pg(m, mpio->pgpath->pg, 1); + if (err_flags & MP_BYPASS_PG) + bypass_pg(m, mpio->pgpath->pg, 1); + } if (err_flags & MP_ERROR_IO) return -EIO; @@ -994,12 +1005,15 @@ struct multipath *m = (struct multipath *) ti->private; struct mpath_io *mpio = (struct mpath_io *) map_context->ptr; struct pgpath *pgpath = mpio->pgpath; - struct path_selector *ps = &pgpath->pg->ps; + struct path_selector *ps; int r; r = do_end_io(m, bio, error, mpio); - if (ps->type->end_io) - ps->type->end_io(ps, &pgpath->path); + if (pgpath) { + ps = &pgpath->pg->ps; + if (ps->type->end_io) + ps->type->end_io(ps, &pgpath->path); + } if (r <= 0) mempool_free(mpio, m->mpio_pool);