linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <nfbrown@novell.com>
To: Heinz Mauelshagen <heinzm@redhat.com>,
	Alasdair G Kergon <agk@redhat.com>
Cc: linux-raid@vger.kernel.org, dm-devel@redhat.com
Subject: [PATCH 7/8] dm-dirty-log: allow log size to be different from target size.
Date: Mon, 26 Jul 2010 13:24:35 +1000	[thread overview]
Message-ID: <20100726032435.29687.63934.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100726032230.29687.5366.stgit@localhost.localdomain>

With RAID1, the dirty log covers the size of the target - the number
of bits is the target size divided by the region size.

For RAID5 and similar the dirty log needs to cover the parity blocks,
so it is best to base the dirty log size on the size of the component
devices rather than the size of the array.

So when creating a dirty log, allow the log_size to be specified
separately from the target, and in raid1, set it to the target length.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 drivers/md/dm-log-userspace-base.c |   11 +++++++----
 drivers/md/dm-log.c                |   18 +++++++++++-------
 drivers/md/dm-raid1.c              |    4 ++--
 include/linux/dm-dirty-log.h       |    3 ++-
 4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 1ed0094..935a49b 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -94,7 +94,7 @@ retry:
 	return -ESRCH;
 }
 
-static int build_constructor_string(struct dm_target *ti,
+static int build_constructor_string(sector_t log_size,
 				    unsigned argc, char **argv,
 				    char **ctr_str)
 {
@@ -114,7 +114,7 @@ static int build_constructor_string(struct dm_target *ti,
 		return -ENOMEM;
 	}
 
-	str_size = sprintf(str, "%llu", (unsigned long long)ti->len);
+	str_size = sprintf(str, "%llu", (unsigned long long)log_size);
 	for (i = 0; i < argc; i++)
 		str_size += sprintf(str + str_size, " %s", argv[i]);
 
@@ -136,6 +136,7 @@ static int build_constructor_string(struct dm_target *ti,
  * else.
  */
 static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+			 sector_t log_size,
 			 unsigned argc, char **argv)
 {
 	int r = 0;
@@ -171,7 +172,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	spin_lock_init(&lc->flush_lock);
 	INIT_LIST_HEAD(&lc->flush_list);
 
-	str_size = build_constructor_string(ti, argc - 1, argv + 1, &ctr_str);
+	str_size = build_constructor_string(log_size,
+					    argc - 1, argv + 1,
+					    &ctr_str);
 	if (str_size < 0) {
 		kfree(lc);
 		return str_size;
@@ -197,7 +200,7 @@ 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->region_count = dm_sector_div_up(log_size, lc->region_size);
 
 out:
 	if (r) {
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 5a08be0..a232c14 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -146,6 +146,7 @@ EXPORT_SYMBOL(dm_dirty_log_type_unregister);
 
 struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
 			struct dm_target *ti,
+			sector_t log_size,
 			int (*flush_callback_fn)(struct dm_target *ti),
 			unsigned int argc, char **argv)
 {
@@ -164,7 +165,7 @@ struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
 
 	log->flush_callback_fn = flush_callback_fn;
 	log->type = type;
-	if (type->ctr(log, ti, argc, argv)) {
+	if (type->ctr(log, ti, log_size, argc, argv)) {
 		kfree(log);
 		put_type(type);
 		return NULL;
@@ -335,9 +336,9 @@ static int read_header(struct log_c *log)
 	return 0;
 }
 
-static int _check_region_size(struct dm_target *ti, uint32_t region_size)
+static int _check_region_size(sector_t log_size, uint32_t region_size)
 {
-	if (region_size < 2 || region_size > ti->len)
+	if (region_size < 2 || region_size > log_size)
 		return 0;
 
 	if (!is_power_of_2(region_size))
@@ -353,6 +354,7 @@ static int _check_region_size(struct dm_target *ti, uint32_t region_size)
  *--------------------------------------------------------------*/
 #define BYTE_SHIFT 3
 static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
+			      sector_t log_size,
 			      unsigned int argc, char **argv,
 			      struct dm_dev *dev)
 {
@@ -382,12 +384,12 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
 	}
 
 	if (sscanf(argv[0], "%u", &region_size) != 1 ||
-	    !_check_region_size(ti, region_size)) {
+	    !_check_region_size(log_size, region_size)) {
 		DMWARN("invalid region size %s", argv[0]);
 		return -EINVAL;
 	}
 
-	region_count = dm_sector_div_up(ti->len, region_size);
+	region_count = dm_sector_div_up(log_size, region_size);
 
 	lc = kmalloc(sizeof(*lc), GFP_KERNEL);
 	if (!lc) {
@@ -507,9 +509,10 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
 }
 
 static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+		    sector_t log_size,
 		    unsigned int argc, char **argv)
 {
-	return create_log_context(log, ti, argc, argv, NULL);
+	return create_log_context(log, ti, log_size, argc, argv, NULL);
 }
 
 static void destroy_log_context(struct log_c *lc)
@@ -533,6 +536,7 @@ static void core_dtr(struct dm_dirty_log *log)
  * argv contains log_device region_size followed optionally by [no]sync
  *--------------------------------------------------------------*/
 static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+		    sector_t log_size,
 		    unsigned int argc, char **argv)
 {
 	int r;
@@ -547,7 +551,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	if (r)
 		return r;
 
-	r = create_log_context(log, ti, argc - 1, argv + 1, dev);
+	r = create_log_context(log, ti, log_size, argc - 1, argv + 1, dev);
 	if (r) {
 		dm_put_device(ti, dev);
 		return r;
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index ddda531..ea732fc 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -968,8 +968,8 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
 		return NULL;
 	}
 
-	dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
-				 argv + 2);
+	dl = dm_dirty_log_create(argv[0], ti, ti->len, mirror_flush,
+				 param_count, argv + 2);
 	if (!dl) {
 		ti->error = "Error creating mirror dirty log";
 		return NULL;
diff --git a/include/linux/dm-dirty-log.h b/include/linux/dm-dirty-log.h
index 7084503..641419f 100644
--- a/include/linux/dm-dirty-log.h
+++ b/include/linux/dm-dirty-log.h
@@ -33,6 +33,7 @@ struct dm_dirty_log_type {
 	struct list_head list;
 
 	int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
+		   sector_t log_size,
 		   unsigned argc, char **argv);
 	void (*dtr)(struct dm_dirty_log *log);
 
@@ -137,7 +138,7 @@ int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type);
  * type->constructor/destructor() directly.
  */
 struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
-			struct dm_target *ti,
+			struct dm_target *ti, sector_t log_size,
 			int (*flush_callback_fn)(struct dm_target *ti),
 			unsigned argc, char **argv);
 void dm_dirty_log_destroy(struct dm_dirty_log *log);



  parent reply	other threads:[~2010-07-26  3:24 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-26  3:24 [PATCH 0/8] The DM part of dm-raid45 NeilBrown
2010-07-26  3:24 ` [PATCH 4/8] dm-raid456: add support for setting IO hints NeilBrown
2010-07-26  3:24 ` NeilBrown [this message]
2010-07-26  3:24 ` [PATCH 5/8] dm-raid456: add suspend/resume method NeilBrown
2010-07-26  3:24 ` [PATCH 2/8] dm-raid456: add congestion checking NeilBrown
2010-07-26  3:24 ` [PATCH 6/8] dm-raid456: add message handler NeilBrown
2010-07-26  3:24 ` [PATCH 3/8] dm-raid456: support unplug NeilBrown
2010-07-26  3:24 ` [PATCH 8/8] dm-raid456: switch to use dm_dirty_log for tracking dirty regions NeilBrown
2010-07-26  3:24 ` [PATCH 1/8] md/dm: create dm-raid456 module using md/raid5 NeilBrown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100726032435.29687.63934.stgit@localhost.localdomain \
    --to=nfbrown@novell.com \
    --cc=agk@redhat.com \
    --cc=dm-devel@redhat.com \
    --cc=heinzm@redhat.com \
    --cc=linux-raid@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).