* [PATCH 7 of 8] MD: add bitmap support
@ 2011-06-07 22:52 Jonathan Brassow
2011-06-08 5:18 ` NeilBrown
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Brassow @ 2011-06-07 22:52 UTC (permalink / raw)
To: linux-raid
Add bitmap support to the device-mapper specific metadata area.
This patch allows the creation of the bitmap metadata area upon initial array
creation via device-mapper.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Index: linux-2.6/drivers/md/bitmap.c
===================================================================
--- linux-2.6.orig/drivers/md/bitmap.c
+++ linux-2.6/drivers/md/bitmap.c
@@ -534,6 +534,84 @@ void bitmap_print_sb(struct bitmap *bitm
kunmap_atomic(sb, KM_USER0);
}
+/*
+ * bitmap_new_disk_sb
+ * @bitmap
+ *
+ * This function is somewhat the reverse of bitmap_read_sb. bitmap_read_sb
+ * reads and verifies the on-disk bitmap superblock and populates bitmap_info.
+ * This function verifies 'bitmap_info' and populates the on-disk bitmap
+ * structure, which is to be written to disk.
+ *
+ * Returns: 0 on success, -Exxx on error
+ */
+static int bitmap_new_disk_sb(struct bitmap *bitmap)
+{
+ bitmap_super_t *sb;
+ unsigned long chunksize, daemon_sleep, write_behind;
+ int err = -EINVAL;
+
+ /* page 0 is the superblock, read it... */
+ bitmap->sb_page = read_sb_page(bitmap->mddev,
+ bitmap->mddev->bitmap_info.offset,
+ NULL, 0, sizeof(bitmap_super_t));
+
+ if (IS_ERR(bitmap->sb_page)) {
+ err = PTR_ERR(bitmap->sb_page);
+ bitmap->sb_page = NULL;
+ return err;
+ }
+
+ sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+
+ sb->magic = cpu_to_le32(BITMAP_MAGIC);
+ sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
+
+ chunksize = bitmap->mddev->bitmap_info.chunksize;
+ BUG_ON(!chunksize);
+ if ((1 << ffz(~chunksize)) != chunksize) {
+ kunmap_atomic(sb, KM_USER0);
+ printk(KERN_ERR "bitmap chunksize not a power of 2\n");
+ return -EINVAL;
+ }
+ sb->chunksize = cpu_to_le32(chunksize);
+
+ daemon_sleep = bitmap->mddev->bitmap_info.daemon_sleep;
+ if (!daemon_sleep ||
+ (daemon_sleep < 1) || (daemon_sleep > MAX_SCHEDULE_TIMEOUT)) {
+ printk(KERN_INFO "Choosing daemon_sleep default (5 sec)\n");
+ daemon_sleep = 5 * HZ;
+ }
+ sb->daemon_sleep = cpu_to_le32(daemon_sleep);
+ bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
+
+ /*
+ * FIXME: write_behind for RAID1. If not specified, what
+ * is a good choice? We choose COUNTER_MAX / 2 arbitrarily.
+ */
+ write_behind = bitmap->mddev->bitmap_info.max_write_behind;
+ if (write_behind > COUNTER_MAX)
+ write_behind = COUNTER_MAX / 2;
+ sb->write_behind = cpu_to_le32(write_behind);
+ bitmap->mddev->bitmap_info.max_write_behind = write_behind;
+
+ /* keep the array size field of the bitmap superblock up to date */
+ sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
+
+ memcpy(sb->uuid, bitmap->mddev->uuid, 16);
+
+ bitmap->flags |= BITMAP_STALE;
+ sb->state |= cpu_to_le32(BITMAP_STALE);
+ bitmap->events_cleared = bitmap->mddev->events;
+ sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
+
+ bitmap->flags |= BITMAP_HOSTENDIAN;
+ sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
+
+ kunmap_atomic(sb, KM_USER0);
+ return 0;
+}
+
/* read the superblock from the bitmap file and initialize some bitmap fields */
static int bitmap_read_sb(struct bitmap *bitmap)
{
@@ -1076,8 +1154,8 @@ static int bitmap_init_from_disk(struct
}
printk(KERN_INFO "%s: bitmap initialized from disk: "
- "read %lu/%lu pages, set %lu bits\n",
- bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt);
+ "read %lu/%lu pages, set %lu of %lu bits\n",
+ bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, chunks);
return 0;
@@ -1728,9 +1806,16 @@ int bitmap_create(mddev_t *mddev)
vfs_fsync(file, 1);
}
/* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */
- if (!mddev->bitmap_info.external)
- err = bitmap_read_sb(bitmap);
- else {
+ if (!mddev->bitmap_info.external) {
+ /*
+ * If 'MD_ARRAY_FIRST_USE' is set, then device-mapper is
+ * instructing us to create a new on-disk bitmap instance.
+ */
+ if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags))
+ err = bitmap_new_disk_sb(bitmap);
+ else
+ err = bitmap_read_sb(bitmap);
+ } else {
err = 0;
if (mddev->bitmap_info.chunksize == 0 ||
mddev->bitmap_info.daemon_sleep == 0)
Index: linux-2.6/drivers/md/md.h
===================================================================
--- linux-2.6.orig/drivers/md/md.h
+++ linux-2.6/drivers/md/md.h
@@ -124,6 +124,7 @@ struct mddev_s
#define MD_CHANGE_DEVS 0 /* Some device status has changed */
#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
#define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */
+#define MD_ARRAY_FIRST_USE 3 /* First use of array, needs initialization */
int suspended;
atomic_t active_io;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH 7 of 8] MD: add bitmap support
2011-06-07 22:52 [PATCH 7 of 8] MD: add bitmap support Jonathan Brassow
@ 2011-06-08 5:18 ` NeilBrown
0 siblings, 0 replies; 2+ messages in thread
From: NeilBrown @ 2011-06-08 5:18 UTC (permalink / raw)
To: Jonathan Brassow; +Cc: linux-raid
On Tue, 07 Jun 2011 17:52:39 -0500 Jonathan Brassow <jbrassow@redhat.com>
wrote:
> Add bitmap support to the device-mapper specific metadata area.
>
> This patch allows the creation of the bitmap metadata area upon initial array
> creation via device-mapper.
>
> Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
>
> Index: linux-2.6/drivers/md/bitmap.c
> ===================================================================
> --- linux-2.6.orig/drivers/md/bitmap.c
> +++ linux-2.6/drivers/md/bitmap.c
> @@ -534,6 +534,84 @@ void bitmap_print_sb(struct bitmap *bitm
> kunmap_atomic(sb, KM_USER0);
> }
>
> +/*
> + * bitmap_new_disk_sb
> + * @bitmap
> + *
> + * This function is somewhat the reverse of bitmap_read_sb. bitmap_read_sb
> + * reads and verifies the on-disk bitmap superblock and populates bitmap_info.
> + * This function verifies 'bitmap_info' and populates the on-disk bitmap
> + * structure, which is to be written to disk.
> + *
> + * Returns: 0 on success, -Exxx on error
> + */
> +static int bitmap_new_disk_sb(struct bitmap *bitmap)
> +{
> + bitmap_super_t *sb;
> + unsigned long chunksize, daemon_sleep, write_behind;
> + int err = -EINVAL;
> +
> + /* page 0 is the superblock, read it... */
> + bitmap->sb_page = read_sb_page(bitmap->mddev,
> + bitmap->mddev->bitmap_info.offset,
> + NULL, 0, sizeof(bitmap_super_t));
> +
I don't understand ... why are you reading the page from disk when you don't
expect anything to be there are are about to create an initial bitmap
superblock?
Shouldn't this just be
bitmap->sb_page = alloc_page(GFP_KERNEL);
??
> + if (IS_ERR(bitmap->sb_page)) {
> + err = PTR_ERR(bitmap->sb_page);
> + bitmap->sb_page = NULL;
> + return err;
> + }
> +
> + sb = kmap_atomic(bitmap->sb_page, KM_USER0);
> +
> + sb->magic = cpu_to_le32(BITMAP_MAGIC);
> + sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
> +
> + chunksize = bitmap->mddev->bitmap_info.chunksize;
> + BUG_ON(!chunksize);
> + if ((1 << ffz(~chunksize)) != chunksize) {
Please use is_power_of_2(chunksize) - defined in log2.h
Otherwise it looks OK.
NeilBrown
> + kunmap_atomic(sb, KM_USER0);
> + printk(KERN_ERR "bitmap chunksize not a power of 2\n");
> + return -EINVAL;
> + }
> + sb->chunksize = cpu_to_le32(chunksize);
> +
> + daemon_sleep = bitmap->mddev->bitmap_info.daemon_sleep;
> + if (!daemon_sleep ||
> + (daemon_sleep < 1) || (daemon_sleep > MAX_SCHEDULE_TIMEOUT)) {
> + printk(KERN_INFO "Choosing daemon_sleep default (5 sec)\n");
> + daemon_sleep = 5 * HZ;
> + }
> + sb->daemon_sleep = cpu_to_le32(daemon_sleep);
> + bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
> +
> + /*
> + * FIXME: write_behind for RAID1. If not specified, what
> + * is a good choice? We choose COUNTER_MAX / 2 arbitrarily.
> + */
> + write_behind = bitmap->mddev->bitmap_info.max_write_behind;
> + if (write_behind > COUNTER_MAX)
> + write_behind = COUNTER_MAX / 2;
> + sb->write_behind = cpu_to_le32(write_behind);
> + bitmap->mddev->bitmap_info.max_write_behind = write_behind;
> +
> + /* keep the array size field of the bitmap superblock up to date */
> + sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
> +
> + memcpy(sb->uuid, bitmap->mddev->uuid, 16);
> +
> + bitmap->flags |= BITMAP_STALE;
> + sb->state |= cpu_to_le32(BITMAP_STALE);
> + bitmap->events_cleared = bitmap->mddev->events;
> + sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
> +
> + bitmap->flags |= BITMAP_HOSTENDIAN;
> + sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
> +
> + kunmap_atomic(sb, KM_USER0);
> + return 0;
> +}
> +
> /* read the superblock from the bitmap file and initialize some bitmap fields */
> static int bitmap_read_sb(struct bitmap *bitmap)
> {
> @@ -1076,8 +1154,8 @@ static int bitmap_init_from_disk(struct
> }
>
> printk(KERN_INFO "%s: bitmap initialized from disk: "
> - "read %lu/%lu pages, set %lu bits\n",
> - bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt);
> + "read %lu/%lu pages, set %lu of %lu bits\n",
> + bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, chunks);
>
> return 0;
>
> @@ -1728,9 +1806,16 @@ int bitmap_create(mddev_t *mddev)
> vfs_fsync(file, 1);
> }
> /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */
> - if (!mddev->bitmap_info.external)
> - err = bitmap_read_sb(bitmap);
> - else {
> + if (!mddev->bitmap_info.external) {
> + /*
> + * If 'MD_ARRAY_FIRST_USE' is set, then device-mapper is
> + * instructing us to create a new on-disk bitmap instance.
> + */
> + if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags))
> + err = bitmap_new_disk_sb(bitmap);
> + else
> + err = bitmap_read_sb(bitmap);
> + } else {
> err = 0;
> if (mddev->bitmap_info.chunksize == 0 ||
> mddev->bitmap_info.daemon_sleep == 0)
> Index: linux-2.6/drivers/md/md.h
> ===================================================================
> --- linux-2.6.orig/drivers/md/md.h
> +++ linux-2.6/drivers/md/md.h
> @@ -124,6 +124,7 @@ struct mddev_s
> #define MD_CHANGE_DEVS 0 /* Some device status has changed */
> #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
> #define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */
> +#define MD_ARRAY_FIRST_USE 3 /* First use of array, needs initialization */
>
> int suspended;
> atomic_t active_io;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-06-08 5:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-07 22:52 [PATCH 7 of 8] MD: add bitmap support Jonathan Brassow
2011-06-08 5:18 ` NeilBrown
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).