Skip to content

Commit

Permalink
dm raid: display a consistent copy of the MD status via raid_status()
Browse files Browse the repository at this point in the history
The MD sync thread updates recovery flags providing state of any
running, idle, frozen, recovering, reshaping, ... activity it performs
and updates respective flags asynchronously versus dm processing
raid_status().  To close that race window, take a single copy of the
flags and pass it into its callees.

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 d39f001 commit 6714351
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions drivers/md/dm-raid.c
Original file line number Diff line number Diff line change
Expand Up @@ -3300,25 +3300,25 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
}

/* Return string describing the current sync action of @mddev */
static const char *decipher_sync_action(struct mddev *mddev)
static const char *decipher_sync_action(struct mddev *mddev, unsigned long recovery)
{
if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
if (test_bit(MD_RECOVERY_FROZEN, &recovery))
return "frozen";

if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
(!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
if (test_bit(MD_RECOVERY_RUNNING, &recovery) ||
(!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &recovery))) {
if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
return "reshape";

if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
if (test_bit(MD_RECOVERY_SYNC, &recovery)) {
if (!test_bit(MD_RECOVERY_REQUESTED, &recovery))
return "resync";
else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
else if (test_bit(MD_RECOVERY_CHECK, &recovery))
return "check";
return "repair";
}

if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery))
if (test_bit(MD_RECOVERY_RECOVER, &recovery))
return "recover";
}

Expand Down Expand Up @@ -3350,7 +3350,7 @@ static const char *__raid_dev_status(struct raid_set *rs, struct md_rdev *rdev,
}

/* Helper to return resync/reshape progress for @rs and @array_in_sync */
static sector_t rs_get_progress(struct raid_set *rs,
static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
sector_t resync_max_sectors, bool *array_in_sync)
{
sector_t r, curr_resync_completed;
Expand All @@ -3367,7 +3367,7 @@ static sector_t rs_get_progress(struct raid_set *rs,
r = mddev->reshape_position;

/* Reshape is relative to the array size */
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) ||
if (test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
r != MaxSector) {
if (r == MaxSector) {
*array_in_sync = true;
Expand All @@ -3382,20 +3382,20 @@ static sector_t rs_get_progress(struct raid_set *rs,
}

/* Sync is relative to the component device size */
} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
} else if (test_bit(MD_RECOVERY_RUNNING, &recovery))
r = curr_resync_completed;
else
r = mddev->recovery_cp;

if ((r == MaxSector) ||
(test_bit(MD_RECOVERY_DONE, &mddev->recovery) &&
(test_bit(MD_RECOVERY_DONE, &recovery) &&
(mddev->curr_resync_completed == resync_max_sectors))) {
/*
* Sync complete.
*/
*array_in_sync = true;
r = resync_max_sectors;
} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
} else if (test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
/*
* If "check" or "repair" is occurring, the raid set has
* undergone an initial sync and the health characters
Expand Down Expand Up @@ -3438,6 +3438,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
struct r5conf *conf = mddev->private;
int i, max_nr_stripes = conf ? conf->max_nr_stripes : 0;
bool array_in_sync;
unsigned long recovery;
unsigned int raid_param_cnt = 1; /* at least 1 for chunksize */
unsigned int sz = 0;
unsigned int rebuild_disks;
Expand All @@ -3457,13 +3458,14 @@ static void raid_status(struct dm_target *ti, status_type_t type,

/* Access most recent mddev properties for status output */
smp_rmb();
recovery = rs->md.recovery;
/* Get sensible max sectors even if raid set not yet started */
resync_max_sectors = test_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags) ?
mddev->resync_max_sectors : mddev->dev_sectors;
progress = rs_get_progress(rs, resync_max_sectors, &array_in_sync);
progress = rs_get_progress(rs, recovery, resync_max_sectors, &array_in_sync);
resync_mismatches = (mddev->last_sync_action && !strcasecmp(mddev->last_sync_action, "check")) ?
atomic64_read(&mddev->resync_mismatches) : 0;
sync_action = decipher_sync_action(&rs->md);
sync_action = decipher_sync_action(&rs->md, recovery);

/* HM FIXME: do we want another state char for raid0? It shows 'D'/'A'/'-' now */
for (i = 0; i < rs->raid_disks; i++)
Expand Down

0 comments on commit 6714351

Please sign in to comment.