aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-mpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-mpath.c')
-rw-r--r--drivers/md/dm-mpath.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 3d3848132c69..103304c1e3b0 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -30,6 +30,7 @@ struct pgpath {
30 struct list_head list; 30 struct list_head list;
31 31
32 struct priority_group *pg; /* Owning PG */ 32 struct priority_group *pg; /* Owning PG */
33 unsigned is_active; /* Path status */
33 unsigned fail_count; /* Cumulative failure count */ 34 unsigned fail_count; /* Cumulative failure count */
34 35
35 struct dm_path path; 36 struct dm_path path;
@@ -125,7 +126,7 @@ static struct pgpath *alloc_pgpath(void)
125 struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); 126 struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
126 127
127 if (pgpath) { 128 if (pgpath) {
128 pgpath->path.is_active = 1; 129 pgpath->is_active = 1;
129 INIT_WORK(&pgpath->deactivate_path, deactivate_path); 130 INIT_WORK(&pgpath->deactivate_path, deactivate_path);
130 } 131 }
131 132
@@ -575,12 +576,12 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
575 /* we need at least a path arg */ 576 /* we need at least a path arg */
576 if (as->argc < 1) { 577 if (as->argc < 1) {
577 ti->error = "no device given"; 578 ti->error = "no device given";
578 return NULL; 579 return ERR_PTR(-EINVAL);
579 } 580 }
580 581
581 p = alloc_pgpath(); 582 p = alloc_pgpath();
582 if (!p) 583 if (!p)
583 return NULL; 584 return ERR_PTR(-ENOMEM);
584 585
585 r = dm_get_device(ti, shift(as), ti->begin, ti->len, 586 r = dm_get_device(ti, shift(as), ti->begin, ti->len,
586 dm_table_get_mode(ti->table), &p->path.dev); 587 dm_table_get_mode(ti->table), &p->path.dev);
@@ -608,7 +609,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
608 609
609 bad: 610 bad:
610 free_pgpath(p); 611 free_pgpath(p);
611 return NULL; 612 return ERR_PTR(r);
612} 613}
613 614
614static struct priority_group *parse_priority_group(struct arg_set *as, 615static struct priority_group *parse_priority_group(struct arg_set *as,
@@ -626,14 +627,14 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
626 627
627 if (as->argc < 2) { 628 if (as->argc < 2) {
628 as->argc = 0; 629 as->argc = 0;
629 ti->error = "not enough priority group aruments"; 630 ti->error = "not enough priority group arguments";
630 return NULL; 631 return ERR_PTR(-EINVAL);
631 } 632 }
632 633
633 pg = alloc_priority_group(); 634 pg = alloc_priority_group();
634 if (!pg) { 635 if (!pg) {
635 ti->error = "couldn't allocate priority group"; 636 ti->error = "couldn't allocate priority group";
636 return NULL; 637 return ERR_PTR(-ENOMEM);
637 } 638 }
638 pg->m = m; 639 pg->m = m;
639 640
@@ -666,8 +667,10 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
666 path_args.argv = as->argv; 667 path_args.argv = as->argv;
667 668
668 pgpath = parse_path(&path_args, &pg->ps, ti); 669 pgpath = parse_path(&path_args, &pg->ps, ti);
669 if (!pgpath) 670 if (IS_ERR(pgpath)) {
671 r = PTR_ERR(pgpath);
670 goto bad; 672 goto bad;
673 }
671 674
672 pgpath->pg = pg; 675 pgpath->pg = pg;
673 list_add_tail(&pgpath->list, &pg->pgpaths); 676 list_add_tail(&pgpath->list, &pg->pgpaths);
@@ -678,7 +681,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
678 681
679 bad: 682 bad:
680 free_priority_group(pg, ti); 683 free_priority_group(pg, ti);
681 return NULL; 684 return ERR_PTR(r);
682} 685}
683 686
684static int parse_hw_handler(struct arg_set *as, struct multipath *m) 687static int parse_hw_handler(struct arg_set *as, struct multipath *m)
@@ -797,8 +800,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
797 struct priority_group *pg; 800 struct priority_group *pg;
798 801
799 pg = parse_priority_group(&as, m); 802 pg = parse_priority_group(&as, m);
800 if (!pg) { 803 if (IS_ERR(pg)) {
801 r = -EINVAL; 804 r = PTR_ERR(pg);
802 goto bad; 805 goto bad;
803 } 806 }
804 807
@@ -864,13 +867,13 @@ static int fail_path(struct pgpath *pgpath)
864 867
865 spin_lock_irqsave(&m->lock, flags); 868 spin_lock_irqsave(&m->lock, flags);
866 869
867 if (!pgpath->path.is_active) 870 if (!pgpath->is_active)
868 goto out; 871 goto out;
869 872
870 DMWARN("Failing path %s.", pgpath->path.dev->name); 873 DMWARN("Failing path %s.", pgpath->path.dev->name);
871 874
872 pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path); 875 pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path);
873 pgpath->path.is_active = 0; 876 pgpath->is_active = 0;
874 pgpath->fail_count++; 877 pgpath->fail_count++;
875 878
876 m->nr_valid_paths--; 879 m->nr_valid_paths--;
@@ -901,7 +904,7 @@ static int reinstate_path(struct pgpath *pgpath)
901 904
902 spin_lock_irqsave(&m->lock, flags); 905 spin_lock_irqsave(&m->lock, flags);
903 906
904 if (pgpath->path.is_active) 907 if (pgpath->is_active)
905 goto out; 908 goto out;
906 909
907 if (!pgpath->pg->ps.type->reinstate_path) { 910 if (!pgpath->pg->ps.type->reinstate_path) {
@@ -915,7 +918,7 @@ static int reinstate_path(struct pgpath *pgpath)
915 if (r) 918 if (r)
916 goto out; 919 goto out;
917 920
918 pgpath->path.is_active = 1; 921 pgpath->is_active = 1;
919 922
920 m->current_pgpath = NULL; 923 m->current_pgpath = NULL;
921 if (!m->nr_valid_paths++ && m->queue_size) 924 if (!m->nr_valid_paths++ && m->queue_size)
@@ -1303,7 +1306,7 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
1303 1306
1304 list_for_each_entry(p, &pg->pgpaths, list) { 1307 list_for_each_entry(p, &pg->pgpaths, list) {
1305 DMEMIT("%s %s %u ", p->path.dev->name, 1308 DMEMIT("%s %s %u ", p->path.dev->name,
1306 p->path.is_active ? "A" : "F", 1309 p->is_active ? "A" : "F",
1307 p->fail_count); 1310 p->fail_count);
1308 if (pg->ps.type->status) 1311 if (pg->ps.type->status)
1309 sz += pg->ps.type->status(&pg->ps, 1312 sz += pg->ps.type->status(&pg->ps,