diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-20 11:37:37 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-20 11:37:37 -0400 |
| commit | 2edbdd1266784495979576c4ab4ef294c29bad27 (patch) | |
| tree | fd4909b58e783145f19cde650e7d4d16daa36b21 | |
| parent | a5432f5ad43822802ba6f8ba8662ca6361712044 (diff) | |
| parent | 1f59390339f263c0fe7908fbe54466dbf3a64b58 (diff) | |
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md:
md: support bitmaps on RAID10 arrays larger then 2 terabytes
md: update sync_completed and reshape_position even more often.
md: improve usefulness and accuracy of sysfs file md/sync_completed.
md: allow setting newly added device to 'in_sync' via sysfs.
md: tiny md.h cleanups
| -rw-r--r-- | drivers/md/bitmap.c | 7 | ||||
| -rw-r--r-- | drivers/md/md.c | 41 | ||||
| -rw-r--r-- | drivers/md/md.h | 21 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 7 |
4 files changed, 51 insertions, 25 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f8a9f7ab2cb8..1fb91edc7de2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | |||
| 1479 | s += blocks; | 1479 | s += blocks; |
| 1480 | } | 1480 | } |
| 1481 | bitmap->last_end_sync = jiffies; | 1481 | bitmap->last_end_sync = jiffies; |
| 1482 | sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed"); | ||
| 1482 | } | 1483 | } |
| 1483 | 1484 | ||
| 1484 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) | 1485 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) |
| @@ -1589,7 +1590,7 @@ void bitmap_destroy(mddev_t *mddev) | |||
| 1589 | int bitmap_create(mddev_t *mddev) | 1590 | int bitmap_create(mddev_t *mddev) |
| 1590 | { | 1591 | { |
| 1591 | struct bitmap *bitmap; | 1592 | struct bitmap *bitmap; |
| 1592 | unsigned long blocks = mddev->resync_max_sectors; | 1593 | sector_t blocks = mddev->resync_max_sectors; |
| 1593 | unsigned long chunks; | 1594 | unsigned long chunks; |
| 1594 | unsigned long pages; | 1595 | unsigned long pages; |
| 1595 | struct file *file = mddev->bitmap_file; | 1596 | struct file *file = mddev->bitmap_file; |
| @@ -1631,8 +1632,8 @@ int bitmap_create(mddev_t *mddev) | |||
| 1631 | bitmap->chunkshift = ffz(~bitmap->chunksize); | 1632 | bitmap->chunkshift = ffz(~bitmap->chunksize); |
| 1632 | 1633 | ||
| 1633 | /* now that chunksize and chunkshift are set, we can use these macros */ | 1634 | /* now that chunksize and chunkshift are set, we can use these macros */ |
| 1634 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / | 1635 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >> |
| 1635 | CHUNK_BLOCK_RATIO(bitmap); | 1636 | CHUNK_BLOCK_SHIFT(bitmap); |
| 1636 | pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; | 1637 | pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; |
| 1637 | 1638 | ||
| 1638 | BUG_ON(!pages); | 1639 | BUG_ON(!pages); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index ed5727c089a9..612343fdde94 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -2017,6 +2017,8 @@ repeat: | |||
| 2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | 2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
| 2018 | spin_unlock_irq(&mddev->write_lock); | 2018 | spin_unlock_irq(&mddev->write_lock); |
| 2019 | wake_up(&mddev->sb_wait); | 2019 | wake_up(&mddev->sb_wait); |
| 2020 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
| 2021 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 2020 | 2022 | ||
| 2021 | } | 2023 | } |
| 2022 | 2024 | ||
| @@ -2086,6 +2088,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2086 | * -writemostly - clears write_mostly | 2088 | * -writemostly - clears write_mostly |
| 2087 | * blocked - sets the Blocked flag | 2089 | * blocked - sets the Blocked flag |
| 2088 | * -blocked - clears the Blocked flag | 2090 | * -blocked - clears the Blocked flag |
| 2091 | * insync - sets Insync providing device isn't active | ||
| 2089 | */ | 2092 | */ |
| 2090 | int err = -EINVAL; | 2093 | int err = -EINVAL; |
| 2091 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { | 2094 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { |
| @@ -2118,6 +2121,9 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2118 | md_wakeup_thread(rdev->mddev->thread); | 2121 | md_wakeup_thread(rdev->mddev->thread); |
| 2119 | 2122 | ||
| 2120 | err = 0; | 2123 | err = 0; |
| 2124 | } else if (cmd_match(buf, "insync") && rdev->raid_disk == -1) { | ||
| 2125 | set_bit(In_sync, &rdev->flags); | ||
| 2126 | err = 0; | ||
| 2121 | } | 2127 | } |
| 2122 | if (!err && rdev->sysfs_state) | 2128 | if (!err && rdev->sysfs_state) |
| 2123 | sysfs_notify_dirent(rdev->sysfs_state); | 2129 | sysfs_notify_dirent(rdev->sysfs_state); |
| @@ -2190,7 +2196,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2190 | } else if (rdev->mddev->pers) { | 2196 | } else if (rdev->mddev->pers) { |
| 2191 | mdk_rdev_t *rdev2; | 2197 | mdk_rdev_t *rdev2; |
| 2192 | /* Activating a spare .. or possibly reactivating | 2198 | /* Activating a spare .. or possibly reactivating |
| 2193 | * if we every get bitmaps working here. | 2199 | * if we ever get bitmaps working here. |
| 2194 | */ | 2200 | */ |
| 2195 | 2201 | ||
| 2196 | if (rdev->raid_disk != -1) | 2202 | if (rdev->raid_disk != -1) |
| @@ -3482,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
| 3482 | { | 3488 | { |
| 3483 | unsigned long max_sectors, resync; | 3489 | unsigned long max_sectors, resync; |
| 3484 | 3490 | ||
| 3491 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
| 3492 | return sprintf(page, "none\n"); | ||
| 3493 | |||
| 3485 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 3494 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
| 3486 | max_sectors = mddev->resync_max_sectors; | 3495 | max_sectors = mddev->resync_max_sectors; |
| 3487 | else | 3496 | else |
| 3488 | max_sectors = mddev->dev_sectors; | 3497 | max_sectors = mddev->dev_sectors; |
| 3489 | 3498 | ||
| 3490 | resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); | 3499 | resync = mddev->curr_resync_completed; |
| 3491 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); | 3500 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); |
| 3492 | } | 3501 | } |
| 3493 | 3502 | ||
| @@ -6334,18 +6343,13 @@ void md_do_sync(mddev_t *mddev) | |||
| 6334 | sector_t sectors; | 6343 | sector_t sectors; |
| 6335 | 6344 | ||
| 6336 | skipped = 0; | 6345 | skipped = 0; |
| 6337 | if (j >= mddev->resync_max) { | ||
| 6338 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 6339 | wait_event(mddev->recovery_wait, | ||
| 6340 | mddev->resync_max > j | ||
| 6341 | || kthread_should_stop()); | ||
| 6342 | } | ||
| 6343 | if (kthread_should_stop()) | ||
| 6344 | goto interrupted; | ||
| 6345 | 6346 | ||
| 6346 | if (mddev->curr_resync > mddev->curr_resync_completed && | 6347 | if ((mddev->curr_resync > mddev->curr_resync_completed && |
| 6347 | (mddev->curr_resync - mddev->curr_resync_completed) | 6348 | (mddev->curr_resync - mddev->curr_resync_completed) |
| 6348 | > (max_sectors >> 4)) { | 6349 | > (max_sectors >> 4)) || |
| 6350 | (j - mddev->curr_resync_completed)*2 | ||
| 6351 | >= mddev->resync_max - mddev->curr_resync_completed | ||
| 6352 | ) { | ||
| 6349 | /* time to update curr_resync_completed */ | 6353 | /* time to update curr_resync_completed */ |
| 6350 | blk_unplug(mddev->queue); | 6354 | blk_unplug(mddev->queue); |
| 6351 | wait_event(mddev->recovery_wait, | 6355 | wait_event(mddev->recovery_wait, |
| @@ -6353,7 +6357,17 @@ void md_do_sync(mddev_t *mddev) | |||
| 6353 | mddev->curr_resync_completed = | 6357 | mddev->curr_resync_completed = |
| 6354 | mddev->curr_resync; | 6358 | mddev->curr_resync; |
| 6355 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6359 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
| 6360 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 6356 | } | 6361 | } |
| 6362 | |||
| 6363 | if (j >= mddev->resync_max) | ||
| 6364 | wait_event(mddev->recovery_wait, | ||
| 6365 | mddev->resync_max > j | ||
| 6366 | || kthread_should_stop()); | ||
| 6367 | |||
| 6368 | if (kthread_should_stop()) | ||
| 6369 | goto interrupted; | ||
| 6370 | |||
| 6357 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 6371 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
| 6358 | currspeed < speed_min(mddev)); | 6372 | currspeed < speed_min(mddev)); |
| 6359 | if (sectors == 0) { | 6373 | if (sectors == 0) { |
| @@ -6461,6 +6475,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 6461 | 6475 | ||
| 6462 | skip: | 6476 | skip: |
| 6463 | mddev->curr_resync = 0; | 6477 | mddev->curr_resync = 0; |
| 6478 | mddev->curr_resync_completed = 0; | ||
| 6464 | mddev->resync_min = 0; | 6479 | mddev->resync_min = 0; |
| 6465 | mddev->resync_max = MaxSector; | 6480 | mddev->resync_max = MaxSector; |
| 6466 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6481 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
diff --git a/drivers/md/md.h b/drivers/md/md.h index e9b7f54c24d6..8227ab909d44 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
| @@ -12,10 +12,17 @@ | |||
| 12 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 12 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #ifndef _MD_K_H | 15 | #ifndef _MD_MD_H |
| 16 | #define _MD_K_H | 16 | #define _MD_MD_H |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_BLOCK | 18 | #include <linux/blkdev.h> |
| 19 | #include <linux/kobject.h> | ||
| 20 | #include <linux/list.h> | ||
| 21 | #include <linux/mm.h> | ||
| 22 | #include <linux/mutex.h> | ||
| 23 | #include <linux/timer.h> | ||
| 24 | #include <linux/wait.h> | ||
| 25 | #include <linux/workqueue.h> | ||
| 19 | 26 | ||
| 20 | #define MaxSector (~(sector_t)0) | 27 | #define MaxSector (~(sector_t)0) |
| 21 | 28 | ||
| @@ -408,10 +415,6 @@ static inline void safe_put_page(struct page *p) | |||
| 408 | if (p) put_page(p); | 415 | if (p) put_page(p); |
| 409 | } | 416 | } |
| 410 | 417 | ||
| 411 | #endif /* CONFIG_BLOCK */ | ||
| 412 | #endif | ||
| 413 | |||
| 414 | |||
| 415 | extern int register_md_personality(struct mdk_personality *p); | 418 | extern int register_md_personality(struct mdk_personality *p); |
| 416 | extern int unregister_md_personality(struct mdk_personality *p); | 419 | extern int unregister_md_personality(struct mdk_personality *p); |
| 417 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), | 420 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), |
| @@ -434,3 +437,5 @@ extern void md_new_event(mddev_t *mddev); | |||
| 434 | extern int md_allow_write(mddev_t *mddev); | 437 | extern int md_allow_write(mddev_t *mddev); |
| 435 | extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); | 438 | extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); |
| 436 | extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); | 439 | extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); |
| 440 | |||
| 441 | #endif /* _MD_MD_H */ | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3bbc6d647044..4616bc3a6e71 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
| 3845 | wait_event(conf->wait_for_overlap, | 3845 | wait_event(conf->wait_for_overlap, |
| 3846 | atomic_read(&conf->reshape_stripes)==0); | 3846 | atomic_read(&conf->reshape_stripes)==0); |
| 3847 | mddev->reshape_position = conf->reshape_progress; | 3847 | mddev->reshape_position = conf->reshape_progress; |
| 3848 | mddev->curr_resync_completed = mddev->curr_resync; | ||
| 3848 | conf->reshape_checkpoint = jiffies; | 3849 | conf->reshape_checkpoint = jiffies; |
| 3849 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 3850 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
| 3850 | md_wakeup_thread(mddev->thread); | 3851 | md_wakeup_thread(mddev->thread); |
| @@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
| 3854 | conf->reshape_safe = mddev->reshape_position; | 3855 | conf->reshape_safe = mddev->reshape_position; |
| 3855 | spin_unlock_irq(&conf->device_lock); | 3856 | spin_unlock_irq(&conf->device_lock); |
| 3856 | wake_up(&conf->wait_for_overlap); | 3857 | wake_up(&conf->wait_for_overlap); |
| 3858 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 3857 | } | 3859 | } |
| 3858 | 3860 | ||
| 3859 | if (mddev->delta_disks < 0) { | 3861 | if (mddev->delta_disks < 0) { |
| @@ -3938,11 +3940,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
| 3938 | * then we need to write out the superblock. | 3940 | * then we need to write out the superblock. |
| 3939 | */ | 3941 | */ |
| 3940 | sector_nr += reshape_sectors; | 3942 | sector_nr += reshape_sectors; |
| 3941 | if (sector_nr >= mddev->resync_max) { | 3943 | if ((sector_nr - mddev->curr_resync_completed) * 2 |
| 3944 | >= mddev->resync_max - mddev->curr_resync_completed) { | ||
| 3942 | /* Cannot proceed until we've updated the superblock... */ | 3945 | /* Cannot proceed until we've updated the superblock... */ |
| 3943 | wait_event(conf->wait_for_overlap, | 3946 | wait_event(conf->wait_for_overlap, |
| 3944 | atomic_read(&conf->reshape_stripes) == 0); | 3947 | atomic_read(&conf->reshape_stripes) == 0); |
| 3945 | mddev->reshape_position = conf->reshape_progress; | 3948 | mddev->reshape_position = conf->reshape_progress; |
| 3949 | mddev->curr_resync_completed = mddev->curr_resync; | ||
| 3946 | conf->reshape_checkpoint = jiffies; | 3950 | conf->reshape_checkpoint = jiffies; |
| 3947 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 3951 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
| 3948 | md_wakeup_thread(mddev->thread); | 3952 | md_wakeup_thread(mddev->thread); |
| @@ -3953,6 +3957,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
| 3953 | conf->reshape_safe = mddev->reshape_position; | 3957 | conf->reshape_safe = mddev->reshape_position; |
| 3954 | spin_unlock_irq(&conf->device_lock); | 3958 | spin_unlock_irq(&conf->device_lock); |
| 3955 | wake_up(&conf->wait_for_overlap); | 3959 | wake_up(&conf->wait_for_overlap); |
| 3960 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 3956 | } | 3961 | } |
| 3957 | return reshape_sectors; | 3962 | return reshape_sectors; |
| 3958 | } | 3963 | } |
