Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md/raid10: Don't call bitmap_cond_end_sync when we are doing recovery.

For raid1/4/5/6, resync (fixing inconsistencies between devices) is
very similar to recovery (rebuilding a failed device onto a spare).
The both walk through the device addresses in order.

For raid10 it can be quite different. resync follows the 'array'
address, and makes sure all copies are the same. Recover walks
through 'device' addresses and recreates each missing block.

The 'bitmap_cond_end_sync' function allows the write-intent-bitmap
(When present) to be updated to reflect a partially completed resync.
It makes assumptions which mean that it does not work correctly for
raid10 recovery at all.

In particularly, it can cause bitmap-directed recovery of a raid10 to
not recovery some of the blocks that need to be recovered.

So move the call to bitmap_cond_end_sync into the resync path, rather
than being in the common "resync or recovery" path.


Cc: stable@kernel.org
Signed-off-by: NeilBrown <neilb@suse.de>

NeilBrown 78200d45 09b4068a

+2 -2
+2 -2
drivers/md/raid10.c
··· 1749 1749 if (!go_faster && conf->nr_waiting) 1750 1750 msleep_interruptible(1000); 1751 1751 1752 - bitmap_cond_end_sync(mddev->bitmap, sector_nr); 1753 - 1754 1752 /* Again, very different code for resync and recovery. 1755 1753 * Both must result in an r10bio with a list of bios that 1756 1754 * have bi_end_io, bi_sector, bi_bdev set, ··· 1883 1885 } else { 1884 1886 /* resync. Schedule a read for every block at this virt offset */ 1885 1887 int count = 0; 1888 + 1889 + bitmap_cond_end_sync(mddev->bitmap, sector_nr); 1886 1890 1887 1891 if (!bitmap_start_sync(mddev->bitmap, sector_nr, 1888 1892 &sync_blocks, mddev->degraded) &&