[dm-devel] [RFC][PATCH 4/4] dm-log: interface update for multiple log devices

Takahiro Yasui tyasui at redhat.com
Wed Nov 26 00:01:43 UTC 2008


This patch introduces a new interface for multi-log devices. disk log
has two interfaces, constructor and status, and disk_ctr function and
disk_status functions are extended to handle multiple log device paths.

 - Current interface

    disk_ctr():
        log_path region_size [[no]sync]

    disk_status() - STATUSTYPE_INFO:
        nr_params disk log_path log_status:"A" or "D"

    disk_status() - STATUSTYPE_TABLE:
        disk nr_params log_path region_size [[no]sync]


 - Proposed interface

    disk_ctr():
        [log_path]{1,} region_size [[no]sync]

    disk_status() - STATUSTYPE_INFO:
        nr_params disk [log_path]{1,} [log_status:"A" or "D"]{1,}

    disk_status() - STATUSTYPE_TABLE:
        disk nr_params [log_path]{1,} region_size [[no]sync]


Signed-off-by: Takahiro Yasui <tyasui at redhat.com>
---
 drivers/md/dm-log.c   |   75 ++++++++++++++++++++++++++++++++++++++------------
 drivers/md/dm-raid1.c |    2 -
 2 files changed, 59 insertions(+), 18 deletions(-)

Index: linux-2.6.28-rc4/drivers/md/dm-log.c
===================================================================
--- linux-2.6.28-rc4.orig/drivers/md/dm-log.c
+++ linux-2.6.28-rc4/drivers/md/dm-log.c
@@ -11,7 +11,7 @@
 #include <linux/vmalloc.h>
 #include <linux/dm-io.h>
 #include <linux/dm-dirty-log.h>
-
+#include <linux/dm-kcopyd.h>
 #include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "dirty region log"
@@ -536,8 +536,40 @@ static size_t log_buffer_size(struct log
 }
 
 static int parse_params(unsigned int argc, char **argv,
-			uint32_t *region_size, enum sync *sync)
+			unsigned int *nr_logs, uint32_t *region_size,
+			enum sync *sync)
 {
+	unsigned long tmp_region;
+	int i;
+
+	if (argc && nr_logs) {
+		/*
+		 * case of disk log
+		 *
+		 * find region_size param from the end as a number string
+		 * and get the number of log devices
+		 */
+		for (i = argc - 1; i >= 0; i--)
+			if (!strict_strtoul(argv[i], 10, &tmp_region))
+				break;
+
+		if (i < 0) {
+			DMWARN("invalid region size to dirty region log");
+			return -EINVAL;
+		}
+
+		/* limit the same number as mirror disk */
+		if (i < 1 || i > DM_KCOPYD_MAX_REGIONS + 1) {
+			DMWARN("Invalid number of dirty region log devices");
+			return -EINVAL;
+		}
+
+		*nr_logs = i;
+
+		argc -= i;
+		argv += i;
+	}
+
 	/*
 	 * check number of parameters
 	 */
@@ -757,7 +789,7 @@ static int core_ctr(struct dm_dirty_log 
 	enum sync sync;
 	int r;
 
-	r = parse_params(argc, argv, &region_size, &sync);
+	r = parse_params(argc, argv, NULL, &region_size, &sync);
 	if (r)
 		return r;
 
@@ -786,26 +818,22 @@ static void core_dtr(struct dm_dirty_log
 /*----------------------------------------------------------------
  * disks log constructor/destructor
  *
- * argv contains log_device region_size followed optionally by [no]sync
+ * argv contains [log_path]{1,} region_size [[no]sync]
  *--------------------------------------------------------------*/
 static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 		    unsigned int argc, char **argv)
 {
 	struct log_c *lc;
+	unsigned int nr_logs;
 	uint32_t region_size;
 	enum sync sync;
 	int r;
 
-	if (!argc) {
-		DMWARN("wrong number of arguments to dirty region log");
-		return -EINVAL;
-	}
-
-	r = parse_params(argc-1, argv+1, &region_size, &sync);
+	r = parse_params(argc, argv, &nr_logs, &region_size, &sync);
 	if (r)
 		return r;
 
-	lc = create_log_context(ti, 1, region_size, sync);
+	lc = create_log_context(ti, nr_logs, region_size, sync);
 	if (!lc)
 		return -ENOMEM;
 
@@ -1032,19 +1060,32 @@ static int core_status(struct dm_dirty_l
 static int disk_status(struct dm_dirty_log *log, status_type_t status,
 		       char *result, unsigned int maxlen)
 {
-	int sz = 0;
 	struct log_c *lc = log->context;
+	char buffer[lc->nr_logs + 1];
+	unsigned int i;
+	int sz = 0;
+	int params;
 
 	switch(status) {
 	case STATUSTYPE_INFO:
-		DMEMIT("3 %s %s %c", log->type->name, lc->log[0].dev->name,
-		       lc->log[0].failed ? 'D' : 'A');
+		DMEMIT("%d %s ", lc->nr_logs + 2, log->type->name);
+		for (i = 0; i < lc->nr_logs; i++) {
+			DMEMIT("%s ", lc->log[i].dev->name);
+			buffer[i] = lc->log[i].failed ? 'D' : 'A';
+		}
+		buffer[i] = '\0';
+		DMEMIT("%s", buffer);
 		break;
 
 	case STATUSTYPE_TABLE:
-		DMEMIT("%s %u %s %u ", log->type->name,
-		       lc->sync == DEFAULTSYNC ? 2 : 3, lc->log[0].dev->name,
-		       lc->region_size);
+		params = lc->nr_logs + 1;
+		params += (lc->sync == DEFAULTSYNC) ? 0 : 1;
+		DMEMIT("%s %d ", log->type->name, params);
+
+		for (i = 0; i < lc->nr_logs; i++)
+			DMEMIT("%s ", lc->log[i].dev->name);
+
+		DMEMIT("%u ", lc->region_size);
 		DMEMIT_SYNC;
 	}
 
Index: linux-2.6.28-rc4/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.28-rc4.orig/drivers/md/dm-raid1.c
+++ linux-2.6.28-rc4/drivers/md/dm-raid1.c
@@ -926,7 +926,7 @@ static int parse_features(struct mirror_
  * [#features <features>]
  *
  * log_type is "core" or "disk"
- * #log_params is between 1 and 3
+ * #log_params is more than 0
  *
  * If present, features must be "handle_errors".
  */




More information about the dm-devel mailing list