diff options
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r-- | drivers/md/dm-raid.c | 111 |
1 files changed, 109 insertions, 2 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 311e3d35b272..1d3fe1a40a9b 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -1279,6 +1279,31 @@ static int raid_map(struct dm_target *ti, struct bio *bio) | |||
1279 | return DM_MAPIO_SUBMITTED; | 1279 | return DM_MAPIO_SUBMITTED; |
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | static const char *decipher_sync_action(struct mddev *mddev) | ||
1283 | { | ||
1284 | if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) | ||
1285 | return "frozen"; | ||
1286 | |||
1287 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | ||
1288 | (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) { | ||
1289 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | ||
1290 | return "reshape"; | ||
1291 | |||
1292 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | ||
1293 | if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | ||
1294 | return "resync"; | ||
1295 | else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) | ||
1296 | return "check"; | ||
1297 | return "repair"; | ||
1298 | } | ||
1299 | |||
1300 | if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) | ||
1301 | return "recover"; | ||
1302 | } | ||
1303 | |||
1304 | return "idle"; | ||
1305 | } | ||
1306 | |||
1282 | static void raid_status(struct dm_target *ti, status_type_t type, | 1307 | static void raid_status(struct dm_target *ti, status_type_t type, |
1283 | unsigned status_flags, char *result, unsigned maxlen) | 1308 | unsigned status_flags, char *result, unsigned maxlen) |
1284 | { | 1309 | { |
@@ -1298,8 +1323,18 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1298 | sync = rs->md.recovery_cp; | 1323 | sync = rs->md.recovery_cp; |
1299 | 1324 | ||
1300 | if (sync >= rs->md.resync_max_sectors) { | 1325 | if (sync >= rs->md.resync_max_sectors) { |
1326 | /* | ||
1327 | * Sync complete. | ||
1328 | */ | ||
1301 | array_in_sync = 1; | 1329 | array_in_sync = 1; |
1302 | sync = rs->md.resync_max_sectors; | 1330 | sync = rs->md.resync_max_sectors; |
1331 | } else if (test_bit(MD_RECOVERY_REQUESTED, &rs->md.recovery)) { | ||
1332 | /* | ||
1333 | * If "check" or "repair" is occurring, the array has | ||
1334 | * undergone and initial sync and the health characters | ||
1335 | * should not be 'a' anymore. | ||
1336 | */ | ||
1337 | array_in_sync = 1; | ||
1303 | } else { | 1338 | } else { |
1304 | /* | 1339 | /* |
1305 | * The array may be doing an initial sync, or it may | 1340 | * The array may be doing an initial sync, or it may |
@@ -1311,6 +1346,7 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1311 | if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) | 1346 | if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) |
1312 | array_in_sync = 1; | 1347 | array_in_sync = 1; |
1313 | } | 1348 | } |
1349 | |||
1314 | /* | 1350 | /* |
1315 | * Status characters: | 1351 | * Status characters: |
1316 | * 'D' = Dead/Failed device | 1352 | * 'D' = Dead/Failed device |
@@ -1339,6 +1375,21 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1339 | (unsigned long long) sync, | 1375 | (unsigned long long) sync, |
1340 | (unsigned long long) rs->md.resync_max_sectors); | 1376 | (unsigned long long) rs->md.resync_max_sectors); |
1341 | 1377 | ||
1378 | /* | ||
1379 | * Sync action: | ||
1380 | * See Documentation/device-mapper/dm-raid.c for | ||
1381 | * information on each of these states. | ||
1382 | */ | ||
1383 | DMEMIT(" %s", decipher_sync_action(&rs->md)); | ||
1384 | |||
1385 | /* | ||
1386 | * resync_mismatches/mismatch_cnt | ||
1387 | * This field shows the number of discrepancies found when | ||
1388 | * performing a "check" of the array. | ||
1389 | */ | ||
1390 | DMEMIT(" %llu", | ||
1391 | (unsigned long long) | ||
1392 | atomic64_read(&rs->md.resync_mismatches)); | ||
1342 | break; | 1393 | break; |
1343 | case STATUSTYPE_TABLE: | 1394 | case STATUSTYPE_TABLE: |
1344 | /* The string you would use to construct this array */ | 1395 | /* The string you would use to construct this array */ |
@@ -1425,7 +1476,62 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1425 | } | 1476 | } |
1426 | } | 1477 | } |
1427 | 1478 | ||
1428 | static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) | 1479 | static int raid_message(struct dm_target *ti, unsigned argc, char **argv) |
1480 | { | ||
1481 | struct raid_set *rs = ti->private; | ||
1482 | struct mddev *mddev = &rs->md; | ||
1483 | |||
1484 | if (!strcasecmp(argv[0], "reshape")) { | ||
1485 | DMERR("Reshape not supported."); | ||
1486 | return -EINVAL; | ||
1487 | } | ||
1488 | |||
1489 | if (!mddev->pers || !mddev->pers->sync_request) | ||
1490 | return -EINVAL; | ||
1491 | |||
1492 | if (!strcasecmp(argv[0], "frozen")) | ||
1493 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | ||
1494 | else | ||
1495 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | ||
1496 | |||
1497 | if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { | ||
1498 | if (mddev->sync_thread) { | ||
1499 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | ||
1500 | md_reap_sync_thread(mddev); | ||
1501 | } | ||
1502 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | ||
1503 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | ||
1504 | return -EBUSY; | ||
1505 | else if (!strcasecmp(argv[0], "resync")) | ||
1506 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
1507 | else if (!strcasecmp(argv[0], "recover")) { | ||
1508 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
1509 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
1510 | } else { | ||
1511 | if (!strcasecmp(argv[0], "check")) | ||
1512 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); | ||
1513 | else if (!!strcasecmp(argv[0], "repair")) | ||
1514 | return -EINVAL; | ||
1515 | set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); | ||
1516 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | ||
1517 | } | ||
1518 | if (mddev->ro == 2) { | ||
1519 | /* A write to sync_action is enough to justify | ||
1520 | * canceling read-auto mode | ||
1521 | */ | ||
1522 | mddev->ro = 0; | ||
1523 | if (!mddev->suspended) | ||
1524 | md_wakeup_thread(mddev->sync_thread); | ||
1525 | } | ||
1526 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
1527 | if (!mddev->suspended) | ||
1528 | md_wakeup_thread(mddev->thread); | ||
1529 | |||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1533 | static int raid_iterate_devices(struct dm_target *ti, | ||
1534 | iterate_devices_callout_fn fn, void *data) | ||
1429 | { | 1535 | { |
1430 | struct raid_set *rs = ti->private; | 1536 | struct raid_set *rs = ti->private; |
1431 | unsigned i; | 1537 | unsigned i; |
@@ -1482,12 +1588,13 @@ static void raid_resume(struct dm_target *ti) | |||
1482 | 1588 | ||
1483 | static struct target_type raid_target = { | 1589 | static struct target_type raid_target = { |
1484 | .name = "raid", | 1590 | .name = "raid", |
1485 | .version = {1, 4, 2}, | 1591 | .version = {1, 5, 0}, |
1486 | .module = THIS_MODULE, | 1592 | .module = THIS_MODULE, |
1487 | .ctr = raid_ctr, | 1593 | .ctr = raid_ctr, |
1488 | .dtr = raid_dtr, | 1594 | .dtr = raid_dtr, |
1489 | .map = raid_map, | 1595 | .map = raid_map, |
1490 | .status = raid_status, | 1596 | .status = raid_status, |
1597 | .message = raid_message, | ||
1491 | .iterate_devices = raid_iterate_devices, | 1598 | .iterate_devices = raid_iterate_devices, |
1492 | .io_hints = raid_io_hints, | 1599 | .io_hints = raid_io_hints, |
1493 | .presuspend = raid_presuspend, | 1600 | .presuspend = raid_presuspend, |