[dm-devel] [PATCH 2/2] change API of dm-log-userspace to support delay flush

dongmao zhang dmzhang at suse.com
Thu Sep 26 10:50:18 UTC 2013


Signed-off-by: dongmao zhang <dmzhang at suse.com>
---
 drivers/md/dm-log-userspace-base.c    |   80 ++++++++++++++++++++++++---------
 include/uapi/linux/dm-log-userspace.h |    2 +-
 2 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index d5f4a1c..f455d95 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -14,7 +14,7 @@
 #include <linux/workqueue.h>
 #include "dm-log-userspace-transfer.h"
 
-#define DM_LOG_USERSPACE_VSN "1.1.0"
+#define DM_LOG_USERSPACE_VSN "1.2.0"
 
 struct flush_entry {
 	int type;
@@ -30,6 +30,8 @@ struct flush_entry {
  */
 #define MAX_FLUSH_GROUP_COUNT 32
 
+#define SUPPORT_DELAY_FLUSH "support_delay_flush"
+
 struct log_c {
 	struct dm_target *ti;
 	struct dm_dev *log_dev;
@@ -64,6 +66,7 @@ struct log_c {
 	struct workqueue_struct *dmlog_wq;
 	struct delayed_work flush_log_work;
 	atomic_t sched_flush;
+	uint32_t support_delay_flush;
 };
 
 static mempool_t *flush_entry_pool;
@@ -158,6 +161,8 @@ static void do_flush(struct delayed_work *work)
 		dm_table_event(lc->ti->table);
 }
 
+
+
 /*
  * userspace_ctr
  *
@@ -181,7 +186,11 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	uint64_t rdata;
 	size_t rdata_size = sizeof(rdata);
 	char *devices_rdata = NULL;
-	size_t devices_rdata_size = DM_NAME_LEN;
+
+	char *logdev = NULL;
+	char *delay_flush_string = NULL;
+
+	size_t devices_rdata_size = DM_NAME_LEN + sizeof(SUPPORT_DELAY_FLUSH);
 
 	if (argc < 3) {
 		DMWARN("Too few arguments to userspace dirty log");
@@ -251,16 +260,8 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	lc->region_size = (uint32_t)rdata;
 	lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
 
-	lc->dmlog_wq =  alloc_workqueue("dmlogd",
-			WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
-	if (!lc->dmlog_wq) {
-		DMERR("couldn't start dmlogd");
-		r = -ENOMEM;
-		goto out;
-	}
 
-	INIT_DELAYED_WORK(&lc->flush_log_work, do_flush);
-	atomic_set(&lc->sched_flush, 0);
+	lc->support_delay_flush = 0;
 
 	if (devices_rdata_size) {
 		if (devices_rdata[devices_rdata_size - 1] != '\0') {
@@ -268,12 +269,34 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 			r = -EINVAL;
 			goto out;
 		}
-		r = dm_get_device(ti, devices_rdata,
+
+		logdev = strsep(&devices_rdata, " ");
+		delay_flush_string = strsep(&devices_rdata, " ");
+
+		if (delay_flush_string &&
+			!strcmp(delay_flush_string, SUPPORT_DELAY_FLUSH))
+			lc->support_delay_flush = 1;
+
+		r = dm_get_device(ti, logdev,
 				  dm_table_get_mode(ti->table), &lc->log_dev);
 		if (r)
 			DMERR("Failed to register %s with device-mapper",
-			      devices_rdata);
+			      logdev);
 	}
+
+	if (lc->support_delay_flush) {
+		lc->dmlog_wq =  alloc_workqueue("dmlogd",
+				WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
+		if (!lc->dmlog_wq) {
+			DMERR("couldn't start dmlogd");
+			r = -ENOMEM;
+			goto out;
+		}
+
+		INIT_DELAYED_WORK(&lc->flush_log_work, do_flush);
+		atomic_set(&lc->sched_flush, 0);
+	}
+
 out:
 	kfree(devices_rdata);
 	if (r) {
@@ -292,12 +315,14 @@ static void userspace_dtr(struct dm_dirty_log *log)
 {
 	struct log_c *lc = log->context;
 
-	/*flush workqueue*/
-	if (atomic_read(&lc->sched_flush))
-		flush_delayed_work(&lc->flush_log_work);
+	if (lc->support_delay_flush) {
+		/*flush workqueue*/
+		if (atomic_read(&lc->sched_flush))
+			flush_delayed_work(&lc->flush_log_work);
 
-	flush_workqueue(lc->dmlog_wq);
-	destroy_workqueue(lc->dmlog_wq);
+		flush_workqueue(lc->dmlog_wq);
+		destroy_workqueue(lc->dmlog_wq);
+	}
 
 	(void) dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
 				 NULL, 0,
@@ -329,8 +354,8 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
 	int r;
 	struct log_c *lc = log->context;
 
-	/*run planed flush*/
-	if (atomic_read(&lc->sched_flush))
+	/*run planed flush earlier*/
+	if (lc->support_delay_flush && atomic_read(&lc->sched_flush))
 		flush_delayed_work(&lc->flush_log_work);
 
 	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
@@ -539,13 +564,24 @@ static int userspace_flush(struct dm_dirty_log *log)
 	if (r)
 		goto fail;
 
+	/* If we do not support delay flush, just contact
+	 * userspace immediately.
+	 * If we support delay flush and only has clear region,
+	 * we could postpone * the flush command
+	 */
+	if (!lc->support_delay_flush) {
+		r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
+				NULL, 0, NULL, NULL);
+		goto fail;
+	}
+
+	/* when only has clear region,we plan a flush in the furture*/
 	if (!is_clear_list_empty && is_mark_list_empty
 				 && !atomic_read(&lc->sched_flush)) {
-		/* plan a flush */
 		queue_delayed_work(lc->dmlog_wq, &lc->flush_log_work , 3 * HZ);
 		atomic_set(&lc->sched_flush, 1);
+	/* cancel pending flush because we have already flushed in mark_region*/
 	} else {
-		/* cancel pending flush because already flushed in mark_region*/
 		cancel_delayed_work(&lc->flush_log_work);
 		atomic_set(&lc->sched_flush, 0);
 	}
diff --git a/include/uapi/linux/dm-log-userspace.h b/include/uapi/linux/dm-log-userspace.h
index 0678c2a..5fbeb2c 100644
--- a/include/uapi/linux/dm-log-userspace.h
+++ b/include/uapi/linux/dm-log-userspace.h
@@ -386,7 +386,7 @@
  *	            device name that is to be registered with DM via
  *	            'dm_get_device'.
  */
-#define DM_ULOG_REQUEST_VERSION 2
+#define DM_ULOG_REQUEST_VERSION 3
 
 struct dm_ulog_request {
 	/*
-- 
1.7.3.4




More information about the dm-devel mailing list