===================================================================
@@ -1802,9 +1802,24 @@ static int super_2_load(mdk_rdev_t *rdev
sb = (struct mdp_superblock_2 *)page_address(rdev->sb_page);
if (sb->magic != cpu_to_le32(MD_DM_SB_MAGIC)) {
+ /*
+ * If we are in this function at all, it means that
+ * the device-mapper interface is being used /and/
+ * metadata devices have been allocated and specified.
+ *
+ * If no superblock has been found, then we must create
+ * a new one - including a new bitmap. First, populate
+ * the superblock with good info. Then set the bitmap's
+ * chunksize, which has the effect of notifying 'bitmap_create'
+ * to allocate the bitmap's superblock page. Finally,
+ * ensure that the changes will be written by setting
+ * MD_CHANGE_DEVS.
+ */
printk(KERN_INFO " Superblock not found: creating new\n");
super_2_sync(rdev->mddev, rdev);
+ rdev->mddev->bitmap_info.chunksize = rdev->mddev->chunk_sectors;
+
/* Force new superblocks to disk */
set_bit(MD_CHANGE_DEVS, &rdev->mddev->flags);
@@ -1865,7 +1880,7 @@ static int super_2_validate(mddev_t *mdd
}
}
- rdev->mddev->bitmap_info.offset = 0; /* disable bitmap creation */
+ mddev->bitmap_info.offset = 1024 >> 9; /* enable bitmap creation */
rdev->mddev->bitmap_info.default_offset = 1024 >> 9;
/*
===================================================================
@@ -533,6 +533,90 @@ 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)
+{
+ char *reason = NULL;
+ bitmap_super_t *sb;
+ unsigned long chunksize, daemon_sleep, write_behind;
+ unsigned long long events;
+ int err = -EINVAL;
+
+ printk("CREATING NEW BITMAP SUPERBLOCK\n");
+
+ /* page 0 is the superblock, read it... */
+ /* FIXME: It's probably enough to just allocate the page */
+ 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)) {
+ /* FIXME: A guess */
+ printk(KERN_INFO "Guessing at good daemon_sleep default\n");
+ daemon_sleep = MAX_SCHEDULE_TIMEOUT / 2;
+ }
+ sb->daemon_sleep = cpu_to_le32(daemon_sleep);
+ bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
+
+ write_behind = bitmap->mddev->bitmap_info.max_write_behind;
+ if (write_behind > COUNTER_MAX) {
+ /* FIXME: A guess */
+ printk(KERN_INFO "Guessing at good write_behind default\n");
+ 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);
+
+ /* Force full recovery? */
+ 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)
{
@@ -542,6 +626,8 @@ static int bitmap_read_sb(struct bitmap
unsigned long long events;
int err = -EINVAL;
+ printk("READING OLD BITMAP\n");
+
/* page 0 is the superblock, read it... */
if (bitmap->file) {
loff_t isize = i_size_read(bitmap->file->f_mapping->host);
@@ -1687,9 +1773,20 @@ 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 the bitmap is internal and persistent and the chunksize
+ * is already set, then we know we are being called through
+ * device-mapper and that this is the first time the array
+ * is being activated. We must create a new on-disk bitmap
+ * instance.
+ */
+ if (!bitmap->file && bitmap->mddev->persistent &&
+ mddev->bitmap_info.chunksize)
+ 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)