aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-06-26 03:27:56 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:39 -0400
commit07d84d109d8beedd68df9da2e4e9f25c8217e7fb (patch)
tree09b4749cb2ff1759c076c362891a28ceda2b8520 /drivers/md
parent3285edf152cefff482f95ceb90b1bd46ac169df1 (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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c25
-rw-r--r--drivers/md/raid1.c6
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)
1105static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) 1107static 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 */