Skip to contentSkip to conversation

2.6.0-test5-mm2 Device Mapper Patches

PATCH In review Kevin Corry 3 participants 11 messages Sep 22, 2003 – Sep 23, 2003 Device mapper

lore
Share & tools
lore
#0 lore raw

A handful of minor fixes for Device-Mapper. Joe Thornber asked me to forward these on while he is changing internet connections.

Signature · 3 lines
Kevin Corry
[email protected]
http://evms.sourceforge.net/
#1 lore raw

PATCH 1/1 DM 1/6: Use new format_dev_t macro

Use the format_dev_t function for target status functions.

drivers/md/dm-linear.c +3 -3
@@ -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;
drivers/md/dm-stripe.c +3 -3
@@ -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;
#2 lore raw

Re: [PATCH] DM 1/6: Use new format_dev_t macro

Quoted 1 line · Kevin Corry

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.

#3 lore raw

Re: [PATCH] DM 1/6: Use new format_dev_t macro

Quoted 10 lines · On Monday, September 22, 2003, at 08:29 PM…
Quoted 1 line · Kevin Corry

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

#4 lore raw

Re: [PATCH] DM 1/6: Use new format_dev_t macro

Quoted 9 lines · Joe Thornber
Quoted 5 lines · On Monday, September 22, 2003, at 08:29 PM…
Quoted 1 line · Kevin Corry

Use the format_dev_t function for target status functions.

[instead of bdevname, that is]

Quoted 7 lines
Quoted 5 lines

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?

#5 lore raw

Re: [PATCH] DM 1/6: Use new format_dev_t macro

Quoted 9 lines · On Tuesday 23 September 2003 02:57, [email protected]…
Quoted 8 lines · Joe Thornber

On Monday, September 22, 2003, at 08:29 PM,

Quoted 5 lines · [email protected] wrote:
Quoted 1 line · Kevin Corry

Use the format_dev_t function for target status functions.

[instead of bdevname, that is]

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

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().

Signature · 3 lines
Kevin Corry
[email protected]
http://evms.sourceforge.net/
#6 lore raw

PATCH 1/1 DM 2/6: Drop extra table ref-count

In reply to Kevin Corry

When multiple load ioctls are issued the reference count on older 'new_tables' wasn't being dropped. [Christophe Saout]

drivers/md/dm-ioctl-v4.c +2 -0
@@ -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;
 
#7 lore raw

PATCH 1/1 DM 4/6: Return table status for dev_wait

In reply to Kevin Corry

dev_wait was meant to return table status not dev status. [Alasdair Kergon]

drivers/md/dm-ioctl-v4.c +10 -0
@@ -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;
 }
#8 lore raw

PATCH 1/1 DM 3/6: Move retrieve_status function

In reply to Kevin Corry

Move retrieve_status up so dev_wait() can use it.

drivers/md/dm-ioctl-v4.c +63 -63
@@ -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.
  */
#9 lore raw

PATCH 1/1 DM 5/6: Message fix in dm-linear

In reply to Kevin Corry

Fix error message when linear targets gets handed more than 2 arguments. [Alasdair Kergon]

drivers/md/dm-linear.c +1 -1
@@ -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;
 	}
 
#10 lore raw

PATCH 1/1 DM 6/6: Support arbitrary number of target params

In reply to Kevin Corry

Support an arbitrary number of target parameters. [Alasdair Kergon]

drivers/md/dm-table.c +36 -7
@@ -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;