dm mpath: use place-holder devices for removed failed paths throwaway-dm-mpath-placeholder-devs
authorMike Snitzer <snitzer@redhat.com>
Thu, 17 Jul 2014 22:58:48 +0000 (18:58 -0400)
committerMike Snitzer <snitzer@redhat.com>
Fri, 18 Jul 2014 15:56:07 +0000 (11:56 -0400)
drivers/md/dm-mpath.c
drivers/md/dm-mpath.h

index 50007a7325be1d55f330e1ea60ffa9084d2dd813..6c3ddd29d29e09bc23e32bb9a910c6743272799e 100644 (file)
@@ -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);
 }
 
 /*
index f97388da3279735cde4c060249e1508db26d1865..e230f7196259622947a6bfc5169328a41ed15223 100644 (file)
@@ -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 */
 };