diff options
-rw-r--r-- | Documentation/device-mapper/dm-raid.txt | 1 | ||||
-rw-r--r-- | drivers/md/dm-raid.c | 3 | ||||
-rw-r--r-- | drivers/md/md.c | 29 | ||||
-rw-r--r-- | drivers/md/md.h | 8 |
4 files changed, 32 insertions, 9 deletions
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index 2bb3a6823dc7..ef8ba9fa58c4 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt | |||
@@ -223,3 +223,4 @@ Version History | |||
223 | 1.5.0 Add message interface to allow manipulation of the sync_action. | 223 | 1.5.0 Add message interface to allow manipulation of the sync_action. |
224 | New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt. | 224 | New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt. |
225 | 1.5.1 Add ability to restore transiently failed devices on resume. | 225 | 1.5.1 Add ability to restore transiently failed devices on resume. |
226 | 1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check". | ||
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 21e8e4660c59..4880b69e2e9e 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -1388,6 +1388,7 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1388 | * performing a "check" of the array. | 1388 | * performing a "check" of the array. |
1389 | */ | 1389 | */ |
1390 | DMEMIT(" %llu", | 1390 | DMEMIT(" %llu", |
1391 | (strcmp(rs->md.last_sync_action, "check")) ? 0 : | ||
1391 | (unsigned long long) | 1392 | (unsigned long long) |
1392 | atomic64_read(&rs->md.resync_mismatches)); | 1393 | atomic64_read(&rs->md.resync_mismatches)); |
1393 | break; | 1394 | break; |
@@ -1651,7 +1652,7 @@ static void raid_resume(struct dm_target *ti) | |||
1651 | 1652 | ||
1652 | static struct target_type raid_target = { | 1653 | static struct target_type raid_target = { |
1653 | .name = "raid", | 1654 | .name = "raid", |
1654 | .version = {1, 5, 1}, | 1655 | .version = {1, 5, 2}, |
1655 | .module = THIS_MODULE, | 1656 | .module = THIS_MODULE, |
1656 | .ctr = raid_ctr, | 1657 | .ctr = raid_ctr, |
1657 | .dtr = raid_dtr, | 1658 | .dtr = raid_dtr, |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 26f9452ea61c..dddc87bcf64a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -521,6 +521,7 @@ void mddev_init(struct mddev *mddev) | |||
521 | init_waitqueue_head(&mddev->recovery_wait); | 521 | init_waitqueue_head(&mddev->recovery_wait); |
522 | mddev->reshape_position = MaxSector; | 522 | mddev->reshape_position = MaxSector; |
523 | mddev->reshape_backwards = 0; | 523 | mddev->reshape_backwards = 0; |
524 | mddev->last_sync_action = "none"; | ||
524 | mddev->resync_min = 0; | 525 | mddev->resync_min = 0; |
525 | mddev->resync_max = MaxSector; | 526 | mddev->resync_max = MaxSector; |
526 | mddev->level = LEVEL_NONE; | 527 | mddev->level = LEVEL_NONE; |
@@ -4272,6 +4273,17 @@ action_store(struct mddev *mddev, const char *page, size_t len) | |||
4272 | return len; | 4273 | return len; |
4273 | } | 4274 | } |
4274 | 4275 | ||
4276 | static struct md_sysfs_entry md_scan_mode = | ||
4277 | __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); | ||
4278 | |||
4279 | static ssize_t | ||
4280 | last_sync_action_show(struct mddev *mddev, char *page) | ||
4281 | { | ||
4282 | return sprintf(page, "%s\n", mddev->last_sync_action); | ||
4283 | } | ||
4284 | |||
4285 | static struct md_sysfs_entry md_last_scan_mode = __ATTR_RO(last_sync_action); | ||
4286 | |||
4275 | static ssize_t | 4287 | static ssize_t |
4276 | mismatch_cnt_show(struct mddev *mddev, char *page) | 4288 | mismatch_cnt_show(struct mddev *mddev, char *page) |
4277 | { | 4289 | { |
@@ -4280,10 +4292,6 @@ mismatch_cnt_show(struct mddev *mddev, char *page) | |||
4280 | atomic64_read(&mddev->resync_mismatches)); | 4292 | atomic64_read(&mddev->resync_mismatches)); |
4281 | } | 4293 | } |
4282 | 4294 | ||
4283 | static struct md_sysfs_entry md_scan_mode = | ||
4284 | __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); | ||
4285 | |||
4286 | |||
4287 | static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt); | 4295 | static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt); |
4288 | 4296 | ||
4289 | static ssize_t | 4297 | static ssize_t |
@@ -4686,6 +4694,7 @@ static struct attribute *md_default_attrs[] = { | |||
4686 | 4694 | ||
4687 | static struct attribute *md_redundancy_attrs[] = { | 4695 | static struct attribute *md_redundancy_attrs[] = { |
4688 | &md_scan_mode.attr, | 4696 | &md_scan_mode.attr, |
4697 | &md_last_scan_mode.attr, | ||
4689 | &md_mismatches.attr, | 4698 | &md_mismatches.attr, |
4690 | &md_sync_min.attr, | 4699 | &md_sync_min.attr, |
4691 | &md_sync_max.attr, | 4700 | &md_sync_max.attr, |
@@ -7329,7 +7338,7 @@ void md_do_sync(struct md_thread *thread) | |||
7329 | sector_t last_check; | 7338 | sector_t last_check; |
7330 | int skipped = 0; | 7339 | int skipped = 0; |
7331 | struct md_rdev *rdev; | 7340 | struct md_rdev *rdev; |
7332 | char *desc; | 7341 | char *desc, *action = NULL; |
7333 | struct blk_plug plug; | 7342 | struct blk_plug plug; |
7334 | 7343 | ||
7335 | /* just incase thread restarts... */ | 7344 | /* just incase thread restarts... */ |
@@ -7339,17 +7348,21 @@ void md_do_sync(struct md_thread *thread) | |||
7339 | return; | 7348 | return; |
7340 | 7349 | ||
7341 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | 7350 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
7342 | if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) | 7351 | if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) { |
7343 | desc = "data-check"; | 7352 | desc = "data-check"; |
7344 | else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | 7353 | action = "check"; |
7354 | } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | ||
7345 | desc = "requested-resync"; | 7355 | desc = "requested-resync"; |
7346 | else | 7356 | action = "repair"; |
7357 | } else | ||
7347 | desc = "resync"; | 7358 | desc = "resync"; |
7348 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 7359 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
7349 | desc = "reshape"; | 7360 | desc = "reshape"; |
7350 | else | 7361 | else |
7351 | desc = "recovery"; | 7362 | desc = "recovery"; |
7352 | 7363 | ||
7364 | mddev->last_sync_action = action ?: desc; | ||
7365 | |||
7353 | /* we overload curr_resync somewhat here. | 7366 | /* we overload curr_resync somewhat here. |
7354 | * 0 == not engaged in resync at all | 7367 | * 0 == not engaged in resync at all |
7355 | * 2 == checking that there is no conflict with another sync | 7368 | * 2 == checking that there is no conflict with another sync |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 653f992b687a..20f02c0b5f2d 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -268,6 +268,14 @@ struct mddev { | |||
268 | 268 | ||
269 | struct md_thread *thread; /* management thread */ | 269 | struct md_thread *thread; /* management thread */ |
270 | struct md_thread *sync_thread; /* doing resync or reconstruct */ | 270 | struct md_thread *sync_thread; /* doing resync or reconstruct */ |
271 | |||
272 | /* 'last_sync_action' is initialized to "none". It is set when a | ||
273 | * sync operation (i.e "data-check", "requested-resync", "resync", | ||
274 | * "recovery", or "reshape") is started. It holds this value even | ||
275 | * when the sync thread is "frozen" (interrupted) or "idle" (stopped | ||
276 | * or finished). It is overwritten when a new sync operation is begun. | ||
277 | */ | ||
278 | char *last_sync_action; | ||
271 | sector_t curr_resync; /* last block scheduled */ | 279 | sector_t curr_resync; /* last block scheduled */ |
272 | /* As resync requests can complete out of order, we cannot easily track | 280 | /* As resync requests can complete out of order, we cannot easily track |
273 | * how much resync has been completed. So we occasionally pause until | 281 | * how much resync has been completed. So we occasionally pause until |