[PATCH] md: Fix issues with referencing rdev in md/raid1

We need to be careful when referencing mirrors[i].rdev. It can disappear
under us at various times.

So:
fix a couple of problem places.
comment a couple of non-problem places
move an 'atomic_add' which deferences rdev down a little
way to some where where it is sure to not be NULL.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by NeilBrown and committed by Linus Torvalds ddac7c7e df9ecaba

+35 -22
+35 -22
drivers/md/raid1.c
··· 930 930 931 931 seq_printf(seq, " [%d/%d] [", conf->raid_disks, 932 932 conf->working_disks); 933 - for (i = 0; i < conf->raid_disks; i++) 933 + rcu_read_lock(); 934 + for (i = 0; i < conf->raid_disks; i++) { 935 + mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); 934 936 seq_printf(seq, "%s", 935 - conf->mirrors[i].rdev && 936 - test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_"); 937 + rdev && test_bit(In_sync, &rdev->flags) ? "U" : "_"); 938 + } 939 + rcu_read_unlock(); 937 940 seq_printf(seq, "]"); 938 941 } 939 942 ··· 978 975 static void print_conf(conf_t *conf) 979 976 { 980 977 int i; 981 - mirror_info_t *tmp; 982 978 983 979 printk("RAID1 conf printout:\n"); 984 980 if (!conf) { ··· 987 985 printk(" --- wd:%d rd:%d\n", conf->working_disks, 988 986 conf->raid_disks); 989 987 988 + rcu_read_lock(); 990 989 for (i = 0; i < conf->raid_disks; i++) { 991 990 char b[BDEVNAME_SIZE]; 992 - tmp = conf->mirrors + i; 993 - if (tmp->rdev) 991 + mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); 992 + if (rdev) 994 993 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 995 - i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags), 996 - bdevname(tmp->rdev->bdev,b)); 994 + i, !test_bit(In_sync, &rdev->flags), 995 + !test_bit(Faulty, &rdev->flags), 996 + bdevname(rdev->bdev,b)); 997 997 } 998 + rcu_read_unlock(); 998 999 } 999 1000 1000 1001 static void close_sync(conf_t *conf) ··· 1013 1008 { 1014 1009 int i; 1015 1010 conf_t *conf = mddev->private; 1016 - mirror_info_t *tmp; 1017 1011 1018 1012 /* 1019 1013 * Find all failed disks within the RAID1 configuration 1020 - * and mark them readable 1014 + * and mark them readable. 1015 + * Called under mddev lock, so rcu protection not needed. 1021 1016 */ 1022 1017 for (i = 0; i < conf->raid_disks; i++) { 1023 - tmp = conf->mirrors + i; 1024 - if (tmp->rdev 1025 - && !test_bit(Faulty, &tmp->rdev->flags) 1026 - && !test_bit(In_sync, &tmp->rdev->flags)) { 1018 + mdk_rdev_t *rdev = conf->mirrors[i].rdev; 1019 + if (rdev 1020 + && !test_bit(Faulty, &rdev->flags) 1021 + && !test_bit(In_sync, &rdev->flags)) { 1027 1022 conf->working_disks++; 1028 1023 mddev->degraded--; 1029 - set_bit(In_sync, &tmp->rdev->flags); 1024 + set_bit(In_sync, &rdev->flags); 1030 1025 } 1031 1026 } 1032 1027 ··· 1242 1237 /* ouch - failed to read all of that. 1243 1238 * Try some synchronous reads of other devices to get 1244 1239 * good data, much like with normal read errors. Only 1245 - * read into the pages we already have so they we don't 1240 + * read into the pages we already have so we don't 1246 1241 * need to re-issue the read request. 1247 1242 * We don't need to freeze the array, because being in an 1248 1243 * active sync request, there is no normal IO, and ··· 1262 1257 s = PAGE_SIZE >> 9; 1263 1258 do { 1264 1259 if (r1_bio->bios[d]->bi_end_io == end_sync_read) { 1260 + /* No rcu protection needed here devices 1261 + * can only be removed when no resync is 1262 + * active, and resync is currently active 1263 + */ 1265 1264 rdev = conf->mirrors[d].rdev; 1266 1265 if (sync_page_io(rdev->bdev, 1267 1266 sect + rdev->data_offset, ··· 1472 1463 s = PAGE_SIZE >> 9; 1473 1464 1474 1465 do { 1466 + /* Note: no rcu protection needed here 1467 + * as this is synchronous in the raid1d thread 1468 + * which is the thread that might remove 1469 + * a device. If raid1d ever becomes multi-threaded.... 1470 + */ 1475 1471 rdev = conf->mirrors[d].rdev; 1476 1472 if (rdev && 1477 1473 test_bit(In_sync, &rdev->flags) && ··· 1500 1486 d = conf->raid_disks; 1501 1487 d--; 1502 1488 rdev = conf->mirrors[d].rdev; 1503 - atomic_add(s, &rdev->corrected_errors); 1504 1489 if (rdev && 1505 1490 test_bit(In_sync, &rdev->flags)) { 1506 1491 if (sync_page_io(rdev->bdev, ··· 1522 1509 s<<9, conf->tmppage, READ) == 0) 1523 1510 /* Well, this device is dead */ 1524 1511 md_error(mddev, rdev); 1525 - else 1512 + else { 1513 + atomic_add(s, &rdev->corrected_errors); 1526 1514 printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n", 1527 1515 mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b)); 1516 + } 1528 1517 } 1529 1518 } 1530 1519 } else { ··· 1802 1787 for (i=0; i<conf->raid_disks; i++) { 1803 1788 bio = r1_bio->bios[i]; 1804 1789 if (bio->bi_end_io == end_sync_read) { 1805 - md_sync_acct(conf->mirrors[i].rdev->bdev, nr_sectors); 1790 + md_sync_acct(bio->bi_bdev, nr_sectors); 1806 1791 generic_make_request(bio); 1807 1792 } 1808 1793 } 1809 1794 } else { 1810 1795 atomic_set(&r1_bio->remaining, 1); 1811 1796 bio = r1_bio->bios[r1_bio->read_disk]; 1812 - md_sync_acct(conf->mirrors[r1_bio->read_disk].rdev->bdev, 1813 - nr_sectors); 1797 + md_sync_acct(bio->bi_bdev, nr_sectors); 1814 1798 generic_make_request(bio); 1815 1799 1816 1800 } 1817 - 1818 1801 return nr_sectors; 1819 1802 } 1820 1803