aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-10-03 04:15:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 11:04:17 -0400
commit850b2b420cd5b363ed4cf48a8816d656c8b5251b (patch)
treeb63aa37b3fb7dfb7a0b674d5a2ebe9da13cc7405
parent6814d5368d68341ec6b5e4ecd10ea5947130775a (diff)
[PATCH] md: replace magic numbers in sb_dirty with well defined bit flags
Instead of magic numbers (0,1,2,3) in sb_dirty, we have some flags instead: MD_CHANGE_DEVS Some device state has changed requiring superblock update on all devices. MD_CHANGE_CLEAN The array has transitions from 'clean' to 'dirty' or back, requiring a superblock update on active devices, but possibly not on spares MD_CHANGE_PENDING A superblock update is underway. We wait for an update to complete by waiting for all flags to be clear. A flag can be set at any time, even during an update, without risk that the change will be lost. Stop exporting md_update_sb - isn't needed. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-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;