Update recovery_offset even when external metadata is used.
The update of ->recovery_offset in sync_sbs is appropriate even then external metadata is in use. However sync_sbs is only called when native metadata is used. So move that update in to the top of md_update_sb (which is the only caller of sync_sbs) before the test on ->external. This moves the update out of ->write_lock protection, but those fields only need ->reconfig_mutex protection which they still have. Also move the test on ->persistent up to where ->external is set as for metadata update purposes they are the same. Clear MD_CHANGE_DEVS and MD_CHANGE_CLEAN as they can only be confusing if ->external is set or ->persistent isn't. Finally move the update of ->utime down as it is only relevent (like the ->events update) for native metadata. Signed-off-by: NeilBrown <neilb@suse.de> Reported-by: "Kwolek, Adam" <adam.kwolek@intel.com>
This commit is contained in:
Родитель
da5cabf80e
Коммит
3a3a5ddb7a
|
@ -2136,16 +2136,6 @@ static void sync_sbs(mddev_t * mddev, int nospares)
|
|||
* with the rest of the array)
|
||||
*/
|
||||
mdk_rdev_t *rdev;
|
||||
|
||||
/* First make sure individual recovery_offsets are correct */
|
||||
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
||||
if (rdev->raid_disk >= 0 &&
|
||||
mddev->delta_disks >= 0 &&
|
||||
!test_bit(In_sync, &rdev->flags) &&
|
||||
mddev->curr_resync_completed > rdev->recovery_offset)
|
||||
rdev->recovery_offset = mddev->curr_resync_completed;
|
||||
|
||||
}
|
||||
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
||||
if (rdev->sb_events == mddev->events ||
|
||||
(nospares &&
|
||||
|
@ -2167,12 +2157,27 @@ static void md_update_sb(mddev_t * mddev, int force_change)
|
|||
int sync_req;
|
||||
int nospares = 0;
|
||||
|
||||
mddev->utime = get_seconds();
|
||||
if (mddev->external)
|
||||
return;
|
||||
repeat:
|
||||
/* First make sure individual recovery_offsets are correct */
|
||||
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
||||
if (rdev->raid_disk >= 0 &&
|
||||
mddev->delta_disks >= 0 &&
|
||||
!test_bit(In_sync, &rdev->flags) &&
|
||||
mddev->curr_resync_completed > rdev->recovery_offset)
|
||||
rdev->recovery_offset = mddev->curr_resync_completed;
|
||||
|
||||
}
|
||||
if (mddev->external || !mddev->persistent) {
|
||||
clear_bit(MD_CHANGE_DEVS, &mddev->flags);
|
||||
clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
wake_up(&mddev->sb_wait);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irq(&mddev->write_lock);
|
||||
|
||||
mddev->utime = get_seconds();
|
||||
|
||||
set_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
|
||||
force_change = 1;
|
||||
|
@ -2221,19 +2226,6 @@ repeat:
|
|||
MD_BUG();
|
||||
mddev->events --;
|
||||
}
|
||||
|
||||
/*
|
||||
* do not write anything to disk if using
|
||||
* nonpersistent superblocks
|
||||
*/
|
||||
if (!mddev->persistent) {
|
||||
if (!mddev->external)
|
||||
clear_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
|
||||
spin_unlock_irq(&mddev->write_lock);
|
||||
wake_up(&mddev->sb_wait);
|
||||
return;
|
||||
}
|
||||
sync_sbs(mddev, nospares);
|
||||
spin_unlock_irq(&mddev->write_lock);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче