Kyle McMartin 7140c9d
From ce5fa9851090cc5f3de4139bf0f343eb78d1c568 Mon Sep 17 00:00:00 2001
Kyle McMartin 7140c9d
From: Peter Jones <pjones@redhat.com>
Kyle McMartin 7140c9d
Date: Mon, 11 Oct 2010 15:49:28 -0400
Kyle McMartin 7140c9d
Subject: [PATCH] device-mapper: Allow setting of UUID via rename if not already set
Kyle McMartin 7140c9d
Kyle McMartin 7140c9d
This makes it possible to use DM_DEV_RENAME to add a uuid to a device so
Kyle McMartin 7140c9d
long as one has not been previously set either with DM_DEV_CREATE or
Kyle McMartin 7140c9d
with DM_DEV_RENAME. This is needed because sometimes in it's necessary
Kyle McMartin 7140c9d
to create the device before the uuid is known, and in such cases the
Kyle McMartin 7140c9d
uuid must be filled in after the creation.
Kyle McMartin 7140c9d
Kyle McMartin 7140c9d
Also bump the minor number to 19.
Kyle McMartin 7140c9d
Kyle McMartin 7140c9d
Signed-off-by: Peter Jones <pjones@redhat.com>
Kyle McMartin 7140c9d
---
Kyle McMartin 7140c9d
 drivers/md/dm-ioctl.c    |   95 ++++++++++++++++++++++++++++++++--------------
Kyle McMartin 7140c9d
 include/linux/dm-ioctl.h |   11 ++++-
Kyle McMartin 7140c9d
 2 files changed, 74 insertions(+), 32 deletions(-)
Kyle McMartin 7140c9d
Kyle McMartin 7140c9d
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
Kyle McMartin 7140c9d
index bb6bdc8..d102269 100644
Kyle McMartin 7140c9d
--- a/drivers/md/dm-ioctl.c
Kyle McMartin 7140c9d
+++ b/drivers/md/dm-ioctl.c
Kyle McMartin 7140c9d
@@ -298,15 +298,15 @@ retry:
Kyle McMartin 7140c9d
 static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
Kyle McMartin 7140c9d
 			  const char *new)
