Commit e80d1c80 authored by Vivek Goyal's avatar Vivek Goyal Committed by Mike Snitzer

dm: do not override error code returned from dm_get_device()

Some of the device mapper targets override the error code returned by
dm_get_device() and return either -EINVAL or -ENXIO.  There is nothing
gained by this override.  It is better to propagate the returned error
code unchanged to caller.

This work was motivated by hitting an issue where the underlying device
was busy but -EINVAL was being returned.  After this change we get
-EBUSY instead and it is easier to figure out the problem.
Signed-off-by: default avatarVivek Goyal <vgoyal@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent ab37844d
...@@ -1811,11 +1811,13 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -1811,11 +1811,13 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
} }
cc->iv_offset = tmpll; cc->iv_offset = tmpll;
if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev)) { ret = dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev);
if (ret) {
ti->error = "Device lookup failed"; ti->error = "Device lookup failed";
goto bad; goto bad;
} }
ret = -EINVAL;
if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) { if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
ti->error = "Invalid device sector"; ti->error = "Invalid device sector";
goto bad; goto bad;
......
...@@ -129,6 +129,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -129,6 +129,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct delay_c *dc; struct delay_c *dc;
unsigned long long tmpll; unsigned long long tmpll;
char dummy; char dummy;
int ret;
if (argc != 3 && argc != 6) { if (argc != 3 && argc != 6) {
ti->error = "requires exactly 3 or 6 arguments"; ti->error = "requires exactly 3 or 6 arguments";
...@@ -143,6 +144,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -143,6 +144,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
dc->reads = dc->writes = 0; dc->reads = dc->writes = 0;
ret = -EINVAL;
if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) { if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
ti->error = "Invalid device sector"; ti->error = "Invalid device sector";
goto bad; goto bad;
...@@ -154,12 +156,14 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -154,12 +156,14 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad; goto bad;
} }
if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
&dc->dev_read)) { &dc->dev_read);
if (ret) {
ti->error = "Device lookup failed"; ti->error = "Device lookup failed";
goto bad; goto bad;
} }
ret = -EINVAL;
dc->dev_write = NULL; dc->dev_write = NULL;
if (argc == 3) if (argc == 3)
goto out; goto out;
...@@ -175,13 +179,15 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -175,13 +179,15 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad_dev_read; goto bad_dev_read;
} }
if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), ret = dm_get_device(ti, argv[3], dm_table_get_mode(ti->table),
&dc->dev_write)) { &dc->dev_write);
if (ret) {
ti->error = "Write device lookup failed"; ti->error = "Write device lookup failed";
goto bad_dev_read; goto bad_dev_read;
} }
out: out:
ret = -EINVAL;
dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
if (!dc->kdelayd_wq) { if (!dc->kdelayd_wq) {
DMERR("Couldn't start kdelayd"); DMERR("Couldn't start kdelayd");
...@@ -208,7 +214,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -208,7 +214,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
dm_put_device(ti, dc->dev_read); dm_put_device(ti, dc->dev_read);
bad: bad:
kfree(dc); kfree(dc);
return -EINVAL; return ret;
} }
static void delay_dtr(struct dm_target *ti) static void delay_dtr(struct dm_target *ti)
......
...@@ -183,6 +183,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -183,6 +183,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
devname = dm_shift_arg(&as); devname = dm_shift_arg(&as);
r = -EINVAL;
if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) { if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) {
ti->error = "Invalid device sector"; ti->error = "Invalid device sector";
goto bad; goto bad;
...@@ -211,7 +212,8 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -211,7 +212,8 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (r) if (r)
goto bad; goto bad;
if (dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev)) { r = dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev);
if (r) {
ti->error = "Device lookup failed"; ti->error = "Device lookup failed";
goto bad; goto bad;
} }
...@@ -224,7 +226,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -224,7 +226,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
bad: bad:
kfree(fc); kfree(fc);
return -EINVAL; return r;
} }
static void flakey_dtr(struct dm_target *ti) static void flakey_dtr(struct dm_target *ti)
......
...@@ -30,6 +30,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -30,6 +30,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct linear_c *lc; struct linear_c *lc;
unsigned long long tmp; unsigned long long tmp;
char dummy; char dummy;
int ret;
if (argc != 2) { if (argc != 2) {
ti->error = "Invalid argument count"; ti->error = "Invalid argument count";
...@@ -42,13 +43,15 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -42,13 +43,15 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return -ENOMEM; return -ENOMEM;
} }
ret = -EINVAL;
if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1) { if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1) {
ti->error = "dm-linear: Invalid device sector"; ti->error = "dm-linear: Invalid device sector";
goto bad; goto bad;
} }
lc->start = tmp; lc->start = tmp;
if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev)) { ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev);
if (ret) {
ti->error = "dm-linear: Device lookup failed"; ti->error = "dm-linear: Device lookup failed";
goto bad; goto bad;
} }
...@@ -61,7 +64,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -61,7 +64,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
bad: bad:
kfree(lc); kfree(lc);
return -EINVAL; return ret;
} }
static void linear_dtr(struct dm_target *ti) static void linear_dtr(struct dm_target *ti)
......
...@@ -420,6 +420,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -420,6 +420,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct log_writes_c *lc; struct log_writes_c *lc;
struct dm_arg_set as; struct dm_arg_set as;
const char *devname, *logdevname; const char *devname, *logdevname;
int ret;
as.argc = argc; as.argc = argc;
as.argv = argv; as.argv = argv;
...@@ -443,18 +444,22 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -443,18 +444,22 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv)
atomic_set(&lc->pending_blocks, 0); atomic_set(&lc->pending_blocks, 0);
devname = dm_shift_arg(&as); devname = dm_shift_arg(&as);
if (dm_get_device(ti, devname, dm_table_get_mode(ti->table), &lc->dev)) { ret = dm_get_device(ti, devname, dm_table_get_mode(ti->table), &lc->dev);
if (ret) {
ti->error = "Device lookup failed"; ti->error = "Device lookup failed";
goto bad; goto bad;
} }
logdevname = dm_shift_arg(&as); logdevname = dm_shift_arg(&as);
if (dm_get_device(ti, logdevname, dm_table_get_mode(ti->table), &lc->logdev)) { ret = dm_get_device(ti, logdevname, dm_table_get_mode(ti->table),
&lc->logdev);
if (ret) {
ti->error = "Log device lookup failed"; ti->error = "Log device lookup failed";
dm_put_device(ti, lc->dev); dm_put_device(ti, lc->dev);
goto bad; goto bad;
} }
ret = -EINVAL;
lc->log_kthread = kthread_run(log_writes_kthread, lc, "log-write"); lc->log_kthread = kthread_run(log_writes_kthread, lc, "log-write");
if (!lc->log_kthread) { if (!lc->log_kthread) {
ti->error = "Couldn't alloc kthread"; ti->error = "Couldn't alloc kthread";
...@@ -479,7 +484,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -479,7 +484,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv)
bad: bad:
kfree(lc); kfree(lc);
return -EINVAL; return ret;
} }
static int log_mark(struct log_writes_c *lc, char *data) static int log_mark(struct log_writes_c *lc, char *data)
......
...@@ -943,16 +943,18 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti, ...@@ -943,16 +943,18 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
{ {
unsigned long long offset; unsigned long long offset;
char dummy; char dummy;
int ret;
if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1) { if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1) {
ti->error = "Invalid offset"; ti->error = "Invalid offset";
return -EINVAL; return -EINVAL;
} }
if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
&ms->mirror[mirror].dev)) { &ms->mirror[mirror].dev);
if (ret) {
ti->error = "Device lookup failure"; ti->error = "Device lookup failure";
return -ENXIO; return ret;
} }
ms->mirror[mirror].ms = ms; ms->mirror[mirror].ms = ms;
......
...@@ -75,13 +75,15 @@ static int get_stripe(struct dm_target *ti, struct stripe_c *sc, ...@@ -75,13 +75,15 @@ static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
{ {
unsigned long long start; unsigned long long start;
char dummy; char dummy;
int ret;
if (sscanf(argv[1], "%llu%c", &start, &dummy) != 1) if (sscanf(argv[1], "%llu%c", &start, &dummy) != 1)
return -EINVAL; return -EINVAL;
if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
&sc->stripe[stripe].dev)) &sc->stripe[stripe].dev);
return -ENXIO; if (ret)
return ret;
sc->stripe[stripe].physical_start = start; sc->stripe[stripe].physical_start = start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment