aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-06-21 20:17:27 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 22:07:47 -0400
commita654b9d8f851f4ca02649d5825cbe6c608adb10c (patch)
tree747301647f619a9f1dd48f4d6be96b5e35d2484c /drivers/md/md.c
parent3d310eb7b3df1252e8595d059d982b0a9825a137 (diff)
[PATCH] md: allow md intent bitmap to be stored near the superblock.
This provides an alternate to storing the bitmap in a separate file. The bitmap can be stored at a given offset from the superblock. Obviously the creator of the array must make sure this doesn't intersect with data.... After is good for version-0.90 superblocks. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7075bebb7f37..fde8acfac320 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -337,7 +337,7 @@ static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
337 return 0; 337 return 0;
338} 338}
339 339
340static int sync_page_io(struct block_device *bdev, sector_t sector, int size, 340int sync_page_io(struct block_device *bdev, sector_t sector, int size,
341 struct page *page, int rw) 341 struct page *page, int rw)
342{ 342{
343 struct bio *bio = bio_alloc(GFP_NOIO, 1); 343 struct bio *bio = bio_alloc(GFP_NOIO, 1);
@@ -609,6 +609,17 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
609 memcpy(mddev->uuid+12,&sb->set_uuid3, 4); 609 memcpy(mddev->uuid+12,&sb->set_uuid3, 4);
610 610
611 mddev->max_disks = MD_SB_DISKS; 611 mddev->max_disks = MD_SB_DISKS;
612
613 if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
614 mddev->bitmap_file == NULL) {
615 if (mddev->level != 1) {
616 /* FIXME use a better test */
617 printk(KERN_WARNING "md: bitmaps only support for raid1\n");
618 return -EINVAL;
619 }
620 mddev->bitmap_offset = (MD_SB_BYTES >> 9);
621 }
622
612 } else if (mddev->pers == NULL) { 623 } else if (mddev->pers == NULL) {
613 /* Insist on good event counter while assembling */ 624 /* Insist on good event counter while assembling */
614 __u64 ev1 = md_event(sb); 625 __u64 ev1 = md_event(sb);
@@ -702,6 +713,9 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
702 sb->layout = mddev->layout; 713 sb->layout = mddev->layout;
703 sb->chunk_size = mddev->chunk_size; 714 sb->chunk_size = mddev->chunk_size;
704 715
716 if (mddev->bitmap && mddev->bitmap_file == NULL)
717 sb->state |= (1<<MD_SB_BITMAP_PRESENT);
718
705 sb->disks[0].state = (1<<MD_DISK_REMOVED); 719 sb->disks[0].state = (1<<MD_DISK_REMOVED);
706 ITERATE_RDEV(mddev,rdev2,tmp) { 720 ITERATE_RDEV(mddev,rdev2,tmp) {
707 mdp_disk_t *d; 721 mdp_disk_t *d;
@@ -898,6 +912,15 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
898 memcpy(mddev->uuid, sb->set_uuid, 16); 912 memcpy(mddev->uuid, sb->set_uuid, 16);
899 913
900 mddev->max_disks = (4096-256)/2; 914 mddev->max_disks = (4096-256)/2;
915
916 if ((le32_to_cpu(sb->feature_map) & 1) &&
917 mddev->bitmap_file == NULL ) {
918 if (mddev->level != 1) {
919 printk(KERN_WARNING "md: bitmaps only supported for raid1\n");
920 return -EINVAL;
921 }
922 mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset);
923 }
901 } else if (mddev->pers == NULL) { 924 } else if (mddev->pers == NULL) {
902 /* Insist of good event counter while assembling */ 925 /* Insist of good event counter while assembling */
903 __u64 ev1 = le64_to_cpu(sb->events); 926 __u64 ev1 = le64_to_cpu(sb->events);
@@ -960,6 +983,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
960 else 983 else
961 sb->resync_offset = cpu_to_le64(0); 984 sb->resync_offset = cpu_to_le64(0);
962 985
986 if (mddev->bitmap && mddev->bitmap_file == NULL) {
987 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
988 sb->feature_map = cpu_to_le32(1);
989 }
990
963 max_dev = 0; 991 max_dev = 0;
964 ITERATE_RDEV(mddev,rdev2,tmp) 992 ITERATE_RDEV(mddev,rdev2,tmp)
965 if (rdev2->desc_nr+1 > max_dev) 993 if (rdev2->desc_nr+1 > max_dev)
@@ -2406,7 +2434,8 @@ static int set_bitmap_file(mddev_t *mddev, int fd)
2406 mdname(mddev)); 2434 mdname(mddev));
2407 fput(mddev->bitmap_file); 2435 fput(mddev->bitmap_file);
2408 mddev->bitmap_file = NULL; 2436 mddev->bitmap_file = NULL;
2409 } 2437 } else
2438 mddev->bitmap_offset = 0; /* file overrides offset */
2410 return err; 2439 return err;
2411} 2440}
2412 2441
@@ -3774,6 +3803,13 @@ void md_check_recovery(mddev_t *mddev)
3774 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 3803 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3775 if (!spares) 3804 if (!spares)
3776 set_bit(MD_RECOVERY_SYNC, &mddev->recovery); 3805 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3806 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
3807 /* We are adding a device or devices to an array
3808 * which has the bitmap stored on all devices.
3809 * So make sure all bitmap pages get written
3810 */
3811 bitmap_write_all(mddev->bitmap);
3812 }
3777 mddev->sync_thread = md_register_thread(md_do_sync, 3813 mddev->sync_thread = md_register_thread(md_do_sync,
3778 mddev, 3814 mddev,
3779 "%s_resync"); 3815 "%s_resync");