Skip to content

Commit 50c4feb

Browse files
mauelshasnitm
authored andcommitted
dm raid: be prepared to accept arbitrary '- -' tuples
During raid set resize checks and setting up the recovery offset in case a raid set grows, calculated rd->md.dev_sectors is compared to rs->dev[0].rdev.sectors. Device 0 may not be defined in case userspace passes in '- -' for it (lvm2 doesn't do that so far), thus it's device sectors can't be taken authoritatively in this comparison and another valid device must be used to retrieve the device size. Use mddev->dev_sectors in checking for ongoing recovery for the same reason. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent c63ede3 commit 50c4feb

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

drivers/md/dm-raid.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ static bool rs_is_reshapable(struct raid_set *rs)
370370
/* Return true, if raid set in @rs is recovering */
371371
static bool rs_is_recovering(struct raid_set *rs)
372372
{
373-
return rs->md.recovery_cp < rs->dev[0].rdev.sectors;
373+
return rs->md.recovery_cp < rs->md.dev_sectors;
374374
}
375375

376376
/* Return true, if raid set in @rs is reshaping */
@@ -1425,6 +1425,24 @@ static unsigned int rs_data_stripes(struct raid_set *rs)
14251425
return rs->raid_disks - rs->raid_type->parity_devs;
14261426
}
14271427

1428+
/*
1429+
* Retrieve rdev->sectors from any valid raid device of @rs
1430+
* to allow userpace to pass in arbitray "- -" device tupples.
1431+
*/
1432+
static sector_t __rdev_sectors(struct raid_set *rs)
1433+
{
1434+
int i;
1435+
1436+
for (i = 0; i < rs->md.raid_disks; i++) {
1437+
struct md_rdev *rdev = &rs->dev[i].rdev;
1438+
1439+
if (rdev->bdev && rdev->sectors)
1440+
return rdev->sectors;
1441+
}
1442+
1443+
BUG(); /* Constructor ensures we got some. */
1444+
}
1445+
14281446
/* Calculate the sectors per device and per array used for @rs */
14291447
static int rs_set_dev_and_array_sectors(struct raid_set *rs, bool use_mddev)
14301448
{
@@ -1510,9 +1528,9 @@ static void rs_setup_recovery(struct raid_set *rs, sector_t dev_sectors)
15101528
else if (dev_sectors == MaxSector)
15111529
/* Prevent recovery */
15121530
__rs_setup_recovery(rs, MaxSector);
1513-
else if (rs->dev[0].rdev.sectors < dev_sectors)
1531+
else if (__rdev_sectors(rs) < dev_sectors)
15141532
/* Grown raid set */
1515-
__rs_setup_recovery(rs, rs->dev[0].rdev.sectors);
1533+
__rs_setup_recovery(rs, __rdev_sectors(rs));
15161534
else
15171535
__rs_setup_recovery(rs, MaxSector);
15181536
}
@@ -2828,7 +2846,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
28282846
if (r)
28292847
goto bad;
28302848

2831-
calculated_dev_sectors = rs->dev[0].rdev.sectors;
2849+
calculated_dev_sectors = rs->md.dev_sectors;
28322850

28332851
/*
28342852
* Backup any new raid set level, layout, ...
@@ -2841,7 +2859,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
28412859
if (r)
28422860
goto bad;
28432861

2844-
resize = calculated_dev_sectors != rs->dev[0].rdev.sectors;
2862+
resize = calculated_dev_sectors != __rdev_sectors(rs);
28452863

28462864
INIT_WORK(&rs->md.event_work, do_table_event);
28472865
ti->private = rs;

0 commit comments

Comments
 (0)