Commit 2edbdd12 authored by Linus Torvalds's avatar Linus Torvalds

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
parents a5432f5a 1f593903
...@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) ...@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
s += blocks; s += blocks;
} }
bitmap->last_end_sync = jiffies; bitmap->last_end_sync = jiffies;
sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
} }
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) 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,7 +1590,7 @@ void bitmap_destroy(mddev_t *mddev)
int bitmap_create(mddev_t *mddev) int bitmap_create(mddev_t *mddev)
{ {
struct bitmap *bitmap; struct bitmap *bitmap;
unsigned long blocks = mddev->resync_max_sectors; sector_t blocks = mddev->resync_max_sectors;
unsigned long chunks; unsigned long chunks;
unsigned long pages; unsigned long pages;
struct file *file = mddev->bitmap_file; struct file *file = mddev->bitmap_file;
...@@ -1631,8 +1632,8 @@ int bitmap_create(mddev_t *mddev) ...@@ -1631,8 +1632,8 @@ int bitmap_create(mddev_t *mddev)
bitmap->chunkshift = ffz(~bitmap->chunksize); bitmap->chunkshift = ffz(~bitmap->chunksize);
/* now that chunksize and chunkshift are set, we can use these macros */ /* now that chunksize and chunkshift are set, we can use these macros */
chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
CHUNK_BLOCK_RATIO(bitmap); CHUNK_BLOCK_SHIFT(bitmap);
pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
BUG_ON(!pages); BUG_ON(!pages);
......
...@@ -2017,6 +2017,8 @@ static void md_update_sb(mddev_t * mddev, int force_change) ...@@ -2017,6 +2017,8 @@ static void md_update_sb(mddev_t * mddev, int force_change)
clear_bit(MD_CHANGE_PENDING, &mddev->flags); clear_bit(MD_CHANGE_PENDING, &mddev->flags);
spin_unlock_irq(&mddev->write_lock); spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait); wake_up(&mddev->sb_wait);
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
} }
...@@ -2086,6 +2088,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2086,6 +2088,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
* -writemostly - clears write_mostly * -writemostly - clears write_mostly
* blocked - sets the Blocked flag * blocked - sets the Blocked flag
* -blocked - clears the Blocked flag * -blocked - clears the Blocked flag
* insync - sets Insync providing device isn't active
*/ */
int err = -EINVAL; int err = -EINVAL;
if (cmd_match(buf, "faulty") && rdev->mddev->pers) { if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
...@@ -2117,6 +2120,9 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2117,6 +2120,9 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
md_wakeup_thread(rdev->mddev->thread); md_wakeup_thread(rdev->mddev->thread);
err = 0;
} else if (cmd_match(buf, "insync") && rdev->raid_disk == -1) {
set_bit(In_sync, &rdev->flags);
err = 0; err = 0;
} }
if (!err && rdev->sysfs_state) if (!err && rdev->sysfs_state)
...@@ -2190,7 +2196,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2190,7 +2196,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
} else if (rdev->mddev->pers) { } else if (rdev->mddev->pers) {
mdk_rdev_t *rdev2; mdk_rdev_t *rdev2;
/* Activating a spare .. or possibly reactivating /* Activating a spare .. or possibly reactivating
* if we every get bitmaps working here. * if we ever get bitmaps working here.
*/ */
if (rdev->raid_disk != -1) if (rdev->raid_disk != -1)
...@@ -3482,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page) ...@@ -3482,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page)
{ {
unsigned long max_sectors, resync; unsigned long max_sectors, resync;
if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return sprintf(page, "none\n");
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_sectors = mddev->resync_max_sectors; max_sectors = mddev->resync_max_sectors;
else else
max_sectors = mddev->dev_sectors; max_sectors = mddev->dev_sectors;
resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); resync = mddev->curr_resync_completed;
return sprintf(page, "%lu / %lu\n", resync, max_sectors); return sprintf(page, "%lu / %lu\n", resync, max_sectors);
} }
...@@ -6334,18 +6343,13 @@ void md_do_sync(mddev_t *mddev) ...@@ -6334,18 +6343,13 @@ void md_do_sync(mddev_t *mddev)
sector_t sectors; sector_t sectors;
skipped = 0; skipped = 0;
if (j >= mddev->resync_max) {
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
wait_event(mddev->recovery_wait,
mddev->resync_max > j
|| kthread_should_stop());
}
if (kthread_should_stop())
goto interrupted;
if (mddev->curr_resync > mddev->curr_resync_completed && if ((mddev->curr_resync > mddev->curr_resync_completed &&
(mddev->curr_resync - mddev->curr_resync_completed) (mddev->curr_resync - mddev->curr_resync_completed)
> (max_sectors >> 4)) { > (max_sectors >> 4)) ||
(j - mddev->curr_resync_completed)*2
>= mddev->resync_max - mddev->curr_resync_completed
) {
/* time to update curr_resync_completed */ /* time to update curr_resync_completed */
blk_unplug(mddev->queue); blk_unplug(mddev->queue);
wait_event(mddev->recovery_wait, wait_event(mddev->recovery_wait,
...@@ -6353,7 +6357,17 @@ void md_do_sync(mddev_t *mddev) ...@@ -6353,7 +6357,17 @@ void md_do_sync(mddev_t *mddev)
mddev->curr_resync_completed = mddev->curr_resync_completed =
mddev->curr_resync; mddev->curr_resync;
set_bit(MD_CHANGE_CLEAN, &mddev->flags); set_bit(MD_CHANGE_CLEAN, &mddev->flags);
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
} }
if (j >= mddev->resync_max)
wait_event(mddev->recovery_wait,
mddev->resync_max > j
|| kthread_should_stop());
if (kthread_should_stop())
goto interrupted;
sectors = mddev->pers->sync_request(mddev, j, &skipped, sectors = mddev->pers->sync_request(mddev, j, &skipped,
currspeed < speed_min(mddev)); currspeed < speed_min(mddev));
if (sectors == 0) { if (sectors == 0) {
...@@ -6461,6 +6475,7 @@ void md_do_sync(mddev_t *mddev) ...@@ -6461,6 +6475,7 @@ void md_do_sync(mddev_t *mddev)
skip: skip:
mddev->curr_resync = 0; mddev->curr_resync = 0;
mddev->curr_resync_completed = 0;
mddev->resync_min = 0; mddev->resync_min = 0;
mddev->resync_max = MaxSector; mddev->resync_max = MaxSector;
sysfs_notify(&mddev->kobj, NULL, "sync_completed"); sysfs_notify(&mddev->kobj, NULL, "sync_completed");
......
...@@ -12,10 +12,17 @@ ...@@ -12,10 +12,17 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef _MD_K_H #ifndef _MD_MD_H
#define _MD_K_H #define _MD_MD_H
#ifdef CONFIG_BLOCK #include <linux/blkdev.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#define MaxSector (~(sector_t)0) #define MaxSector (~(sector_t)0)
...@@ -408,10 +415,6 @@ static inline void safe_put_page(struct page *p) ...@@ -408,10 +415,6 @@ static inline void safe_put_page(struct page *p)
if (p) put_page(p); if (p) put_page(p);
} }
#endif /* CONFIG_BLOCK */
#endif
extern int register_md_personality(struct mdk_personality *p); extern int register_md_personality(struct mdk_personality *p);
extern int unregister_md_personality(struct mdk_personality *p); extern int unregister_md_personality(struct mdk_personality *p);
extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), 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,3 +437,5 @@ extern void md_new_event(mddev_t *mddev);
extern int md_allow_write(mddev_t *mddev); extern int md_allow_write(mddev_t *mddev);
extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
#endif /* _MD_MD_H */
...@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
wait_event(conf->wait_for_overlap, wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes)==0); atomic_read(&conf->reshape_stripes)==0);
mddev->reshape_position = conf->reshape_progress; mddev->reshape_position = conf->reshape_progress;
mddev->curr_resync_completed = mddev->curr_resync;
conf->reshape_checkpoint = jiffies; conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
...@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
conf->reshape_safe = mddev->reshape_position; conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap); wake_up(&conf->wait_for_overlap);
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
} }
if (mddev->delta_disks < 0) { if (mddev->delta_disks < 0) {
...@@ -3938,11 +3940,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3938,11 +3940,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
* then we need to write out the superblock. * then we need to write out the superblock.
*/ */
sector_nr += reshape_sectors; sector_nr += reshape_sectors;
if (sector_nr >= mddev->resync_max) { if ((sector_nr - mddev->curr_resync_completed) * 2
>= mddev->resync_max - mddev->curr_resync_completed) {
/* Cannot proceed until we've updated the superblock... */ /* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap, wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes) == 0); atomic_read(&conf->reshape_stripes) == 0);
mddev->reshape_position = conf->reshape_progress; mddev->reshape_position = conf->reshape_progress;
mddev->curr_resync_completed = mddev->curr_resync;
conf->reshape_checkpoint = jiffies; conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
...@@ -3953,6 +3957,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3953,6 +3957,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
conf->reshape_safe = mddev->reshape_position; conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap); wake_up(&conf->wait_for_overlap);
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
} }
return reshape_sectors; return reshape_sectors;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment