| From d0962936bff659d20522555b517582a2715fd23f Mon Sep 17 00:00:00 2001 |
| From: NeilBrown <neilb@suse.de> |
| Date: Mon, 19 Mar 2012 12:46:41 +1100 |
| Subject: md: fix clearing of the 'changed' flags for the bad blocks list. |
| |
| From: NeilBrown <neilb@suse.de> |
| |
| commit d0962936bff659d20522555b517582a2715fd23f upstream. |
| |
| 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. |
| |
| Signed-off-by: NeilBrown <neilb@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/md.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/md/md.c |
| +++ b/drivers/md/md.c |
| @@ -1801,13 +1801,13 @@ retry: |
| | 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; |
| } |
| } |
| |
| @@ -2362,6 +2362,7 @@ repeat: |
| clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
| list_for_each_entry(rdev, &mddev->disks, same_set) { |
| if (rdev->badblocks.changed) { |
| + rdev->badblocks.changed = 0; |
| md_ack_all_badblocks(&rdev->badblocks); |
| md_error(mddev, rdev); |
| } |