diff options
author | NeilBrown <neilb@suse.de> | 2006-06-26 03:27:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:39 -0400 |
commit | 07d84d109d8beedd68df9da2e4e9f25c8217e7fb (patch) | |
tree | 09b4749cb2ff1759c076c362891a28ceda2b8520 | |
parent | 3285edf152cefff482f95ceb90b1bd46ac169df1 (diff) |
[PATCH] md: Allow re-add to work on array without bitmaps
When an array has a bitmap, a device can be removed and re-added and only
blocks changes since the removal (as recorded in the bitmap) will be resynced.
It should be possible to do a similar thing to arrays without bitmaps. i.e.
if a device is removed and re-added and *no* changes have been made in the
interim, then the add should not require a resync.
This patch allows that option. This means that when assembling an array one
device at a time (e.g. during device discovery) the array can be enabled
read-only as soon as enough devices are available, but extra devices can still
be added without causing a resync.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/md/md.c | 25 | ||||
-rw-r--r-- | drivers/md/raid1.c | 6 |
2 files changed, 20 insertions, 11 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7da9e2d023bb..6f97817d28b9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -737,6 +737,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
737 | { | 737 | { |
738 | mdp_disk_t *desc; | 738 | mdp_disk_t *desc; |
739 | mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); | 739 | mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); |
740 | __u64 ev1 = md_event(sb); | ||
740 | 741 | ||
741 | rdev->raid_disk = -1; | 742 | rdev->raid_disk = -1; |
742 | rdev->flags = 0; | 743 | rdev->flags = 0; |
@@ -753,7 +754,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
753 | mddev->layout = sb->layout; | 754 | mddev->layout = sb->layout; |
754 | mddev->raid_disks = sb->raid_disks; | 755 | mddev->raid_disks = sb->raid_disks; |
755 | mddev->size = sb->size; | 756 | mddev->size = sb->size; |
756 | mddev->events = md_event(sb); | 757 | mddev->events = ev1; |
757 | mddev->bitmap_offset = 0; | 758 | mddev->bitmap_offset = 0; |
758 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; | 759 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; |
759 | 760 | ||
@@ -802,7 +803,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
802 | 803 | ||
803 | } else if (mddev->pers == NULL) { | 804 | } else if (mddev->pers == NULL) { |
804 | /* Insist on good event counter while assembling */ | 805 | /* Insist on good event counter while assembling */ |
805 | __u64 ev1 = md_event(sb); | ||
806 | ++ev1; | 806 | ++ev1; |
807 | if (ev1 < mddev->events) | 807 | if (ev1 < mddev->events) |
808 | return -EINVAL; | 808 | return -EINVAL; |
@@ -810,11 +810,13 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
810 | /* if adding to array with a bitmap, then we can accept an | 810 | /* if adding to array with a bitmap, then we can accept an |
811 | * older device ... but not too old. | 811 | * older device ... but not too old. |
812 | */ | 812 | */ |
813 | __u64 ev1 = md_event(sb); | ||
814 | if (ev1 < mddev->bitmap->events_cleared) | 813 | if (ev1 < mddev->bitmap->events_cleared) |
815 | return 0; | 814 | return 0; |
816 | } else /* just a hot-add of a new device, leave raid_disk at -1 */ | 815 | } else { |
817 | return 0; | 816 | if (ev1 < mddev->events) |
817 | /* just a hot-add of a new device, leave raid_disk at -1 */ | ||
818 | return 0; | ||
819 | } | ||
818 | 820 | ||
819 | if (mddev->level != LEVEL_MULTIPATH) { | 821 | if (mddev->level != LEVEL_MULTIPATH) { |
820 | desc = sb->disks + rdev->desc_nr; | 822 | desc = sb->disks + rdev->desc_nr; |
@@ -1105,6 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1105 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | 1107 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) |
1106 | { | 1108 | { |
1107 | struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); | 1109 | struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); |
1110 | __u64 ev1 = le64_to_cpu(sb->events); | ||
1108 | 1111 | ||
1109 | rdev->raid_disk = -1; | 1112 | rdev->raid_disk = -1; |
1110 | rdev->flags = 0; | 1113 | rdev->flags = 0; |
@@ -1120,7 +1123,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1120 | mddev->layout = le32_to_cpu(sb->layout); | 1123 | mddev->layout = le32_to_cpu(sb->layout); |
1121 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); | 1124 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); |
1122 | mddev->size = le64_to_cpu(sb->size)/2; | 1125 | mddev->size = le64_to_cpu(sb->size)/2; |
1123 | mddev->events = le64_to_cpu(sb->events); | 1126 | mddev->events = ev1; |
1124 | mddev->bitmap_offset = 0; | 1127 | mddev->bitmap_offset = 0; |
1125 | mddev->default_bitmap_offset = 1024 >> 9; | 1128 | mddev->default_bitmap_offset = 1024 >> 9; |
1126 | 1129 | ||
@@ -1154,7 +1157,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1154 | 1157 | ||
1155 | } else if (mddev->pers == NULL) { | 1158 | } else if (mddev->pers == NULL) { |
1156 | /* Insist of good event counter while assembling */ | 1159 | /* Insist of good event counter while assembling */ |
1157 | __u64 ev1 = le64_to_cpu(sb->events); | ||
1158 | ++ev1; | 1160 | ++ev1; |
1159 | if (ev1 < mddev->events) | 1161 | if (ev1 < mddev->events) |
1160 | return -EINVAL; | 1162 | return -EINVAL; |
@@ -1162,12 +1164,13 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1162 | /* If adding to array with a bitmap, then we can accept an | 1164 | /* If adding to array with a bitmap, then we can accept an |
1163 | * older device, but not too old. | 1165 | * older device, but not too old. |
1164 | */ | 1166 | */ |
1165 | __u64 ev1 = le64_to_cpu(sb->events); | ||
1166 | if (ev1 < mddev->bitmap->events_cleared) | 1167 | if (ev1 < mddev->bitmap->events_cleared) |
1167 | return 0; | 1168 | return 0; |
1168 | } else /* just a hot-add of a new device, leave raid_disk at -1 */ | 1169 | } else { |
1169 | return 0; | 1170 | if (ev1 < mddev->events) |
1170 | 1171 | /* just a hot-add of a new device, leave raid_disk at -1 */ | |
1172 | return 0; | ||
1173 | } | ||
1171 | if (mddev->level != LEVEL_MULTIPATH) { | 1174 | if (mddev->level != LEVEL_MULTIPATH) { |
1172 | int role; | 1175 | int role; |
1173 | rdev->desc_nr = le32_to_cpu(sb->dev_number); | 1176 | rdev->desc_nr = le32_to_cpu(sb->dev_number); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b3cfae41f769..cead918578a7 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1625,6 +1625,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1625 | /* before building a request, check if we can skip these blocks.. | 1625 | /* before building a request, check if we can skip these blocks.. |
1626 | * This call the bitmap_start_sync doesn't actually record anything | 1626 | * This call the bitmap_start_sync doesn't actually record anything |
1627 | */ | 1627 | */ |
1628 | if (mddev->bitmap == NULL && | ||
1629 | mddev->recovery_cp == MaxSector && | ||
1630 | conf->fullsync == 0) { | ||
1631 | *skipped = 1; | ||
1632 | return max_sector - sector_nr; | ||
1633 | } | ||
1628 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | 1634 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && |
1629 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 1635 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
1630 | /* We can skip this block, and probably several more */ | 1636 | /* We can skip this block, and probably several more */ |