From: Benjamin Marzinski This patch allows path errors from the multipath ctr function to propagate up to userspace as errno values from the ioctl() call. This is in response to https://www.redhat.com/archives/dm-devel/2008-May/msg00000.html and https://bugzilla.redhat.com/show_bug.cgi?id=444421 The patch only lets through the errors that it needs to, in order to get the path errors from parse_path(). It's possible that there are other errors worth progatating that this leaves out. Signed-off-by: Benjamin Marzinski Signed-off-by: Alasdair G Kergon --- drivers/md/dm-mpath.c | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) Index: linux-2.6.26-rc8/drivers/md/dm-mpath.c =================================================================== --- linux-2.6.26-rc8.orig/drivers/md/dm-mpath.c 2008-07-08 17:40:14.000000000 +0100 +++ linux-2.6.26-rc8/drivers/md/dm-mpath.c 2008-07-08 18:12:41.000000000 +0100 @@ -557,12 +557,12 @@ static struct pgpath *parse_path(struct /* we need at least a path arg */ if (as->argc < 1) { ti->error = "no device given"; - return NULL; + return ERR_PTR(-EINVAL); } p = alloc_pgpath(); if (!p) - return NULL; + return ERR_PTR(-ENOMEM); r = dm_get_device(ti, shift(as), ti->begin, ti->len, dm_table_get_mode(ti->table), &p->path.dev); @@ -581,7 +581,7 @@ static struct pgpath *parse_path(struct bad: free_pgpath(p); - return NULL; + return ERR_PTR(r); } static struct priority_group *parse_priority_group(struct arg_set *as, @@ -599,14 +599,14 @@ static struct priority_group *parse_prio if (as->argc < 2) { as->argc = 0; - ti->error = "not enough priority group aruments"; - return NULL; + ti->error = "not enough priority group arguments"; + return ERR_PTR(-EINVAL); } pg = alloc_priority_group(); if (!pg) { ti->error = "couldn't allocate priority group"; - return NULL; + return ERR_PTR(-ENOMEM); } pg->m = m; @@ -639,8 +639,10 @@ static struct priority_group *parse_prio path_args.argv = as->argv; pgpath = parse_path(&path_args, &pg->ps, ti); - if (!pgpath) + if (IS_ERR(pgpath)) { + r = PTR_ERR(pgpath); goto bad; + } pgpath->pg = pg; list_add_tail(&pgpath->list, &pg->pgpaths); @@ -651,7 +653,7 @@ static struct priority_group *parse_prio bad: free_priority_group(pg, ti); - return NULL; + return ERR_PTR(r); } static int parse_hw_handler(struct arg_set *as, struct multipath *m) @@ -782,8 +784,8 @@ static int multipath_ctr(struct dm_targe struct priority_group *pg; pg = parse_priority_group(&as, m); - if (!pg) { - r = -EINVAL; + if (IS_ERR(pg)) { + r = PTR_ERR(pg); goto bad; }