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 /drivers/md/md.c | |
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>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 76 |
1 files changed, 40 insertions, 36 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; | 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 | ||
4971 | void md_write_end(mddev_t *mddev) | 4976 | void 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 |