aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c115
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid10.c3
-rw-r--r--drivers/md/raid5.c1
-rw-r--r--include/linux/raid/md_k.h6
-rw-r--r--include/linux/raid/md_p.h5
6 files changed, 109 insertions, 24 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 71d46eb2c4..a296edd7e1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1175,7 +1175,11 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
1175 set_bit(Faulty, &rdev->flags); 1175 set_bit(Faulty, &rdev->flags);
1176 break; 1176 break;
1177 default: 1177 default:
1178 set_bit(In_sync, &rdev->flags); 1178 if ((le32_to_cpu(sb->feature_map) &
1179 MD_FEATURE_RECOVERY_OFFSET))
1180 rdev->recovery_offset = le64_to_cpu(sb->recovery_offset);
1181 else
1182 set_bit(In_sync, &rdev->flags);
1179 rdev->raid_disk = role; 1183 rdev->raid_disk = role;
1180 break; 1184 break;
1181 } 1185 }
@@ -1199,6 +1203,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1199 1203
1200 sb->feature_map = 0; 1204 sb->feature_map = 0;
1201 sb->pad0 = 0; 1205 sb->pad0 = 0;
1206 sb->recovery_offset = cpu_to_le64(0);
1202 memset(sb->pad1, 0, sizeof(sb->pad1)); 1207 memset(sb->pad1, 0, sizeof(sb->pad1));
1203 memset(sb->pad2, 0, sizeof(sb->pad2)); 1208 memset(sb->pad2, 0, sizeof(sb->pad2));
1204 memset(sb->pad3, 0, sizeof(sb->pad3)); 1209 memset(sb->pad3, 0, sizeof(sb->pad3));
@@ -1219,6 +1224,14 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1219 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); 1224 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
1220 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); 1225 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
1221 } 1226 }
1227
1228 if (rdev->raid_disk >= 0 &&
1229 !test_bit(In_sync, &rdev->flags) &&
1230 rdev->recovery_offset > 0) {
1231 sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
1232 sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
1233 }
1234
1222 if (mddev->reshape_position != MaxSector) { 1235 if (mddev->reshape_position != MaxSector) {
1223 sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE); 1236 sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE);
1224 sb->reshape_position = cpu_to_le64(mddev->reshape_position); 1237 sb->reshape_position = cpu_to_le64(mddev->reshape_position);
@@ -1243,11 +1256,12 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1243 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1256 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1244 else if (test_bit(In_sync, &rdev2->flags)) 1257 else if (test_bit(In_sync, &rdev2->flags))
1245 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); 1258 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1259 else if (rdev2->raid_disk >= 0 && rdev2->recovery_offset > 0)
1260 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1246 else 1261 else
1247 sb->dev_roles[i] = cpu_to_le16(0xffff); 1262 sb->dev_roles[i] = cpu_to_le16(0xffff);
1248 } 1263 }
1249 1264
1250 sb->recovery_offset = cpu_to_le64(0); /* not supported yet */
1251 sb->sb_csum = calc_sb_1_csum(sb); 1265 sb->sb_csum = calc_sb_1_csum(sb);
1252} 1266}
1253 1267
@@ -2603,8 +2617,6 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
2603 return NULL; 2617 return NULL;
2604} 2618}
2605 2619
2606void md_wakeup_thread(mdk_thread_t *thread);
2607
2608static void md_safemode_timeout(unsigned long data) 2620static void md_safemode_timeout(unsigned long data)
2609{ 2621{
2610 mddev_t *mddev = (mddev_t *) data; 2622 mddev_t *mddev = (mddev_t *) data;
@@ -2786,6 +2798,36 @@ static int do_md_run(mddev_t * mddev)
2786 mddev->queue->queuedata = mddev; 2798 mddev->queue->queuedata = mddev;
2787 mddev->queue->make_request_fn = mddev->pers->make_request; 2799 mddev->queue->make_request_fn = mddev->pers->make_request;
2788 2800
2801 /* If there is a partially-recovered drive we need to
2802 * start recovery here. If we leave it to md_check_recovery,
2803 * it will remove the drives and not do the right thing
2804 */
2805 if (mddev->degraded) {
2806 struct list_head *rtmp;
2807 int spares = 0;
2808 ITERATE_RDEV(mddev,rdev,rtmp)
2809 if (rdev->raid_disk >= 0 &&
2810 !test_bit(In_sync, &rdev->flags) &&
2811 !test_bit(Faulty, &rdev->flags))
2812 /* complete an interrupted recovery */
2813 spares++;
2814 if (spares && mddev->pers->sync_request) {
2815 mddev->recovery = 0;
2816 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
2817 mddev->sync_thread = md_register_thread(md_do_sync,
2818 mddev,
2819 "%s_resync");
2820 if (!mddev->sync_thread) {
2821 printk(KERN_ERR "%s: could not start resync"
2822 " thread...\n",
2823 mdname(mddev));
2824 /* leave the spares where they are, it shouldn't hurt */
2825 mddev->recovery = 0;
2826 } else
2827 md_wakeup_thread(mddev->sync_thread);
2828 }
2829 }
2830
2789 mddev->changed = 1; 2831 mddev->changed = 1;
2790 md_new_event(mddev); 2832 md_new_event(mddev);
2791 return 0; 2833 return 0;
@@ -2819,6 +2861,7 @@ static int restart_array(mddev_t *mddev)
2819 */ 2861 */
2820 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2862 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2821 md_wakeup_thread(mddev->thread); 2863 md_wakeup_thread(mddev->thread);
2864 md_wakeup_thread(mddev->sync_thread);
2822 err = 0; 2865 err = 0;
2823 } else { 2866 } else {
2824 printk(KERN_ERR "md: %s has no personality assigned.\n", 2867 printk(KERN_ERR "md: %s has no personality assigned.\n",
@@ -2842,6 +2885,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
2842 } 2885 }
2843 2886
2844 if (mddev->sync_thread) { 2887 if (mddev->sync_thread) {
2888 set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
2845 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 2889 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
2846 md_unregister_thread(mddev->sync_thread); 2890 md_unregister_thread(mddev->sync_thread);
2847 mddev->sync_thread = NULL; 2891 mddev->sync_thread = NULL;
@@ -2871,13 +2915,14 @@ static int do_md_stop(mddev_t * mddev, int ro)
2871 if (mddev->ro) 2915 if (mddev->ro)
2872 mddev->ro = 0; 2916 mddev->ro = 0;
2873 } 2917 }
2874 if (!mddev->in_sync) { 2918 if (!mddev->in_sync || mddev->sb_dirty) {
2875 /* mark array as shutdown cleanly */ 2919 /* mark array as shutdown cleanly */
2876 mddev->in_sync = 1; 2920 mddev->in_sync = 1;
2877 md_update_sb(mddev); 2921 md_update_sb(mddev);
2878 } 2922 }
2879 if (ro) 2923 if (ro)
2880 set_disk_ro(disk, 1); 2924 set_disk_ro(disk, 1);
2925 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
2881 } 2926 }
2882 2927
2883 /* 2928 /*
@@ -4665,10 +4710,14 @@ void md_do_sync(mddev_t *mddev)
4665 struct list_head *tmp; 4710 struct list_head *tmp;
4666 sector_t last_check; 4711 sector_t last_check;
4667 int skipped = 0; 4712 int skipped = 0;
4713 struct list_head *rtmp;
4714 mdk_rdev_t *rdev;
4668 4715
4669 /* just incase thread restarts... */ 4716 /* just incase thread restarts... */
4670 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) 4717 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
4671 return; 4718 return;
4719 if (mddev->ro) /* never try to sync a read-only array */
4720 return;
4672 4721
4673 /* we overload curr_resync somewhat here. 4722 /* we overload curr_resync somewhat here.
4674 * 0 == not engaged in resync at all 4723 * 0 == not engaged in resync at all
@@ -4727,17 +4776,30 @@ void md_do_sync(mddev_t *mddev)
4727 } 4776 }
4728 } while (mddev->curr_resync < 2); 4777 } while (mddev->curr_resync < 2);
4729 4778
4779 j = 0;
4730 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { 4780 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
4731 /* resync follows the size requested by the personality, 4781 /* resync follows the size requested by the personality,
4732 * which defaults to physical size, but can be virtual size 4782 * which defaults to physical size, but can be virtual size
4733 */ 4783 */
4734 max_sectors = mddev->resync_max_sectors; 4784 max_sectors = mddev->resync_max_sectors;
4735 mddev->resync_mismatches = 0; 4785 mddev->resync_mismatches = 0;
4786 /* we don't use the checkpoint if there's a bitmap */
4787 if (!mddev->bitmap &&
4788 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
4789 j = mddev->recovery_cp;
4736 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) 4790 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
4737 max_sectors = mddev->size << 1; 4791 max_sectors = mddev->size << 1;
4738 else 4792 else {
4739 /* recovery follows the physical size of devices */ 4793 /* recovery follows the physical size of devices */
4740 max_sectors = mddev->size << 1; 4794 max_sectors = mddev->size << 1;
4795 j = MaxSector;
4796 ITERATE_RDEV(mddev,rdev,rtmp)
4797 if (rdev->raid_disk >= 0 &&
4798 !test_bit(Faulty, &rdev->flags) &&
4799 !test_bit(In_sync, &rdev->flags) &&
4800 rdev->recovery_offset < j)
4801 j = rdev->recovery_offset;
4802 }
4741 4803<