Kyle McMartin 7140c9d
 {
Kyle McMartin 7140c9d
-	char *new_name, *old_name;
Kyle McMartin 7140c9d
+	char *new_data, *old_data;
Kyle McMartin 7140c9d
 	struct hash_cell *hc;
Kyle McMartin 7140c9d
 	struct dm_table *table;
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	/*
Kyle McMartin 7140c9d
 	 * duplicate new.
Kyle McMartin 7140c9d
 	 */
Kyle McMartin 7140c9d
-	new_name = kstrdup(new, GFP_KERNEL);
Kyle McMartin 7140c9d
-	if (!new_name)
Kyle McMartin 7140c9d
+	new_data = kstrdup(new, GFP_KERNEL);
Kyle McMartin 7140c9d
+	if (!new_data)
Kyle McMartin 7140c9d
 		return -ENOMEM;
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	down_write(&_hash_lock);
Kyle McMartin 7140c9d
@@ -314,13 +314,18 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
Kyle McMartin 7140c9d
 	/*
Kyle McMartin 7140c9d
 	 * Is new free ?
Kyle McMartin 7140c9d
 	 */
Kyle McMartin 7140c9d
-	hc = __get_name_cell(new);
Kyle McMartin 7140c9d
+	if (*flags & DM_NEW_UUID_FLAG)
Kyle McMartin 7140c9d
+		hc = __get_uuid_cell(new);
Kyle McMartin 7140c9d
+	else
Kyle McMartin 7140c9d
+		hc = __get_name_cell(new);
Kyle McMartin 7140c9d
 	if (hc) {
Kyle McMartin 7140c9d
-		DMWARN("asked to rename to an already existing name %s -> %s",
Kyle McMartin 7140c9d
+		DMWARN("Unable to change %s on device, %s to one that "
Kyle McMartin 7140c9d
+		       "already exists: %s",
Kyle McMartin 7140c9d
+		       (*flags & DM_NEW_UUID_FLAG) ? "uuid" : "name",
Kyle McMartin 7140c9d
 		       old, new);
Kyle McMartin 7140c9d
 		dm_put(hc->md);
Kyle McMartin 7140c9d
 		up_write(&_hash_lock);
Kyle McMartin 7140c9d
-		kfree(new_name);
Kyle McMartin 7140c9d
+		kfree(new_data);
Kyle McMartin 7140c9d
 		return -EBUSY;
Kyle McMartin 7140c9d
 	}
Kyle McMartin 7140c9d
 
7810142
@@ -329,22 +334,46 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
Kyle McMartin 7140c9d
 	 */
Kyle McMartin 7140c9d
 	hc = __get_name_cell(old);
Kyle McMartin 7140c9d
 	if (!hc) {
Kyle McMartin 7140c9d
-		DMWARN("asked to rename a non existent device %s -> %s",
Kyle McMartin 7140c9d
+		DMWARN("Unable to rename non-existent device, %s to %s",
Kyle McMartin 7140c9d
 		       old, new);
Kyle McMartin 7140c9d
 		up_write(&_hash_lock);
Kyle McMartin 7140c9d
-		kfree(new_name);
Kyle McMartin 7140c9d
+		kfree(new_data);
Kyle McMartin 7140c9d
 		return -ENXIO;
Kyle McMartin 7140c9d
 	}
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
-	/*
Kyle McMartin 7140c9d
-	 * rename and move the name cell.
Kyle McMartin 7140c9d
-	 */
Kyle McMartin 7140c9d
-	list_del(&hc->name_list);
Kyle McMartin 7140c9d
-	old_name = hc->name;
Kyle McMartin 7140c9d
-	mutex_lock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
-	hc->name = new_name;
Kyle McMartin 7140c9d
-	mutex_unlock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
-	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
Kyle McMartin 7140c9d
+	if (*flags & DM_NEW_UUID_FLAG) {
Kyle McMartin 7140c9d
+		/*
Kyle McMartin 7140c9d
+		 * Does this device already have a uuid?
Kyle McMartin 7140c9d
+		 */
Kyle McMartin 7140c9d
+		if (hc->uuid) {
Kyle McMartin 7140c9d
+			DMWARN("Unable to change uuid of device, %s because "
Kyle McMartin 7140c9d
+			       "uuid is already set to %s",
Kyle McMartin a2d889c
+			       old, hc->uuid);
7810142
+	 		dm_put(hc->md);
Kyle McMartin 7140c9d
+			up_write(&_hash_lock);
Kyle McMartin 7140c9d
+			kfree(new_data);
Kyle McMartin 7140c9d
+			return -EINVAL;
Kyle McMartin 7140c9d
+		}
Kyle McMartin 7140c9d
+		/*
Kyle McMartin 7140c9d
+		 * change uuid and move the uuid cell.
Kyle McMartin 7140c9d
+		 */
Kyle McMartin 7140c9d
+		list_del(&hc->uuid_list);
Kyle McMartin 7140c9d
+		old_data = hc->uuid;
Kyle McMartin 7140c9d
+		mutex_lock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
+		hc->uuid = new_data;
Kyle McMartin 7140c9d
+		mutex_unlock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
+		list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_data));
Kyle McMartin 7140c9d
+	} else {
Kyle McMartin 7140c9d
+		/*
Kyle McMartin 7140c9d
+		 * rename and move the name cell.
Kyle McMartin 7140c9d
+		 */
Kyle McMartin 7140c9d
+		list_del(&hc->name_list);
Kyle McMartin 7140c9d
+		old_data = hc->name;
Kyle McMartin 7140c9d
+		mutex_lock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
+		hc->name = new_data;
Kyle McMartin 7140c9d
+		mutex_unlock(&dm_hash_cells_mutex);
Kyle McMartin 7140c9d
+		list_add(&hc->name_list, _name_buckets + hash_str(new_data));
Kyle McMartin 7140c9d
+	}
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	/*
Kyle McMartin 7140c9d
 	 * Wake up any dm event waiters.
Kyle McMartin 7140c9d
@@ -360,7 +388,7 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	dm_put(hc->md);
Kyle McMartin 7140c9d
 	up_write(&_hash_lock);
Kyle McMartin 7140c9d
-	kfree(old_name);
Kyle McMartin 7140c9d
+	kfree(old_data);
Kyle McMartin 7140c9d
 	return 0;
Kyle McMartin 7140c9d
 }
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
@@ -773,23 +801,32 @@ static int invalid_str(char *str, void *end)
Kyle McMartin 7140c9d
 static int dev_rename(struct dm_ioctl *param, size_t param_size)
Kyle McMartin 7140c9d
 {
Kyle McMartin 7140c9d
 	int r;
Kyle McMartin 7140c9d
-	char *new_name = (char *) param + param->data_start;
Kyle McMartin 7140c9d
+	char *new_data = (char *) param + param->data_start;
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
-	if (new_name < param->data ||
Kyle McMartin 7140c9d
-	    invalid_str(new_name, (void *) param + param_size) ||
Kyle McMartin 7140c9d
-	    strlen(new_name) > DM_NAME_LEN - 1) {
Kyle McMartin 7140c9d
-		DMWARN("Invalid new logical volume name supplied.");
Kyle McMartin 7140c9d
-		return -EINVAL;
Kyle McMartin 7140c9d
-	}
Kyle McMartin 7140c9d
+	if (param->flags & DM_NEW_UUID_FLAG) {
Kyle McMartin 7140c9d
+		if (new_data < param->data ||
Kyle McMartin 7140c9d
+		    invalid_str(new_data, (void *) param + param_size) ||
Kyle McMartin 7140c9d
+		    strlen(new_data) > DM_UUID_LEN - 1) {
Kyle McMartin 7140c9d
+			DMWARN("Invalid new device uuid supplied.");
Kyle McMartin 7140c9d
+			return -EINVAL;
Kyle McMartin 7140c9d
+		}
Kyle McMartin 7140c9d
+	} else {
Kyle McMartin 7140c9d
+		if (new_data < param->data ||
Kyle McMartin 7140c9d
+		    invalid_str(new_data, (void *) param + param_size) ||
Kyle McMartin 7140c9d
+		    strlen(new_data) > DM_NAME_LEN - 1) {
Kyle McMartin 7140c9d
+			DMWARN("Invalid new device name supplied.");
Kyle McMartin 7140c9d
+			return -EINVAL;
Kyle McMartin 7140c9d
+		}
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
-	r = check_name(new_name);
Kyle McMartin 7140c9d
-	if (r)
Kyle McMartin 7140c9d
-		return r;
Kyle McMartin 7140c9d
+		r = check_name(new_data);
Kyle McMartin 7140c9d
+		if (r)
Kyle McMartin 7140c9d
+			return r;
Kyle McMartin 7140c9d
+	}
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	param->data_size = 0;
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 	return dm_hash_rename(param->event_nr, &param->flags, param->name,
Kyle McMartin 7140c9d
-			      new_name);
Kyle McMartin 7140c9d
+			      new_data);
Kyle McMartin 7140c9d
 }
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
Kyle McMartin 7140c9d
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
Kyle McMartin 7140c9d
index 2c445e1..3bbcb3a 100644
Kyle McMartin 7140c9d
--- a/include/linux/dm-ioctl.h
Kyle McMartin 7140c9d
+++ b/include/linux/dm-ioctl.h
Kyle McMartin 7140c9d
@@ -266,9 +266,9 @@ enum {
Kyle McMartin 7140c9d
 #define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 #define DM_VERSION_MAJOR	4
Kyle McMartin 7140c9d
-#define DM_VERSION_MINOR	17
Kyle McMartin 7140c9d
-#define DM_VERSION_PATCHLEVEL	0
Kyle McMartin 7140c9d
-#define DM_VERSION_EXTRA	"-ioctl (2010-03-05)"
Kyle McMartin 7140c9d
+#define DM_VERSION_MINOR	19
Kyle McMartin 7140c9d
+#define DM_VERSION_PATCHLEVEL	1
Kyle McMartin 7140c9d
+#define DM_VERSION_EXTRA	"-ioctl (2010-10-12)"
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
 /* Status bits */
Kyle McMartin 7140c9d
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
Kyle McMartin 7140c9d
@@ -321,4 +321,9 @@ enum {
Kyle McMartin 7140c9d
  */
Kyle McMartin 7140c9d
 #define DM_UEVENT_GENERATED_FLAG	(1 << 13) /* Out */
Kyle McMartin 7140c9d
 
Kyle McMartin 7140c9d
+/*
Kyle McMartin 7140c9d
+ * If set, rename operates on uuid, not name.
Kyle McMartin 7140c9d
+ */
Kyle McMartin 7140c9d
+#define DM_NEW_UUID_FLAG        (1 << 14) /* In */
Kyle McMartin 7140c9d
+
Kyle McMartin 7140c9d
 #endif				/* _LINUX_DM_IOCTL_H */
Kyle McMartin 7140c9d
-- 
Kyle McMartin 7140c9d
1.7.2.3
Kyle McMartin 7140c9d