Skip to content

Commit

Permalink
dm raid: fix raid set size revalidation
Browse files Browse the repository at this point in the history
The raid set size is being revalidated unconditionally before a
reshaping conversion is started.  MD requires the size to only be
reduced in case of a stripe removing (i.e. shrinking) reshape but not
when growing because the raid array has to stay small until after the
growing reshape finishes.

Fix by avoiding the size revalidation in preresume unless a shrinking
reshape is requested.

Signed-off-by: Heinz Mauelshagen <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
  • Loading branch information
mauelsha authored and snitm committed Dec 8, 2017
1 parent 7501537 commit 61e06e2
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions drivers/md/dm-raid.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,15 +675,11 @@ static struct raid_type *get_raid_type_by_ll(const int level, const int layout)
return NULL;
}

/*
* Conditionally change bdev capacity of @rs
* in case of a disk add/remove reshape
*/
static void rs_set_capacity(struct raid_set *rs)
/* Adjust rdev sectors */
static void rs_set_rdev_sectors(struct raid_set *rs)
{
struct mddev *mddev = &rs->md;
struct md_rdev *rdev;
struct gendisk *gendisk = dm_disk(dm_table_get_md(rs->ti->table));

/*
* raid10 sets rdev->sector to the device size, which
Expand All @@ -692,8 +688,16 @@ static void rs_set_capacity(struct raid_set *rs)
rdev_for_each(rdev, mddev)
if (!test_bit(Journal, &rdev->flags))
rdev->sectors = mddev->dev_sectors;
}

set_capacity(gendisk, mddev->array_sectors);
/*
* Change bdev capacity of @rs in case of a disk add/remove reshape
*/
static void rs_set_capacity(struct raid_set *rs)
{
struct gendisk *gendisk = dm_disk(dm_table_get_md(rs->ti->table));

set_capacity(gendisk, rs->md.array_sectors);
revalidate_disk(gendisk);
}

Expand Down Expand Up @@ -1674,8 +1678,11 @@ static void do_table_event(struct work_struct *ws)
struct raid_set *rs = container_of(ws, struct raid_set, md.event_work);

smp_rmb(); /* Make sure we access most actual mddev properties */
if (!rs_is_reshaping(rs))
if (!rs_is_reshaping(rs)) {
if (rs_is_raid10(rs))
rs_set_rdev_sectors(rs);
rs_set_capacity(rs);
}
dm_table_event(rs->ti->table);
}

Expand Down Expand Up @@ -3873,11 +3880,10 @@ static int raid_preresume(struct dm_target *ti)
mddev->resync_min = mddev->recovery_cp;
}

rs_set_capacity(rs);

/* Check for any reshape request unless new raid set */
if (test_and_clear_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
/* Initiate a reshape. */
rs_set_rdev_sectors(rs);
mddev_lock_nointr(mddev);
r = rs_start_reshape(rs);
mddev_unlock(mddev);
Expand Down Expand Up @@ -3906,6 +3912,10 @@ static void raid_resume(struct dm_target *ti)
mddev->ro = 0;
mddev->in_sync = 0;

/* Only reduce raid set size before running a disk removing reshape. */
if (mddev->delta_disks < 0)
rs_set_capacity(rs);

/*
* Keep the RAID set frozen if reshape/rebuild flags are set.
* The RAID set is unfrozen once the next table load/resume,
Expand Down

0 comments on commit 61e06e2

Please sign in to comment.