Ioctl interface accepts refs by device number, not just name or uuid.
--- diff/drivers/md/dm-ioctl.c	2004-10-04 22:34:01.000000000 +0100
+++ source/drivers/md/dm-ioctl.c	2004-10-04 22:34:15.000000000 +0100
@@ -224,6 +224,7 @@
 	}
 	register_with_devfs(cell);
 	dm_get(md);
+	dm_set_mdptr(md, cell);
 	up_write(&_hash_lock);
 
 	return 0;
@@ -240,6 +241,7 @@
 	list_del(&hc->uuid_list);
 	list_del(&hc->name_list);
 	unregister_with_devfs(hc);
+	dm_set_mdptr(hc->md, NULL);
 	dm_put(hc->md);
 	if (hc->new_map)
 		dm_table_put(hc->new_map);
@@ -579,12 +581,16 @@
 }
 
 /*
- * Always use UUID for lookups if it's present, otherwise use name.
+ * Always use UUID for lookups if it's present, otherwise use name or dev.
  */
 static inline struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
 {
-	return *param->uuid ?
-	    __get_uuid_cell(param->uuid) : __get_name_cell(param->name);
+	if (*param->uuid)
+		return __get_uuid_cell(param->uuid);
+	else if (*param->name)
+		return __get_name_cell(param->name);
+	else
+		return dm_get_mdptr(huge_decode_dev(param->dev));
 }
 
 static inline struct mapped_device *find_device(struct dm_ioctl *param)
@@ -596,6 +602,7 @@
 	hc = __find_device_hash_cell(param);
 	if (hc) {
 		md = hc->md;
+		dm_get(md);
 
 		/*
 		 * Sneakily write in both the name and the uuid
@@ -611,8 +618,6 @@
 			param->flags |= DM_INACTIVE_PRESENT_FLAG;
 		else
 			param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-
-		dm_get(md);
 	}
 	up_read(&_hash_lock);
 
@@ -1265,14 +1270,14 @@
 	    cmd == DM_LIST_VERSIONS_CMD)
 		return 0;
 
-	/* Unless creating, either name or uuid but not both */
-	if (cmd != DM_DEV_CREATE_CMD) {
-		if ((!*param->uuid && !*param->name) ||
-		    (*param->uuid && *param->name)) {
-			DMWARN("one of name or uuid must be supplied, cmd(%u)",
-			       cmd);
+	if ((cmd == DM_DEV_CREATE_CMD)) {
+		if (!*param->name) {
+			DMWARN("name not supplied when creating device");
 			return -EINVAL;
 		}
+	} else if ((*param->uuid && *param->name)) {
+		DMWARN("only supply one of name or uuid, cmd(%u)", cmd);
+		return -EINVAL;
 	}
 
 	/* Ensure strings are terminated */
--- diff/drivers/md/dm.c	2004-10-04 15:13:09.000000000 +0100
+++ source/drivers/md/dm.c	2004-10-04 22:34:15.000000000 +0100
@@ -59,6 +59,8 @@
 	request_queue_t *queue;
 	struct gendisk *disk;
 
+	void *interface_ptr;
+
 	/*
 	 * A list of ios that arrived while we were suspended.
 	 */
@@ -643,7 +645,7 @@
 /*
  * See if the device with a specific minor # is free.
  */
-static int specific_minor(unsigned int minor)
+static int specific_minor(struct mapped_device *md, unsigned int minor)
 {
 	int r, m;
 
@@ -663,7 +665,7 @@
 		goto out;
 	}
 
-	r = idr_get_new_above(&_minor_idr, specific_minor, minor, &m);
+	r = idr_get_new_above(&_minor_idr, md, minor, &m);
 	if (r) {
 		goto out;
 	}
@@ -679,7 +681,7 @@
 	return r;
 }
 
-static int next_free_minor(unsigned int *minor)
+static int next_free_minor(struct mapped_device *md, unsigned int *minor)
 {
 	int r;
 	unsigned int m;
@@ -692,7 +694,7 @@
 		goto out;
 	}
 
-	r = idr_get_new(&_minor_idr, next_free_minor, &m);
+	r = idr_get_new(&_minor_idr, md, &m);
 	if (r) {
 		goto out;
 	}
@@ -726,7 +728,7 @@
 	}
 
 	/* get a minor number for the dev */
-	r = persistent ? specific_minor(minor) : next_free_minor(&minor);
+	r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor);
 	if (r < 0)
 		goto bad1;
 
@@ -883,6 +885,32 @@
 	return create_aux(minor, 1, result);
 }
 
+void *dm_get_mdptr(dev_t dev)
+{
+	struct mapped_device *md;
+	void *mdptr = NULL;
+	unsigned minor = MINOR(dev);
+
+	if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
+		return NULL;
+
+	down(&_minor_lock);
+
+	md = idr_find(&_minor_idr, minor);
+
+	if (md && (dm_disk(md)->first_minor == minor))
+		mdptr = md->interface_ptr;
+
+	up(&_minor_lock);
+
+	return mdptr;
+}
+
+void dm_set_mdptr(struct mapped_device *md, void *ptr)
+{
+	md->interface_ptr = ptr;
+}
+
 void dm_get(struct mapped_device *md)
 {
 	atomic_inc(&md->holders);
--- diff/drivers/md/dm.h	2004-10-04 22:34:01.000000000 +0100
+++ source/drivers/md/dm.h	2004-10-04 22:34:15.000000000 +0100
@@ -54,6 +54,8 @@
  *---------------------------------------------------------------*/
 int dm_create(struct mapped_device **md);
 int dm_create_with_minor(unsigned int minor, struct mapped_device **md);
+void dm_set_mdptr(struct mapped_device *md, void *ptr);
+void *dm_get_mdptr(dev_t dev);
 
 /*
  * Reference counting for md.
--- diff/include/linux/dm-ioctl.h	2004-10-04 22:34:01.000000000 +0100
+++ source/include/linux/dm-ioctl.h	2004-10-04 22:34:16.000000000 +0100
@@ -271,9 +271,9 @@
 #define DM_TARGET_MSG	 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	2
+#define DM_VERSION_MINOR	3
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2004-06-08)"
+#define DM_VERSION_EXTRA	"-ioctl (2004-09-30)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
