aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c76
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/md/raid10.c2
-rw-r--r--drivers/md/raid5.c8
-rw-r--r--include/linux/raid/md.h1
-rw-r--r--include/linux/raid/md_k.h6
7 files changed, 52 insertions, 46 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3af6f1f06020..8b08043f07ef 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1587,7 +1587,7 @@ static void sync_sbs(mddev_t * mddev, int nospares)
1587 } 1587 }
1588} 1588}
1589 1589
1590void md_update_sb(mddev_t * mddev) 1590static void md_update_sb(mddev_t * mddev, int force_change)
1591{ 1591{
1592 int err; 1592 int err;
1593 struct list_head *tmp; 1593 struct list_head *tmp;
@@ -1598,7 +1598,18 @@ void md_update_sb(mddev_t * mddev)
1598repeat: 1598repeat:
1599 spin_lock_irq(&mddev->write_lock); 1599 spin_lock_irq(&mddev->write_lock);
1600 1600
1601 if (mddev->degraded && mddev->sb_dirty == 3) 1601 set_bit(MD_CHANGE_PENDING, &mddev->flags);
1602 if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
1603 force_change = 1;
1604 if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
1605 /* just a clean<-> dirty transition, possibly leave spares alone,
1606 * though if events isn't the right even/odd, we will have to do
1607 * spares after all
1608 */
1609 nospares = 1;
1610 if (force_change)
1611 nospares = 0;
1612 if (mddev->degraded)
1602 /* If the array is degraded, then skipping spares is both 1613 /* If the array is degraded, then skipping spares is both
1603 * dangerous and fairly pointless. 1614 * dangerous and fairly pointless.
1604 * Dangerous because a device that was removed from the array 1615 * Dangerous because a device that was removed from the array
@@ -1608,20 +1619,14 @@ repeat:
1608 * then a recovery will happen and soon that array won't 1619 * then a recovery will happen and soon that array won't
1609 * be degraded any more and the spare can go back to sleep then. 1620 * be degraded any more and the spare can go back to sleep then.
1610 */ 1621 */
1611 mddev->sb_dirty = 1; 1622 nospares = 0;
1612 1623
1613 sync_req = mddev->in_sync; 1624 sync_req = mddev->in_sync;
1614 mddev->utime = get_seconds(); 1625 mddev->utime = get_seconds();
1615 if (mddev->sb_dirty == 3)
1616 /* just a clean<-> dirty transition, possibly leave spares alone,
1617 * though if events isn't the right even/odd, we will have to do
1618 * spares after all
1619 */
1620 nospares = 1;
1621 1626
1622 /* If this is just a dirty<->clean transition, and the array is clean 1627 /* If this is just a dirty<->clean transition, and the array is clean
1623 * and 'events' is odd, we can roll back to the previous clean state */ 1628 * and 'events' is odd, we can roll back to the previous clean state */
1624 if (mddev->sb_dirty == 3 1629 if (nospares
1625 && (mddev->in_sync && mddev->recovery_cp == MaxSector) 1630 && (mddev->in_sync && mddev->recovery_cp == MaxSector)
1626 && (mddev->events & 1)) 1631 && (mddev->events & 1))
1627 mddev->events--; 1632 mddev->events--;
@@ -1652,7 +1657,6 @@ repeat:
1652 MD_BUG(); 1657 MD_BUG();
1653 mddev->events --; 1658 mddev->events --;
1654 } 1659 }
1655 mddev->sb_dirty = 2;
1656 sync_sbs(mddev, nospares); 1660 sync_sbs(mddev, nospares);
1657 1661
1658 /* 1662 /*
@@ -1660,7 +1664,7 @@ repeat:
1660 * nonpersistent superblocks 1664 * nonpersistent superblocks
1661 */ 1665 */
1662 if (!mddev->persistent) { 1666 if (!mddev->persistent) {
1663 mddev->sb_dirty = 0; 1667 clear_bit(MD_CHANGE_PENDING, &mddev->flags);
1664 spin_unlock_irq(&mddev->write_lock); 1668 spin_unlock_irq(&mddev->write_lock);
1665 wake_up(&mddev->sb_wait); 1669 wake_up(&mddev->sb_wait);
1666 return; 1670 return;
@@ -1697,20 +1701,20 @@ repeat:
1697 break; 1701 break;
1698 } 1702 }
1699 md_super_wait(mddev); 1703 md_super_wait(mddev);
1700 /* if there was a failure, sb_dirty was set to 1, and we re-write super */ 1704 /* if there was a failure, MD_CHANGE_DEVS was set, and we re-write super */
1701 1705
1702 spin_lock_irq(&mddev->write_lock); 1706 spin_lock_irq(&mddev->write_lock);
1703 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { 1707 if (mddev->in_sync != sync_req ||
1708 test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
1704 /* have to write it out again */ 1709 /* have to write it out again */
1705 spin_unlock_irq(&mddev->write_lock); 1710 spin_unlock_irq(&mddev->write_lock);
1706 goto repeat; 1711 goto repeat;
1707 } 1712 }
1708 mddev->sb_dirty = 0; 1713 clear_bit(MD_CHANGE_PENDING, &mddev->flags);
1709 spin_unlock_irq(&mddev->write_lock); 1714 spin_unlock_irq(&mddev->write_lock);
1710 wake_up(&mddev->sb_wait); 1715 wake_up(&mddev->sb_wait);
1711 1716
1712} 1717}
1713EXPORT_SYMBOL_GPL(md_update_sb);
1714 1718
1715/* words written to sysfs files may, or my not, be \n terminated. 1719/* words written to sysfs files may, or my not, be \n terminated.
1716 * We want to accept with case. For this we use cmd_match. 1720 * We want to accept with case. For this we use cmd_match.
@@ -1783,7 +1787,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1783 else { 1787 else {
1784 mddev_t *mddev = rdev->mddev; 1788 mddev_t *mddev = rdev->mddev;
1785 kick_rdev_from_array(rdev); 1789 kick_rdev_from_array(rdev);
1786 md_update_sb(mddev); 1790 md_update_sb(mddev, 1);
1787 md_new_event(mddev); 1791 md_new_event(mddev);
1788 err = 0; 1792 err = 0;
1789 } 1793 }
@@ -2426,7 +2430,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
2426 spin_lock_irq(&mddev->write_lock); 2430 spin_lock_irq(&mddev->write_lock);
2427 if (atomic_read(&mddev->writes_pending) == 0) { 2431 if (atomic_read(&mddev->writes_pending) == 0) {
2428 mddev->in_sync = 1; 2432 mddev->in_sync = 1;
2429 mddev->sb_dirty = 1; 2433 set_bit(MD_CHANGE_CLEAN, &mddev->flags);
2430 } 2434 }
2431 spin_unlock_irq(&mddev->write_lock); 2435 spin_unlock_irq(&mddev->write_lock);
2432 } else { 2436 } else {
@@ -2438,7 +2442,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
2438 case active: 2442 case active:
2439 if (mddev->pers) { 2443 if (mddev->pers) {
2440 restart_array(mddev); 2444 restart_array(mddev);
2441 mddev->sb_dirty = 0; 2445 clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
2442 wake_up(&mddev->sb_wait); 2446 wake_up(&mddev->sb_wait);
2443 err = 0; 2447 err = 0;
2444 } else { 2448 } else {
@@ -2543,7 +2547,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
2543 2547
2544 if (mddev->pers) { 2548 if (mddev->pers) {
2545 err = update_size(mddev, size); 2549 err = update_size(mddev, size);
2546 md_update_sb(mddev); 2550 md_update_sb(mddev, 1);
2547 } else { 2551 } else {
2548 if (mddev->size == 0 || 2552 if (mddev->size == 0 ||
2549 mddev->size > size) 2553 mddev->size > size)
@@ -3111,8 +3115,8 @@ static int do_md_run(mddev_t * mddev)
3111 3115
3112 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3116 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3113 3117
3114 if (mddev->sb_dirty) 3118 if (mddev->flags)
3115 md_update_sb(mddev); 3119 md_update_sb(mddev, 0);
3116 3120
3117 set_capacity(disk, mddev->array_size<<1); 3121 set_capacity(disk, mddev->array_size<<1);
3118 3122
@@ -3275,10 +3279,10 @@ static int do_md_stop(mddev_t * mddev, int mode)
3275 if (mddev->ro) 3279 if (mddev->ro)
3276 mddev->ro = 0; 3280 mddev->ro = 0;
3277 } 3281 }
3278 if (!mddev->in_sync || mddev->sb_dirty) { 3282 if (!mddev->in_sync || mddev->flags) {
3279 /* mark array as shutdown cleanly */ 3283 /* mark array as shutdown cleanly */
3280 mddev->in_sync = 1; 3284 mddev->in_sync = 1;
3281 md_update_sb(mddev); 3285 md_update_sb(mddev, 1);
3282 } 3286 }
3283 if (mode == 1) 3287 if (mode == 1)
3284 set_disk_ro(disk, 1); 3288 set_disk_ro(disk, 1);
@@ -3747,7 +3751,7 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev)
3747 goto busy; 3751 goto busy;
3748 3752
3749 kick_rdev_from_array(rdev); 3753 kick_rdev_from_array(rdev);
3750 md_update_sb(mddev); 3754 md_update_sb(mddev, 1);
3751 md_new_event(mddev); 3755 md_new_event(mddev);
3752 3756
3753 return 0; 3757 return 0;
@@ -3824,7 +3828,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
3824 3828
3825 rdev->raid_disk = -1; 3829 rdev->raid_disk = -1;
3826 3830
3827 md_update_sb(mddev); 3831 md_update_sb(mddev, 1);
3828 3832
3829 /* 3833 /*
3830 * Kick recovery, maybe this spare has to be added to the 3834 * Kick recovery, maybe this spare has to be added to the
@@ -3955,7 +3959,8 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
3955 3959
3956 mddev->max_disks = MD_SB_DISKS; 3960 mddev->max_disks = MD_SB_DISKS;
3957 3961
3958 mddev->sb_dirty = 1; 3962 mddev->flags = 0;
3963 set_bit(MD_CHANGE_DEVS, &mddev->flags);
3959 3964
3960 mddev->default_bitmap_offset = MD_SB_BYTES >> 9; 3965 mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
3961 mddev->bitmap_offset = 0; 3966 mddev->bitmap_offset = 0;
@@ -4124,7 +4129,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
4124 mddev->bitmap_offset = 0; 4129 mddev->bitmap_offset = 0;
4125 } 4130 }
4126 } 4131 }
4127 md_update_sb(mddev); 4132 md_update_sb(mddev, 1);
4128 return rv; 4133 return rv;
4129} 4134}
4130 4135
@@ -4960,12 +4965,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
4960 spin_lock_irq(&mddev->write_lock); 4965 spin_lock_irq(&mddev->write_lock);
4961 if (mddev->in_sync) { 4966 if (mddev->in_sync) {
4962 mddev->in_sync = 0; 4967 mddev->in_sync = 0;
4963 mddev->sb_dirty = 3; 4968 set_bit(MD_CHANGE_CLEAN, &mddev->flags);
4964 md_wakeup_thread(mddev->thread); 4969 md_wakeup_thread(mddev->thread);
4965 } 4970 }
4966 spin_unlock_irq(&mddev->write_lock); 4971 spin_unlock_irq(&mddev->write_lock);
4967 } 4972 }
4968 wait_event(mddev->sb_wait, mddev->sb_dirty==0); 4973 wait_event(mddev->sb_wait, mddev->flags==0);
4969} 4974}
4970 4975
4971void md_write_end(mddev_t *mddev) 4976void md_write_end(mddev_t *mddev)
@@ -5235,7 +5240,6 @@ void md_do_sync(mddev_t *mddev)
5235 !test_bit(In_sync, &rdev->flags) && 5240 !test_bit(In_sync, &rdev->flags) &&
5236 rdev->recovery_offset < mddev->curr_resync) 5241 rdev->recovery_offset < mddev->curr_resync)
5237 rdev->recovery_offset = mddev->curr_resync; 5242 rdev->recovery_offset = mddev->curr_resync;
5238 mddev->sb_dirty = 1;
5239 } 5243 }
5240 } 5244 }
5241 5245
@@ -5292,7 +5296,7 @@ void md_check_recovery(mddev_t *mddev)
5292 } 5296 }
5293 5297
5294 if ( ! ( 5298 if ( ! (
5295 mddev->sb_dirty || 5299 mddev->flags ||
5296 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || 5300 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
5297 test_bit(MD_RECOVERY_DONE, &mddev->recovery) || 5301 test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
5298 (mddev->safemode == 1) || 5302 (mddev->safemode == 1) ||
@@ -5308,14 +5312,14 @@ void md_check_recovery(mddev_t *mddev)
5308 if (mddev->safemode && !atomic_read(&mddev->writes_pending) && 5312 if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
5309 !mddev->in_sync && mddev->recovery_cp == MaxSector) { 5313 !mddev->in_sync && mddev->recovery_cp == MaxSector) {
5310 mddev->in_sync = 1; 5314 mddev->in_sync = 1;
5311 mddev->sb_dirty = 3; 5315 set_bit(MD_CHANGE_CLEAN, &mddev->flags);
5312 } 5316 }
5313 if (mddev->safemode == 1) 5317 if (mddev->safemode == 1)
5314 mddev->safemode = 0; 5318 mddev->safemode = 0;
5315 spin_unlock_irq(&mddev->write_lock); 5319 spin_unlock_irq(&mddev->write_lock);
5316 5320
5317 if (mddev->sb_dirty) 5321 if (mddev->flags)
5318 md_update_sb(mddev); 5322 md_update_sb(mddev, 0);
5319 5323
5320 5324
5321 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && 5325 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
@@ -5334,7 +5338,7 @@ void md_check_recovery(mddev_t *mddev)
5334 /* activate any spares */ 5338 /* activate any spares */
5335 mddev->pers->spare_active(mddev); 5339 mddev->pers->spare_active(mddev);
5336 } 5340 }
5337 md_update_sb(mddev); 5341 md_update_sb(mddev, 1);
5338 5342
5339 /* if array is no-longer degraded, then any saved_raid_disk 5343 /* if array is no-longer degraded, then any saved_raid_disk
5340 * information must be scrapped 5344 * information must be scrapped
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1cc9de44ce86..e4f168d063db 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -253,7 +253,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
253 char b[BDEVNAME_SIZE]; 253 char b[BDEVNAME_SIZE];
254 clear_bit(In_sync, &rdev->flags); 254 clear_bit(In_sync, &rdev->flags);
255 set_bit(Faulty, &rdev->flags); 255 set_bit(Faulty, &rdev->flags);
256 mddev->sb_dirty = 1; 256 set_bit(MD_CHANGE_DEVS, &mddev->flags);
257 conf->working_disks--; 257 conf->working_disks--;
258 printk(KERN_ALERT "multipath: IO failure on %s," 258 printk(KERN_ALERT "multipath: IO failure on %s,"
259 " disabling IO path. \n Operation continuing" 259 " disabling IO path. \n Operation continuing"
@@ -470,7 +470,6 @@ static int multipath_run (mddev_t *mddev)
470 } 470 }
471 471
472 conf->raid_disks = mddev->raid_disks; 472 conf->raid_disks = mddev->raid_disks;
473 mddev->sb_dirty = 1;
474 conf->mddev = mddev; 473 conf->mddev = mddev;
475 spin_lock_init(&conf->device_lock); 474 spin_lock_init(&conf->device_lock);
476 INIT_LIST_HEAD(&conf->retry_list); 475 INIT_LIST_HEAD(&conf->retry_list);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3b4d69c05623..2817c477302d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -969,7 +969,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
969 } 969 }
970 clear_bit(In_sync, &rdev->flags); 970 clear_bit(In_sync, &rdev->flags);
971 set_bit(Faulty, &rdev->flags); 971 set_bit(Faulty, &rdev->flags);
972 mddev->sb_dirty = 1; 972 set_bit(MD_CHANGE_DEVS, &mddev->flags);
973 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" 973 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
974 " Operation continuing on %d devices\n", 974 " Operation continuing on %d devices\n",
975 bdevname(rdev->bdev,b), conf->working_disks); 975 bdevname(rdev->bdev,b), conf->working_disks);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7bf5ce281c4d..85e3df2d268a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -960,7 +960,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
960 } 960 }
961 clear_bit(In_sync, &rdev->flags); 961 clear_bit(In_sync, &rdev->flags);
962 set_bit(Faulty, &rdev->flags); 962 set_bit(Faulty, &rdev->flags);
963 mddev->sb_dirty = 1; 963 set_bit(MD_CHANGE_DEVS, &mddev->flags);
964 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" 964 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
965 " Operation continuing on %d devices\n", 965 " Operation continuing on %d devices\n",
966 bdevname(rdev->bdev,b), conf->working_disks); 966 bdevname(rdev->bdev,b), conf->working_disks);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 450066007160..d5a06b258427 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -696,7 +696,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
696 PRINTK("raid5: error called\n"); 696 PRINTK("raid5: error called\n");
697 697
698 if (!test_bit(Faulty, &rdev->flags)) { 698 if (!test_bit(Faulty, &rdev->flags)) {
699 mddev->sb_dirty = 1; 699 set_bit(MD_CHANGE_DEVS, &mddev->flags);
700 if (test_bit(In_sync, &rdev->flags)) { 700 if (test_bit(In_sync, &rdev->flags)) {
701 conf->working_disks--; 701 conf->working_disks--;
702 mddev->degraded++; 702 mddev->degraded++;
@@ -2781,9 +2781,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
2781 wait_event(conf->wait_for_overlap, 2781 wait_event(conf->wait_for_overlap,
2782 atomic_read(&conf->reshape_stripes)==0); 2782 atomic_read(&conf->reshape_stripes)==0);
2783 mddev->reshape_position = conf->expand_progress; 2783 mddev->reshape_position = conf->expand_progress;
2784 mddev->sb_dirty = 1; 2784 set_bit(MD_CHANGE_DEVS, &mddev->flags);
2785 md_wakeup_thread(mddev->thread); 2785 md_wakeup_thread(mddev->thread);
2786 wait_event(mddev->sb_wait, mddev->sb_dirty == 0 || 2786 wait_event(mddev->sb_wait, mddev->flags == 0 ||
2787 kthread_should_stop()); 2787 kthread_should_stop());
2788 spin_lock_irq(&conf->device_lock); 2788 spin_lock_irq(&conf->device_lock);
2789 conf->expand_lo = mddev->reshape_position; 2789 conf->expand_lo = mddev->reshape_position;
@@ -3605,7 +3605,7 @@ static int raid5_start_reshape(mddev_t *mddev)
3605 mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices; 3605 mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
3606 mddev->raid_disks = conf->raid_disks; 3606 mddev->raid_disks = conf->raid_disks;
3607 mddev->reshape_position = 0; 3607 mddev->reshape_position = 0;
3608 mddev->sb_dirty = 1; 3608 set_bit(MD_CHANGE_DEVS, &mddev->flags);
3609 3609
3610 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); 3610 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3611 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); 3611 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index c588709acbbc..866a1e2b0ce0 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -95,7 +95,6 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
95extern void md_do_sync(mddev_t *mddev); 95extern void md_do_sync(mddev_t *mddev);
96extern void md_new_event(mddev_t *mddev); 96extern void md_new_event(mddev_t *mddev);
97 97
98extern void md_update_sb(mddev_t * mddev);
99 98
100#endif /* CONFIG_MD */ 99#endif /* CONFIG_MD */
101#endif 100#endif
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 920b94fe31fa..e423dad1a7fd 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -116,7 +116,11 @@ struct mddev_s
116 dev_t unit; 116 dev_t unit;
117 int md_minor; 117 int md_minor;
118 struct list_head disks; 118 struct list_head disks;
119 int sb_dirty; 119 unsigned long flags;
120#define MD_CHANGE_DEVS 0 /* Some device status has changed */
121#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
122#define MD_CHANGE_PENDING 2 /* superblock update in progress */
123
120 int ro; 124 int ro;
121 125
122 struct gendisk *gendisk; 126 struct gendisk *gendisk;