A handful of minor fixes for Device-Mapper. Joe Thornber asked me to forward
these on while he is changing internet connections.
--
Kevin Corry
[email protected]
http://evms.sourceforge.net/
Move retrieve_status up so dev_wait() can use it.
--- diff/drivers/md/dm-ioctl-v4.c 2003-09-17 13:08:53.000000000 +0100
+++ source/drivers/md/dm-ioctl-v4.c 2003-09-17 13:09:04.000000000 +0100
@@ -700,6 +700,69 @@
}
/*
+ * Build up the status struct for each target
+ */
+static void retrieve_status(struct dm_table *table,
+ struct dm_ioctl *param, size_t param_size)
+{
+ unsigned int i, num_targets;
+ struct dm_target_spec *spec;
+ char *outbuf, *outptr;
+ status_type_t type;
+ size_t remaining, len, used = 0;
+
+ outptr = outbuf = get_result_buffer(param, param_size, &len);
+
+ if (param->flags & DM_STATUS_TABLE_FLAG)
+ type = STATUSTYPE_TABLE;
+ else
+ type = STATUSTYPE_INFO;
+
+ /* Get all the target info */
+ num_targets = dm_table_get_num_targets(table);
+ for (i = 0; i < num_targets; i++) {
+ struct dm_target *ti = dm_table_get_target(table, i);
+
+ remaining = len - (outptr - outbuf);
+ if (remaining < sizeof(struct dm_target_spec)) {
+ param->flags |= DM_BUFFER_FULL_FLAG;
+ break;
+ }
+
+ spec = (struct dm_target_spec *) outptr;
+
+ spec->status = 0;
+ spec->sector_start = ti->begin;
+ spec->length = ti->len;
+ strncpy(spec->target_type, ti->type->name,
+ sizeof(spec->target_type));
+
+ outptr += sizeof(struct dm_target_spec);
+ remaining = len - (outptr - outbuf);
+
+ /* Get the status/table string from the target driver */
+ if (ti->type->status) {
+ if (ti->type->status(ti, type, outptr, remaining)) {
+ param->flags |= DM_BUFFER_FULL_FLAG;
+ break;
+ }
+ } else
+ outptr[0] = '\0';
+
+ outptr += strlen(outptr) + 1;
+ used = param->data_start + (outptr - outbuf);
+
+ align_ptr(outptr);
+ spec->next = outptr - outbuf;
+ }
+
+ if (used)
+ param->data_size = used;
+
+ param->target_count = num_targets;
+}
+
+/*
* Wait for a device to report an event
*/
static int dev_wait(struct dm_ioctl *param, size_t param_size)
@@ -920,69 +983,6 @@
}
/*
- * Build up the status struct for each target
- */
-static void retrieve_status(struct dm_table *table,
- struct dm_ioctl *param, size_t param_size)
-{
- unsigned int i, num_targets;
- struct dm_target_spec *spec;
- char *outbuf, *outptr;
- status_type_t type;
- size_t remaining, len, used = 0;
-
- outptr = outbuf = get_result_buffer(param, param_size, &len);
-
- if (param->flags & DM_STATUS_TABLE_FLAG)
- type = STATUSTYPE_TABLE;
- else
- type = STATUSTYPE_INFO;
-
- /* Get all the target info */
- num_targets = dm_table_get_num_targets(table);
- for (i = 0; i < num_targets; i++) {
- struct dm_target *ti = dm_table_get_target(table, i);
-
- remaining = len - (outptr - outbuf);
- if (remaining < sizeof(struct dm_target_spec)) {
- param->flags |= DM_BUFFER_FULL_FLAG;
- break;
- }
-
- spec = (struct dm_target_spec *) outptr;
-
- spec->status = 0;
- spec->sector_start = ti->begin;
- spec->length = ti->len;
- strncpy(spec->target_type, ti->type->name,
- sizeof(spec->target_type));
-
- outptr += sizeof(struct dm_target_spec);
- remaining = len - (outptr - outbuf);
-
- /* Get the status/table string from the target driver */
- if (ti->type->status) {
- if (ti->type->status(ti, type, outptr, remaining)) {
- param->flags |= DM_BUFFER_FULL_FLAG;
- break;
- }
- } else
- outptr[0] = '\0';
-
- outptr += strlen(outptr) + 1;
- used = param->data_start + (outptr - outbuf);
-
- align_ptr(outptr);
- spec->next = outptr - outbuf;
- }
-
- if (used)
- param->data_size = used;
-
- param->target_count = num_targets;
-}
-
-/*
* Return the status of a device as a text string for each
* target.
*/
Support an arbitrary number of target parameters. [Alasdair Kergon]
--- diff/drivers/md/dm-table.c 2003-09-17 12:28:06.000000000 +0100
+++ source/drivers/md/dm-table.c 2003-09-17 13:09:41.000000000 +0100
@@ -534,12 +534,36 @@
}
/*
+ * Used to dynamically allocate the arg array.
+ */
+static char **realloc_argv(unsigned *array_size, char **old_argv)
+{
+ char **argv;
+ unsigned new_size;
+
+ new_size = *array_size ? *array_size * 2 : 64;
+ argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL);
+ if (argv) {
+ memcpy(argv, old_argv, *array_size * sizeof(*argv));
+ *array_size = new_size;
+ }
+
+ kfree(old_argv);
+ return argv;
+}
+
+/*
* Destructively splits up the argument list to pass to ctr.
*/
-static int split_args(int max, int *argc, char **argv, char *input)
+static int split_args(int *argc, char ***argvp, char *input)
{
- char *start, *end = input, *out;
+ char *start, *end = input, *out, **argv = NULL;
+ unsigned array_size = 0;
+
*argc = 0;
+ argv = realloc_argv(&array_size, argv);
+ if (!argv)
+ return -ENOMEM;
while (1) {
start = end;
@@ -568,8 +592,11 @@
}
/* have we already filled the array ? */
- if ((*argc + 1) > max)
- return -EINVAL;
+ if ((*argc + 1) > array_size) {
+ argv = realloc_argv(&array_size, argv);
+ if (!argv)
+ return -ENOMEM;
+ }
/* we know this is whitespace */
if (*end)
@@ -581,6 +608,7 @@
(*argc)++;
}
+ *argvp = argv;
return 0;
}
@@ -588,7 +616,7 @@
sector_t start, sector_t len, char *params)
{
int r = -EINVAL, argc;
- char *argv[32];
+ char **argv;
struct dm_target *tgt;
if ((r = check_space(t)))
@@ -617,13 +645,14 @@
goto bad;
}
- r = split_args(ARRAY_SIZE(argv), &argc, argv, params);
+ r = split_args(&argc, &argv, params);
if (r) {
- tgt->error = "couldn't split parameters";
+ tgt->error = "couldn't split parameters (insufficient memory)";
goto bad;
}
r = tgt->type->ctr(tgt, argc, argv);
+ kfree(argv);
if (r)
goto bad;
Fix error message when linear targets gets handed more than 2 arguments.
[Alasdair Kergon]
--- diff/drivers/md/dm-linear.c 2003-09-17 13:08:44.000000000 +0100
+++ source/drivers/md/dm-linear.c 2003-09-17 13:09:34.000000000 +0100
@@ -28,7 +28,7 @@
struct linear_c *lc;
if (argc != 2) {
- ti->error = "dm-linear: Not enough arguments";
+ ti->error = "dm-linear: Invalid argument count";
return -EINVAL;
}
dev_wait was meant to return table status not dev status. [Alasdair Kergon]
--- diff/drivers/md/dm-ioctl-v4.c 2003-09-17 13:09:04.000000000 +0100
+++ source/drivers/md/dm-ioctl-v4.c 2003-09-17 13:09:26.000000000 +0100
@@ -769,6 +769,7 @@
{
int r;
struct mapped_device *md;
+ struct dm_table *table;
DECLARE_WAITQUEUE(wq, current);
md = find_device(param);
@@ -791,7 +792,16 @@
* him and save an ioctl.
*/
r = __dev_status(md, param);
+ if (r)
+ goto out;
+
+ table = dm_get_table(md);
+ if (table) {
+ retrieve_status(table, param, param_size);
+ dm_table_put(table);
+ }
+ out:
dm_put(md);
return r;
}
When multiple load ioctls are issued the reference count on older
'new_tables' wasn't being dropped. [Christophe Saout]
--- diff/drivers/md/dm-ioctl-v4.c 2003-09-17 12:28:06.000000000 +0100
+++ source/drivers/md/dm-ioctl-v4.c 2003-09-17 13:08:53.000000000 +0100
@@ -817,6 +817,8 @@
return -ENXIO;
}
+ if (hc->new_map)
+ dm_table_put(hc->new_map);
hc->new_map = t;
param->flags |= DM_INACTIVE_PRESENT_FLAG;
Use the format_dev_t function for target status functions.
--- diff/drivers/md/dm-linear.c 2003-06-30 10:07:21.000000000 +0100
+++ source/drivers/md/dm-linear.c 2003-09-17 13:08:44.000000000 +0100
@@ -79,7 +79,7 @@
char *result, unsigned int maxlen)
{
struct linear_c *lc = (struct linear_c *) ti->private;
- char b[BDEVNAME_SIZE];
+ char buffer[32];
switch (type) {
case STATUSTYPE_INFO:
@@ -87,8 +87,8 @@
break;
case STATUSTYPE_TABLE:
- snprintf(result, maxlen, "%s " SECTOR_FORMAT,
- bdevname(lc->dev->bdev, b), lc->start);
+ format_dev_t(buffer, lc->dev->bdev->bd_dev);
+ snprintf(result, maxlen, "%s " SECTOR_FORMAT, buffer, lc->start);
break;
}
return 0;
--- diff/drivers/md/dm-stripe.c 2003-08-20 14:16:28.000000000 +0100
+++ source/drivers/md/dm-stripe.c 2003-09-17 13:08:44.000000000 +0100
@@ -187,7 +187,7 @@
struct stripe_c *sc = (struct stripe_c *) ti->private;
int offset;
unsigned int i;
- char b[BDEVNAME_SIZE];
+ char buffer[32];
switch (type) {
case STATUSTYPE_INFO:
@@ -198,10 +198,10 @@
offset = snprintf(result, maxlen, "%d " SECTOR_FORMAT,
sc->stripes, sc->chunk_mask + 1);
for (i = 0; i < sc->stripes; i++) {
+ format_dev_t(buffer, sc->stripe[i].dev->bdev->bd_dev);
offset +=
snprintf(result + offset, maxlen - offset,
- " %s " SECTOR_FORMAT,
- bdevname(sc->stripe[i].dev->bdev, b),
+ " %s " SECTOR_FORMAT, buffer,
sc->stripe[i].physical_start);
}
break;
On Mon, Sep 22, 2003 at 10:51:27AM -0500, Kevin Corry wrote:
> Use the format_dev_t function for target status functions.
[instead of bdevname, that is]
It's wrong. Simply because "sdb3" is immediately parsed by admin and
08:13 is nowhere near that convenient. These are error messages, let's
keep them readable.
On Tue, Sep 23, 2003 at 08:57:07AM +0100, Joe Thornber wrote:
>
> On Monday, September 22, 2003, at 08:29 PM,
> [email protected] wrote:
>
> >On Mon, Sep 22, 2003 at 10:51:27AM -0500, Kevin Corry wrote:
> >>Use the format_dev_t function for target status functions.
> >
> >[instead of bdevname, that is]
> >
> >It's wrong. Simply because "sdb3" is immediately parsed by admin and
> >08:13 is nowhere near that convenient. These are error messages, let's
> >keep them readable.
> >
> >
>
> No they are not just error messages, userland tools use them.
In which case the change in question would break said userland tools, wouldn't
it?
On Monday, September 22, 2003, at 08:29 PM,
[email protected] wrote:
> On Mon, Sep 22, 2003 at 10:51:27AM -0500, Kevin Corry wrote:
>> Use the format_dev_t function for target status functions.
>
> [instead of bdevname, that is]
>
> It's wrong. Simply because "sdb3" is immediately parsed by admin and
> 08:13 is nowhere near that convenient. These are error messages, let's
> keep them readable.
>
>
No they are not just error messages, userland tools use them.
- Joe
On Tuesday 23 September 2003 02:57, [email protected]
wrote:
> On Tue, Sep 23, 2003 at 08:57:07AM +0100, Joe Thornber wrote:
> > On Monday, September 22, 2003, at 08:29 PM,
> >
> > [email protected] wrote:
> > >On Mon, Sep 22, 2003 at 10:51:27AM -0500, Kevin Corry wrote:
> > >>Use the format_dev_t function for target status functions.
> > >
> > >[instead of bdevname, that is]
> > >
> > >It's wrong. Simply because "sdb3" is immediately parsed by admin and
> > >08:13 is nowhere near that convenient. These are error messages, let's
> > >keep them readable.
> >
> > No they are not just error messages, userland tools use them.
>
> In which case the change in question would break said userland tools,
> wouldn't it?
No, actually this change brings the status info back in-line with how the 2.4
version of DM behaves. A while back the bdevname() function changed to return
a text name (it used to return a major:minor, similar to kdevname in 2.4). In
many cases the only way to make any sense of this text name is to search
around in sysfs for a matching entry (provided, of course, that sysfs is
mounted, which many people still don't realize they should be doing. :) And
if you find that entry in sysfs, the info you're really looking for is in the
"dev" file, whose contents are displayed using format_dev_t().
--
Kevin Corry
[email protected]
http://evms.sourceforge.net/