diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 261 |
1 files changed, 205 insertions, 56 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1223e98ecd70..e2a40283e323 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector | |||
293 | return sh; | 293 | return sh; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int grow_stripes(raid5_conf_t *conf, int num) | 296 | static int grow_one_stripe(raid5_conf_t *conf) |
297 | { | 297 | { |
298 | struct stripe_head *sh; | 298 | struct stripe_head *sh; |
299 | sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); | ||
300 | if (!sh) | ||
301 | return 0; | ||
302 | memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev)); | ||
303 | sh->raid_conf = conf; | ||
304 | spin_lock_init(&sh->lock); | ||
305 | |||
306 | if (grow_buffers(sh, conf->raid_disks)) { | ||
307 | shrink_buffers(sh, conf->raid_disks); | ||
308 | kmem_cache_free(conf->slab_cache, sh); | ||
309 | return 0; | ||
310 | } | ||
311 | /* we just created an active stripe so... */ | ||
312 | atomic_set(&sh->count, 1); | ||
313 | atomic_inc(&conf->active_stripes); | ||
314 | INIT_LIST_HEAD(&sh->lru); | ||
315 | release_stripe(sh); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | static int grow_stripes(raid5_conf_t *conf, int num) | ||
320 | { | ||
299 | kmem_cache_t *sc; | 321 | kmem_cache_t *sc; |
300 | int devs = conf->raid_disks; | 322 | int devs = conf->raid_disks; |
301 | 323 | ||
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num) | |||
308 | return 1; | 330 | return 1; |
309 | conf->slab_cache = sc; | 331 | conf->slab_cache = sc; |
310 | while (num--) { | 332 | while (num--) { |
311 | sh = kmem_cache_alloc(sc, GFP_KERNEL); | 333 | if (!grow_one_stripe(conf)) |
312 | if (!sh) | ||
313 | return 1; | ||
314 | memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev)); | ||
315 | sh->raid_conf = conf; | ||
316 | spin_lock_init(&sh->lock); | ||
317 | |||
318 | if (grow_buffers(sh, conf->raid_disks)) { | ||
319 | shrink_buffers(sh, conf->raid_disks); | ||
320 | kmem_cache_free(sc, sh); | ||
321 | return 1; | 334 | return 1; |
322 | } | ||
323 | /* we just created an active stripe so... */ | ||
324 | atomic_set(&sh->count, 1); | ||
325 | atomic_inc(&conf->active_stripes); | ||
326 | INIT_LIST_HEAD(&sh->lru); | ||
327 | release_stripe(sh); | ||
328 | } | 335 | } |
329 | return 0; | 336 | return 0; |
330 | } | 337 | } |
331 | 338 | ||
332 | static void shrink_stripes(raid5_conf_t *conf) | 339 | static int drop_one_stripe(raid5_conf_t *conf) |
333 | { | 340 | { |
334 | struct stripe_head *sh; | 341 | struct stripe_head *sh; |
335 | 342 | ||
336 | while (1) { | 343 | spin_lock_irq(&conf->device_lock); |
337 | spin_lock_irq(&conf->device_lock); | 344 | sh = get_free_stripe(conf); |
338 | sh = get_free_stripe(conf); | 345 | spin_unlock_irq(&conf->device_lock); |
339 | spin_unlock_irq(&conf->device_lock); | 346 | if (!sh) |
340 | if (!sh) | 347 | return 0; |
341 | break; | 348 | if (atomic_read(&sh->count)) |
342 | if (atomic_read(&sh->count)) | 349 | BUG(); |
343 | BUG(); | 350 | shrink_buffers(sh, conf->raid_disks); |
344 | shrink_buffers(sh, conf->raid_disks); | 351 | kmem_cache_free(conf->slab_cache, sh); |
345 | kmem_cache_free(conf->slab_cache, sh); | 352 | atomic_dec(&conf->active_stripes); |
346 | atomic_dec(&conf->active_stripes); | 353 | return 1; |
347 | } | 354 | } |
355 | |||
356 | static void shrink_stripes(raid5_conf_t *conf) | ||
357 | { | ||
358 | while (drop_one_stripe(conf)) | ||
359 | ; | ||
360 | |||
348 | kmem_cache_destroy(conf->slab_cache); | 361 | kmem_cache_destroy(conf->slab_cache); |
349 | conf->slab_cache = NULL; | 362 | conf->slab_cache = NULL; |
350 | } | 363 | } |
351 | 364 | ||
352 | static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, | 365 | static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done, |
353 | int error) | 366 | int error) |
354 | { | 367 | { |
355 | struct stripe_head *sh = bi->bi_private; | 368 | struct stripe_head *sh = bi->bi_private; |
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, | |||
401 | } | 414 | } |
402 | #else | 415 | #else |
403 | set_bit(R5_UPTODATE, &sh->dev[i].flags); | 416 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
404 | #endif | 417 | #endif |
418 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | ||
419 | printk("R5: read error corrected!!\n"); | ||
420 | clear_bit(R5_ReadError, &sh->dev[i].flags); | ||
421 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | ||
422 | } | ||
423 | if (atomic_read(&conf->disks[i].rdev->read_errors)) | ||
424 | atomic_set(&conf->disks[i].rdev->read_errors, 0); | ||
405 | } else { | 425 | } else { |
406 | md_error(conf->mddev, conf->disks[i].rdev); | 426 | int retry = 0; |
407 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); | 427 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); |
428 | atomic_inc(&conf->disks[i].rdev->read_errors); | ||
429 | if (conf->mddev->degraded) | ||
430 | printk("R5: read error not correctable.\n"); | ||
431 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | ||
432 | /* Oh, no!!! */ | ||
433 | printk("R5: read error NOT corrected!!\n"); | ||
434 | else if (atomic_read(&conf->disks[i].rdev->read_errors) | ||
435 | > conf->max_nr_stripes) | ||
436 | printk("raid5: Too many read errors, failing device.\n"); | ||
437 | else | ||
438 | retry = 1; | ||
439 | if (retry) | ||
440 | set_bit(R5_ReadError, &sh->dev[i].flags); | ||
441 | else { | ||
442 | clear_bit(R5_ReadError, &sh->dev[i].flags); | ||
443 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | ||
444 | md_error(conf->mddev, conf->disks[i].rdev); | ||
445 | } | ||
408 | } | 446 | } |
409 | rdev_dec_pending(conf->disks[i].rdev, conf->mddev); | 447 | rdev_dec_pending(conf->disks[i].rdev, conf->mddev); |
410 | #if 0 | 448 | #if 0 |
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
487 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; | 525 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; |
488 | PRINTK("raid5: error called\n"); | 526 | PRINTK("raid5: error called\n"); |
489 | 527 | ||
490 | if (!rdev->faulty) { | 528 | if (!test_bit(Faulty, &rdev->flags)) { |
491 | mddev->sb_dirty = 1; | 529 | mddev->sb_dirty = 1; |
492 | if (rdev->in_sync) { | 530 | if (test_bit(In_sync, &rdev->flags)) { |
493 | conf->working_disks--; | 531 | conf->working_disks--; |
494 | mddev->degraded++; | 532 | mddev->degraded++; |
495 | conf->failed_disks++; | 533 | conf->failed_disks++; |
496 | rdev->in_sync = 0; | 534 | clear_bit(In_sync, &rdev->flags); |
497 | /* | 535 | /* |
498 | * if recovery was running, make sure it aborts. | 536 | * if recovery was running, make sure it aborts. |
499 | */ | 537 | */ |
500 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 538 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); |
501 | } | 539 | } |
502 | rdev->faulty = 1; | 540 | set_bit(Faulty, &rdev->flags); |
503 | printk (KERN_ALERT | 541 | printk (KERN_ALERT |
504 | "raid5: Disk failure on %s, disabling device." | 542 | "raid5: Disk failure on %s, disabling device." |
505 | " Operation continuing on %d devices\n", | 543 | " Operation continuing on %d devices\n", |
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh) | |||
965 | } | 1003 | } |
966 | if (dev->written) written++; | 1004 | if (dev->written) written++; |
967 | rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ | 1005 | rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ |
968 | if (!rdev || !rdev->in_sync) { | 1006 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
1007 | /* The ReadError flag wil just be confusing now */ | ||
1008 | clear_bit(R5_ReadError, &dev->flags); | ||
1009 | clear_bit(R5_ReWrite, &dev->flags); | ||
1010 | } | ||
1011 | if (!rdev || !test_bit(In_sync, &rdev->flags) | ||
1012 | || test_bit(R5_ReadError, &dev->flags)) { | ||
969 | failed++; | 1013 | failed++; |
970 | failed_num = i; | 1014 | failed_num = i; |
971 | } else | 1015 | } else |
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh) | |||
980 | if (failed > 1 && to_read+to_write+written) { | 1024 | if (failed > 1 && to_read+to_write+written) { |
981 | for (i=disks; i--; ) { | 1025 | for (i=disks; i--; ) { |
982 | int bitmap_end = 0; | 1026 | int bitmap_end = 0; |
1027 | |||
1028 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | ||
1029 | mdk_rdev_t *rdev = conf->disks[i].rdev; | ||
1030 | if (rdev && test_bit(In_sync, &rdev->flags)) | ||
1031 | /* multiple read failures in one stripe */ | ||
1032 | md_error(conf->mddev, rdev); | ||
1033 | } | ||
1034 | |||
983 | spin_lock_irq(&conf->device_lock); | 1035 | spin_lock_irq(&conf->device_lock); |
984 | /* fail all writes first */ | 1036 | /* fail all writes first */ |
985 | bi = sh->dev[i].towrite; | 1037 | bi = sh->dev[i].towrite; |
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh) | |||
1015 | } | 1067 | } |
1016 | 1068 | ||
1017 | /* fail any reads if this device is non-operational */ | 1069 | /* fail any reads if this device is non-operational */ |
1018 | if (!test_bit(R5_Insync, &sh->dev[i].flags)) { | 1070 | if (!test_bit(R5_Insync, &sh->dev[i].flags) || |
1071 | test_bit(R5_ReadError, &sh->dev[i].flags)) { | ||
1019 | bi = sh->dev[i].toread; | 1072 | bi = sh->dev[i].toread; |
1020 | sh->dev[i].toread = NULL; | 1073 | sh->dev[i].toread = NULL; |
1021 | if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) | 1074 | if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) |
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh) | |||
1247 | !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { | 1300 | !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { |
1248 | /* parity is correct (on disc, not in buffer any more) */ | 1301 | /* parity is correct (on disc, not in buffer any more) */ |
1249 | set_bit(STRIPE_INSYNC, &sh->state); | 1302 | set_bit(STRIPE_INSYNC, &sh->state); |
1303 | } else { | ||
1304 | conf->mddev->resync_mismatches += STRIPE_SECTORS; | ||
1305 | if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) | ||
1306 | /* don't try to repair!! */ | ||
1307 | set_bit(STRIPE_INSYNC, &sh->state); | ||
1250 | } | 1308 | } |
1251 | } | 1309 | } |
1252 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { | 1310 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { |
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh) | |||
1274 | md_done_sync(conf->mddev, STRIPE_SECTORS,1); | 1332 | md_done_sync(conf->mddev, STRIPE_SECTORS,1); |
1275 | clear_bit(STRIPE_SYNCING, &sh->state); | 1333 | clear_bit(STRIPE_SYNCING, &sh->state); |
1276 | } | 1334 | } |
1277 | 1335 | ||
1336 | /* If the failed drive is just a ReadError, then we might need to progress | ||
1337 | * the repair/check process | ||
1338 | */ | ||
1339 | if (failed == 1 && ! conf->mddev->ro && | ||
1340 | test_bit(R5_ReadError, &sh->dev[failed_num].flags) | ||
1341 | && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags) | ||
1342 | && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags) | ||
1343 | ) { | ||
1344 | dev = &sh->dev[failed_num]; | ||
1345 | if (!test_bit(R5_ReWrite, &dev->flags)) { | ||
1346 | set_bit(R5_Wantwrite, &dev->flags); | ||
1347 | set_bit(R5_ReWrite, &dev->flags); | ||
1348 | set_bit(R5_LOCKED, &dev->flags); | ||
1349 | } else { | ||
1350 | /* let's read it back */ | ||
1351 | set_bit(R5_Wantread, &dev->flags); | ||
1352 | set_bit(R5_LOCKED, &dev->flags); | ||
1353 | } | ||
1354 | } | ||
1355 | |||
1278 | spin_unlock(&sh->lock); | 1356 | spin_unlock(&sh->lock); |
1279 | 1357 | ||
1280 | while ((bi=return_bi)) { | 1358 | while ((bi=return_bi)) { |
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh) | |||
1305 | bi->bi_end_io = raid5_end_read_request; | 1383 | bi->bi_end_io = raid5_end_read_request; |
1306 | 1384 | ||
1307 | rcu_read_lock(); | 1385 | rcu_read_lock(); |
1308 | rdev = conf->disks[i].rdev; | 1386 | rdev = rcu_dereference(conf->disks[i].rdev); |
1309 | if (rdev && rdev->faulty) | 1387 | if (rdev && test_bit(Faulty, &rdev->flags)) |
1310 | rdev = NULL; | 1388 | rdev = NULL; |
1311 | if (rdev) | 1389 | if (rdev) |
1312 | atomic_inc(&rdev->nr_pending); | 1390 | atomic_inc(&rdev->nr_pending); |
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev) | |||
1379 | 1457 | ||
1380 | rcu_read_lock(); | 1458 | rcu_read_lock(); |
1381 | for (i=0; i<mddev->raid_disks; i++) { | 1459 | for (i=0; i<mddev->raid_disks; i++) { |
1382 | mdk_rdev_t *rdev = conf->disks[i].rdev; | 1460 | mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); |
1383 | if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { | 1461 | if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { |
1384 | request_queue_t *r_queue = bdev_get_queue(rdev->bdev); | 1462 | request_queue_t *r_queue = bdev_get_queue(rdev->bdev); |
1385 | 1463 | ||
1386 | atomic_inc(&rdev->nr_pending); | 1464 | atomic_inc(&rdev->nr_pending); |
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
1424 | 1502 | ||
1425 | rcu_read_lock(); | 1503 | rcu_read_lock(); |
1426 | for (i=0; i<mddev->raid_disks && ret == 0; i++) { | 1504 | for (i=0; i<mddev->raid_disks && ret == 0; i++) { |
1427 | mdk_rdev_t *rdev = conf->disks[i].rdev; | 1505 | mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); |
1428 | if (rdev && !rdev->faulty) { | 1506 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
1429 | struct block_device *bdev = rdev->bdev; | 1507 | struct block_device *bdev = rdev->bdev; |
1430 | request_queue_t *r_queue = bdev_get_queue(bdev); | 1508 | request_queue_t *r_queue = bdev_get_queue(bdev); |
1431 | 1509 | ||
@@ -1567,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1567 | return rv; | 1645 | return rv; |
1568 | } | 1646 | } |
1569 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | 1647 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && |
1648 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && | ||
1570 | !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { | 1649 | !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { |
1571 | /* we can skip this block, and probably more */ | 1650 | /* we can skip this block, and probably more */ |
1572 | sync_blocks /= STRIPE_SECTORS; | 1651 | sync_blocks /= STRIPE_SECTORS; |
@@ -1663,6 +1742,74 @@ static void raid5d (mddev_t *mddev) | |||
1663 | PRINTK("--- raid5d inactive\n"); | 1742 | PRINTK("--- raid5d inactive\n"); |
1664 | } | 1743 | } |
1665 | 1744 | ||
1745 | static ssize_t | ||
1746 | raid5_show_stripe_cache_size(mddev_t *mddev, char *page) | ||
1747 | { | ||
1748 | raid5_conf_t *conf = mddev_to_conf(mddev); | ||
1749 | if (conf) | ||
1750 | return sprintf(page, "%d\n", conf->max_nr_stripes); | ||
1751 | else | ||
1752 | return 0; | ||
1753 | } | ||
1754 | |||
1755 | static ssize_t | ||
1756 | raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | ||
1757 | { | ||
1758 | raid5_conf_t *conf = mddev_to_conf(mddev); | ||
1759 | char *end; | ||
1760 | int new; | ||
1761 | if (len >= PAGE_SIZE) | ||
1762 | return -EINVAL; | ||
1763 | if (!conf) | ||
1764 | return -ENODEV; | ||
1765 | |||
1766 | new = simple_strtoul(page, &end, 10); | ||
1767 | if (!*page || (*end && *end != '\n') ) | ||
1768 | return -EINVAL; | ||
1769 | if (new <= 16 || new > 32768) | ||
1770 | return -EINVAL; | ||
1771 | while (new < conf->max_nr_stripes) { | ||
1772 | if (drop_one_stripe(conf)) | ||
1773 | conf->max_nr_stripes--; | ||
1774 | else | ||
1775 | break; | ||
1776 | } | ||
1777 | while (new > conf->max_nr_stripes) { | ||
1778 | if (grow_one_stripe(conf)) | ||
1779 | conf->max_nr_stripes++; | ||
1780 | else break; | ||
1781 | } | ||
1782 | return len; | ||
1783 | } | ||
1784 | |||
1785 | static struct md_sysfs_entry | ||
1786 | raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR, | ||
1787 | raid5_show_stripe_cache_size, | ||
1788 | raid5_store_stripe_cache_size); | ||
1789 | |||
1790 | static ssize_t | ||
1791 | stripe_cache_active_show(mddev_t *mddev, char *page) | ||
1792 | { | ||
1793 | raid5_conf_t *conf = mddev_to_conf(mddev); | ||
1794 | if (conf) | ||
1795 | return sprintf(page, "%d\n", atomic_read(&conf->active_stripes)); | ||
1796 | else | ||
1797 | return 0; | ||
1798 | } | ||
1799 | |||
1800 | static struct md_sysfs_entry | ||
1801 | raid5_stripecache_active = __ATTR_RO(stripe_cache_active); | ||
1802 | |||
1803 | static struct attribute *raid5_attrs[] = { | ||
1804 | &raid5_stripecache_size.attr, | ||
1805 | &raid5_stripecache_active.attr, | ||
1806 | NULL, | ||
1807 | }; | ||
1808 | static struct attribute_group raid5_attrs_group = { | ||
1809 | .name = NULL, | ||
1810 | .attrs = raid5_attrs, | ||
1811 | }; | ||
1812 | |||
1666 | static int run(mddev_t *mddev) | 1813 | static int run(mddev_t *mddev) |
1667 | { | 1814 | { |
1668 | raid5_conf_t *conf; | 1815 | raid5_conf_t *conf; |
@@ -1709,7 +1856,7 @@ static int run(mddev_t *mddev) | |||
1709 | 1856 | ||
1710 | disk->rdev = rdev; | 1857 | disk->rdev = rdev; |
1711 | 1858 | ||
1712 | if (rdev->in_sync) { | 1859 | if (test_bit(In_sync, &rdev->flags)) { |
1713 | char b[BDEVNAME_SIZE]; | 1860 | char b[BDEVNAME_SIZE]; |
1714 | printk(KERN_INFO "raid5: device %s operational as raid" | 1861 | printk(KERN_INFO "raid5: device %s operational as raid" |
1715 | " disk %d\n", bdevname(rdev->bdev,b), | 1862 | " disk %d\n", bdevname(rdev->bdev,b), |
@@ -1804,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + | |||
1804 | } | 1951 | } |
1805 | 1952 | ||
1806 | /* Ok, everything is just fine now */ | 1953 | /* Ok, everything is just fine now */ |
1954 | sysfs_create_group(&mddev->kobj, &raid5_attrs_group); | ||
1807 | 1955 | ||
1808 | if (mddev->bitmap) | 1956 | if (mddev->bitmap) |
1809 | mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; | 1957 | mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; |
@@ -1828,7 +1976,7 @@ abort: | |||
1828 | 1976 | ||
1829 | 1977 | ||
1830 | 1978 | ||
1831 | static int stop (mddev_t *mddev) | 1979 | static int stop(mddev_t *mddev) |
1832 | { | 1980 | { |
1833 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; | 1981 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; |
1834 | 1982 | ||
@@ -1837,6 +1985,7 @@ static int stop (mddev_t *mddev) | |||
1837 | shrink_stripes(conf); | 1985 | shrink_stripes(conf); |
1838 | free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); | 1986 | free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); |
1839 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 1987 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
1988 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); | ||
1840 | kfree(conf); | 1989 | kfree(conf); |
1841 | mddev->private = NULL; | 1990 | mddev->private = NULL; |
1842 | return 0; | 1991 | return 0; |
@@ -1887,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev) | |||
1887 | for (i = 0; i < conf->raid_disks; i++) | 2036 | for (i = 0; i < conf->raid_disks; i++) |
1888 | seq_printf (seq, "%s", | 2037 | seq_printf (seq, "%s", |
1889 | conf->disks[i].rdev && | 2038 | conf->disks[i].rdev && |
1890 | conf->disks[i].rdev->in_sync ? "U" : "_"); | 2039 | test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_"); |
1891 | seq_printf (seq, "]"); | 2040 | seq_printf (seq, "]"); |
1892 | #if RAID5_DEBUG | 2041 | #if RAID5_DEBUG |
1893 | #define D(x) \ | 2042 | #define D(x) \ |
@@ -1914,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf) | |||
1914 | tmp = conf->disks + i; | 2063 | tmp = conf->disks + i; |
1915 | if (tmp->rdev) | 2064 | if (tmp->rdev) |
1916 | printk(" disk %d, o:%d, dev:%s\n", | 2065 | printk(" disk %d, o:%d, dev:%s\n", |
1917 | i, !tmp->rdev->faulty, | 2066 | i, !test_bit(Faulty, &tmp->rdev->flags), |
1918 | bdevname(tmp->rdev->bdev,b)); | 2067 | bdevname(tmp->rdev->bdev,b)); |
1919 | } | 2068 | } |
1920 | } | 2069 | } |
@@ -1928,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev) | |||
1928 | for (i = 0; i < conf->raid_disks; i++) { | 2077 | for (i = 0; i < conf->raid_disks; i++) { |
1929 | tmp = conf->disks + i; | 2078 | tmp = conf->disks + i; |
1930 | if (tmp->rdev | 2079 | if (tmp->rdev |
1931 | && !tmp->rdev->faulty | 2080 | && !test_bit(Faulty, &tmp->rdev->flags) |
1932 | && !tmp->rdev->in_sync) { | 2081 | && !test_bit(In_sync, &tmp->rdev->flags)) { |
1933 | mddev->degraded--; | 2082 | mddev->degraded--; |
1934 | conf->failed_disks--; | 2083 | conf->failed_disks--; |
1935 | conf->working_disks++; | 2084 | conf->working_disks++; |
1936 | tmp->rdev->in_sync = 1; | 2085 | set_bit(In_sync, &tmp->rdev->flags); |
1937 | } | 2086 | } |
1938 | } | 2087 | } |
1939 | print_raid5_conf(conf); | 2088 | print_raid5_conf(conf); |
@@ -1950,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
1950 | print_raid5_conf(conf); | 2099 | print_raid5_conf(conf); |
1951 | rdev = p->rdev; | 2100 | rdev = p->rdev; |
1952 | if (rdev) { | 2101 | if (rdev) { |
1953 | if (rdev->in_sync || | 2102 | if (test_bit(In_sync, &rdev->flags) || |
1954 | atomic_read(&rdev->nr_pending)) { | 2103 | atomic_read(&rdev->nr_pending)) { |
1955 | err = -EBUSY; | 2104 | err = -EBUSY; |
1956 | goto abort; | 2105 | goto abort; |
@@ -1985,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1985 | */ | 2134 | */ |
1986 | for (disk=0; disk < mddev->raid_disks; disk++) | 2135 | for (disk=0; disk < mddev->raid_disks; disk++) |
1987 | if ((p=conf->disks + disk)->rdev == NULL) { | 2136 | if ((p=conf->disks + disk)->rdev == NULL) { |
1988 | rdev->in_sync = 0; | 2137 | clear_bit(In_sync, &rdev->flags); |
1989 | rdev->raid_disk = disk; | 2138 | rdev->raid_disk = disk; |
1990 | found = 1; | 2139 | found = 1; |
1991 | if (rdev->saved_raid_disk != disk) | 2140 | if (rdev->saved_raid_disk != disk) |
1992 | conf->fullsync = 1; | 2141 | conf->fullsync = 1; |
1993 | p->rdev = rdev; | 2142 | rcu_assign_pointer(p->rdev, rdev); |
1994 | break; | 2143 | break; |
1995 | } | 2144 | } |
1996 | print_raid5_conf(conf); | 2145 | print_raid5_conf(conf); |