Skip to content

Commit d176fad

Browse files
mauelshaMikulas Patocka
authored andcommitted
dm raid: fix stripes adding reshape size issues
Adding stripes to an existing raid4/5/6/10 mapped device grows its capacity though it'll be only made available _after_ the respective reshape finished as of MD kernel reshape semantics. Such reshaping involves moving a window forward starting at BOD reading content from previous lesser stripes and writing them back in the new layout with more stripes. Once that process finishes at end of previous data, the grown size may be announced and used. In order to avoid writing over any existing data in place, out-of-place space is added to the beginning of each data device by lvm2 before starting the reshape process. That reshape space wasn't taken into acount for data device size calculation. Fixes resulting from above: - correct event handling conditions in do_table_event() to set the device's capacity after the stripe adding reshape ended - subtract mentioned out-of-place space doing data device and array size calculations - conditionally set capacity as of superblock in preresume Testing: - passes all LVM2 RAID tests including new lvconvert-raid-reshape-size.sh one Tested-by: Heinz Mauelshagen <[email protected]> Signed-off-by: Heinz Mauelshagen <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]>
1 parent 453496b commit d176fad

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

drivers/md/dm-raid.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,7 @@ static int rs_set_dev_and_array_sectors(struct raid_set *rs, sector_t sectors, b
16731673
if (sector_div(dev_sectors, data_stripes))
16741674
goto bad;
16751675

1676-
array_sectors = (data_stripes + delta_disks) * dev_sectors;
1676+
array_sectors = (data_stripes + delta_disks) * (dev_sectors - _get_reshape_sectors(rs));
16771677
if (sector_div(array_sectors, rs->raid10_copies))
16781678
goto bad;
16791679

@@ -1682,7 +1682,7 @@ static int rs_set_dev_and_array_sectors(struct raid_set *rs, sector_t sectors, b
16821682

16831683
else
16841684
/* Striped layouts */
1685-
array_sectors = (data_stripes + delta_disks) * dev_sectors;
1685+
array_sectors = (data_stripes + delta_disks) * (dev_sectors - _get_reshape_sectors(rs));
16861686

16871687
mddev->array_sectors = array_sectors;
16881688
mddev->dev_sectors = dev_sectors;
@@ -1721,11 +1721,20 @@ static void do_table_event(struct work_struct *ws)
17211721
struct raid_set *rs = container_of(ws, struct raid_set, md.event_work);
17221722

17231723
smp_rmb(); /* Make sure we access most actual mddev properties */
1724-
if (!rs_is_reshaping(rs)) {
1724+
1725+
/* Only grow size resulting from added stripe(s) after reshape ended. */
1726+
if (!rs_is_reshaping(rs) &&
1727+
rs->array_sectors > rs->md.array_sectors &&
1728+
!rs->md.delta_disks &&
1729+
rs->md.raid_disks == rs->raid_disks) {
1730+
/* The raid10 personality doesn't provide proper device sizes -> correct. */
17251731
if (rs_is_raid10(rs))
17261732
rs_set_rdev_sectors(rs);
1733+
1734+
rs->md.array_sectors = rs->array_sectors;
17271735
rs_set_capacity(rs);
17281736
}
1737+
17291738
dm_table_event(rs->ti->table);
17301739
}
17311740

@@ -4023,6 +4032,11 @@ static int raid_preresume(struct dm_target *ti)
40234032
if (test_and_set_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags))
40244033
return 0;
40254034

4035+
/* If different and no explicit grow request, expose MD array size as of superblock. */
4036+
if (!test_bit(RT_FLAG_RS_GROW, &rs->runtime_flags) &&
4037+
rs->array_sectors != mddev->array_sectors)
4038+
rs_set_capacity(rs);
4039+
40264040
/*
40274041
* The superblocks need to be updated on disk if the
40284042
* array is new or new devices got added (thus zeroed

0 commit comments

Comments
 (0)