md: fix clearing of the 'changed' flags for the bad blocks list.
In super_1_sync (the first hunk) we need to clear 'changed' before checking read_seqretry(), otherwise we might race with other code adding a bad block and so won't retry later. In md_update_sb (the second hunk), in the case where there is no metadata (neither persistent nor external), we treat any bad blocks as an error. However we need to clear the 'changed' flag before calling md_ack_all_badblocks, else it won't do anything. This patch is suitable for -stable release 3.0 and later. Cc: stable@vger.kernel.org Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
61a0d80ce4
commit
d0962936bf
|
@ -1805,13 +1805,13 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
|
|||
| BB_LEN(internal_bb));
|
||||
*bbp++ = cpu_to_le64(store_bb);
|
||||
}
|
||||
bb->changed = 0;
|
||||
if (read_seqretry(&bb->lock, seq))
|
||||
goto retry;
|
||||
|
||||
bb->sector = (rdev->sb_start +
|
||||
(int)le32_to_cpu(sb->bblog_offset));
|
||||
bb->size = le16_to_cpu(sb->bblog_size);
|
||||
bb->changed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2366,6 +2366,7 @@ static void md_update_sb(struct mddev * mddev, int force_change)
|
|||
clear_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
rdev_for_each(rdev, mddev) {
|
||||
if (rdev->badblocks.changed) {
|
||||
rdev->badblocks.changed = 0;
|
||||
md_ack_all_badblocks(&rdev->badblocks);
|
||||
md_error(mddev, rdev);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue