diff options
| author | NeilBrown <neilb@suse.de> | 2006-10-03 04:15:46 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 11:04:17 -0400 |
| commit | 850b2b420cd5b363ed4cf48a8816d656c8b5251b (patch) | |
| tree | b63aa37b3fb7dfb7a0b674d5a2ebe9da13cc7405 | |
| parent | 6814d5368d68341ec6b5e4ecd10ea5947130775a (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.c | 76 | ||||
| -rw-r--r-- | drivers/md/multipath.c | 3 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 2 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 2 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 8 | ||||
| -rw-r--r-- | include/linux/raid/md.h | 1 | ||||
| -rw-r--r-- | include/linux/raid/md_k.h | 6 |
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 | ||
| 1590 | void md_update_sb(mddev_t * mddev) | 1590 | static 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) | |||
| 1598 | repeat: | 1598 | repeat: |
| 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 | } |
| 1713 | EXPORT_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; | ||
