diff options
author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-06-21 20:17:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 22:07:47 -0400 |
commit | a654b9d8f851f4ca02649d5825cbe6c608adb10c (patch) | |
tree | 747301647f619a9f1dd48f4d6be96b5e35d2484c /drivers/md/md.c | |
parent | 3d310eb7b3df1252e8595d059d982b0a9825a137 (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.c | 40 |
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 | ||
340 | static int sync_page_io(struct block_device *bdev, sector_t sector, int size, | 340 | int 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"); |