Skip to content

Commit

Permalink
md: fix clearing of the 'changed' flags for the bad blocks list.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
NeilBrown committed Mar 19, 2012
1 parent 61a0d80 commit d096293
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit d096293

Please sign in to comment.