From: Mike Snitzer Date: Thu, 17 Jul 2014 22:58:48 +0000 (-0400) Subject: dm mpath: use place-holder devices for removed failed paths X-Git-Url: https://git.fsl.cs.sunysb.edu/?a=commitdiff_plain;h=refs%2Fheads%2Fthrowaway-dm-mpath-placeholder-devs;p=linux-dmdedup.git dm mpath: use place-holder devices for removed failed paths --- diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 50007a7325b..6c3ddd29d29 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -162,7 +162,7 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) list_for_each_entry_safe(pgpath, tmp, pgpaths, list) { list_del(&pgpath->list); - if (m->hw_handler_name && pgpath->path.dev) + if (m->hw_handler_name && pgpath->path.dev->bdev) scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); dm_put_device(ti, pgpath->path.dev); free_pgpath(pgpath); @@ -306,7 +306,7 @@ static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg, m->current_pgpath = path_to_pgpath(path); - if (!m->current_pgpath->path.dev) { + if (!m->current_pgpath->path.dev->bdev) { m->current_pgpath = NULL; return -ENODEV; } @@ -522,7 +522,6 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps { int r; struct pgpath *p; - const char *path; struct multipath *m = ti->private; struct request_queue *q = NULL; const char *attached_handler_name; @@ -537,38 +536,17 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps if (!p) return ERR_PTR(-ENOMEM); - path = dm_shift_arg(as); - r = dm_get_device(ti, path, dm_table_get_mode(ti->table), - &p->path.dev); + r = __dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table), + &p->path.dev, true); if (r) { - unsigned major, minor; - - /* Try to add a failed device */ - if (r == -ENXIO && sscanf(path, "%u:%u", &major, &minor) == 2) { - dev_t dev; - - /* Extract the major/minor numbers */ - dev = MKDEV(major, minor); - if (MAJOR(dev) != major || MINOR(dev) != minor) { - /* Nice try, didn't work */ - DMWARN("Invalid device path %s", path); - ti->error = "error converting devnum"; - goto bad; - } - DMWARN("adding disabled device %d:%d", major, minor); - p->path.dev = NULL; - format_dev_t(p->path.pdev, dev); - p->is_active = 0; - } else { - ti->error = "error getting device"; - goto bad; - } - } else { - memcpy(p->path.pdev, p->path.dev->name, 16); + ti->error = "error getting device"; + goto bad; } - if (p->path.dev) + if (p->path.dev->bdev) q = bdev_get_queue(p->path.dev->bdev); + else + p->is_active = 0; if (q && m->retain_attached_hw_handler) { attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL); @@ -969,7 +947,7 @@ static int fail_path(struct pgpath *pgpath) if (!pgpath->is_active) goto out; - DMWARN("Failing path %s.", pgpath->path.pdev); + DMWARN("Failing path %s.", pgpath->path.dev->name); pgpath->is_active = 0; __fail_path(pgpath, m, &pgpath->pg->ps); @@ -978,7 +956,7 @@ static int fail_path(struct pgpath *pgpath) m->current_pgpath = NULL; dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti, - pgpath->path.pdev, m->nr_valid_paths); + pgpath->path.dev->name, m->nr_valid_paths); schedule_work(&m->trigger_event); @@ -1024,7 +1002,7 @@ static int reinstate_path(struct pgpath *pgpath) } dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti, - pgpath->path.pdev, m->nr_valid_paths); + pgpath->path.dev->name, m->nr_valid_paths); schedule_work(&m->trigger_event); @@ -1048,9 +1026,6 @@ static int action_dev(struct multipath *m, struct dm_dev *dev, list_for_each_entry(pg, &m->priority_groups, list) { list_for_each_entry(pgpath, &pg->pgpaths, list) { - // FIXME: this will _never_ match a removed failed path - // that is now available and attempting to be reinstated - // - shouldn't we be able to reinstate a removed failed path? if (pgpath->path.dev == dev) r = action(pgpath); } @@ -1239,7 +1214,7 @@ static void activate_path(struct work_struct *work) struct pgpath *pgpath = container_of(work, struct pgpath, activate_path.work); - if (pgpath->is_active && pgpath->path.dev) + if (pgpath->is_active && pgpath->path.dev->bdev) scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev), pg_init_done, pgpath); else @@ -1449,7 +1424,7 @@ static void multipath_status(struct dm_target *ti, status_type_t type, pg->ps.type->info_args); list_for_each_entry(p, &pg->pgpaths, list) { - DMEMIT("%s %s %u ", p->path.pdev, + DMEMIT("%s %s %u ", p->path.dev->name, p->is_active ? "A" : "F", p->fail_count); if (pg->ps.type->status) @@ -1475,7 +1450,7 @@ static void multipath_status(struct dm_target *ti, status_type_t type, pg->ps.type->table_args); list_for_each_entry(p, &pg->pgpaths, list) { - DMEMIT("%s ", p->path.pdev); + DMEMIT("%s ", p->path.dev->name); if (pg->ps.type->status) sz += pg->ps.type->status(&pg->ps, &p->path, type, result + sz, @@ -1572,7 +1547,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, pgpath = m->current_pgpath; - if (pgpath && pgpath->path.dev) { + if (pgpath && pgpath->path.dev->bdev) { bdev = pgpath->path.dev->bdev; mode = pgpath->path.dev->mode; } @@ -1618,8 +1593,6 @@ static int multipath_iterate_devices(struct dm_target *ti, list_for_each_entry(pg, &m->priority_groups, list) { list_for_each_entry(p, &pg->pgpaths, list) { - if (!p->path.dev) - continue; ret = fn(ti, p->path.dev, ti->begin, ti->len, data); if (ret) goto out; @@ -1632,9 +1605,9 @@ out: static int __pgpath_busy(struct pgpath *pgpath) { - struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev); + struct request_queue *q = dm_dev_get_queue(pgpath->path.dev); - return dm_underlying_device_busy(q); + return q && dm_underlying_device_busy(q); } /* diff --git a/drivers/md/dm-mpath.h b/drivers/md/dm-mpath.h index f97388da327..e230f719625 100644 --- a/drivers/md/dm-mpath.h +++ b/drivers/md/dm-mpath.h @@ -12,7 +12,6 @@ struct dm_dev; struct dm_path { - char pdev[16]; /* Requested physical device */ struct dm_dev *dev; /* Read-only */ void *pscontext; /* For path-selector use */ };