Skip to content

Commit

Permalink
Update recovery_offset even when external metadata is used.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reported-by: "Kwolek, Adam" <[email protected]>
  • Loading branch information
neilbrown committed Aug 18, 2010
1 parent da5cabf commit 3a3a5dd
Showing 1 changed file with 18 additions and 26 deletions.
44 changes: 18 additions & 26 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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;
Expand Down Expand Up @@ -2221,19 +2226,6 @@ static void md_update_sb(mddev_t * mddev, int force_change)
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);

Expand Down

0 comments on commit 3a3a5dd

Please sign in to comment.