>On Tue, 6 Nov 2012 17:13:00 +0800 majianpeng <majianpeng@xxxxxxxxx> wrote: > >> If read_seqretry returned true and bbp was changed, it will write >> invalid address which can cause some serious problem. >> >> This bug was introduced by commit v3.0-rc7-130-g2699b67. >> So fix is suitable for 3.0.y thru 3.6.y. >> >> Reported-by: zhuwenfeng@xxxxxxxxxxx >> Tested-by: zhuwenfeng@xxxxxxxxxxx >> Cc: stable@xxxxxxxxxxxxxxx >> Signed-off-by: Jianpeng Ma <majianpeng@xxxxxxxxx> >> --- >> drivers/md/md.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/md/md.c b/drivers/md/md.c >> index 9ab768a..d63aa78 100644 >> --- a/drivers/md/md.c >> +++ b/drivers/md/md.c >> @@ -1805,15 +1805,15 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) >> md_error(mddev, rdev); >> else { >> struct badblocks *bb = &rdev->badblocks; >> - u64 *bbp = (u64 *)page_address(rdev->bb_page); >> u64 *p = bb->page; >> sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS); >> if (bb->changed) { >> unsigned seq; >> + u64 *bbp; >> >> retry: >> + bbp = (u64 *)page_address(rdev->bb_page); >> seq = read_seqbegin(&bb->lock); >> - >> memset(bbp, 0xff, PAGE_SIZE); >> >> for (i = 0 ; i < bb->count ; i++) { > > >No. >The contents of the page might change, but it is always the same page, so it >always has the same address, so "bbp" is guaranteed to be stable. > >NeilBrown > Is my understand wrong? >u64 *bbp = (u64 *)page_address(rdev->bb_page); > u64 *p = bb->page; > sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS); > if (bb->changed) { > unsigned seq; >retry: > seq = read_seqbegin(&bb->lock); > memset(bbp, 0xff, PAGE_SIZE); > for (i = 0 ; i < bb->count ; i++) { > u64 internal_bb = *p++; > u64 store_bb = ((BB_OFFSET(internal_bb) << 10) > | BB_LEN(internal_bb)); > *bbp++ = cpu_to_le64(store_bb); I think bbp will be changed. Is ok? > } > bb->changed = 0; > if (read_seqretry(&bb->lock, seq)) > goto retry; ?韬{.n?????%??檩??w?{.n???{炳盯w???塄}?财??j:+v??????2??璀??摺?囤??z夸z罐?+?????w棹f