diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-log.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 6a9261351848..a503d12c2ff8 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -152,6 +152,7 @@ struct log_c { | |||
152 | /* | 152 | /* |
153 | * Disk log fields | 153 | * Disk log fields |
154 | */ | 154 | */ |
155 | int log_dev_failed; | ||
155 | struct dm_dev *log_dev; | 156 | struct dm_dev *log_dev; |
156 | struct log_header header; | 157 | struct log_header header; |
157 | 158 | ||
@@ -315,6 +316,7 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, | |||
315 | lc->disk_header = NULL; | 316 | lc->disk_header = NULL; |
316 | } else { | 317 | } else { |
317 | lc->log_dev = dev; | 318 | lc->log_dev = dev; |
319 | lc->log_dev_failed = 0; | ||
318 | lc->header_location.bdev = lc->log_dev->bdev; | 320 | lc->header_location.bdev = lc->log_dev->bdev; |
319 | lc->header_location.sector = 0; | 321 | lc->header_location.sector = 0; |
320 | 322 | ||
@@ -437,6 +439,15 @@ static int count_bits32(uint32_t *addr, unsigned size) | |||
437 | return count; | 439 | return count; |
438 | } | 440 | } |
439 | 441 | ||
442 | static void fail_log_device(struct log_c *lc) | ||
443 | { | ||
444 | if (lc->log_dev_failed) | ||
445 | return; | ||
446 | |||
447 | lc->log_dev_failed = 1; | ||
448 | dm_table_event(lc->ti->table); | ||
449 | } | ||
450 | |||
440 | static int disk_resume(struct dirty_log *log) | 451 | static int disk_resume(struct dirty_log *log) |
441 | { | 452 | { |
442 | int r; | 453 | int r; |
@@ -446,8 +457,12 @@ static int disk_resume(struct dirty_log *log) | |||
446 | 457 | ||
447 | /* read the disk header */ | 458 | /* read the disk header */ |
448 | r = read_header(lc); | 459 | r = read_header(lc); |
449 | if (r) | 460 | if (r) { |
461 | DMWARN("%s: Failed to read header on mirror log device", | ||
462 | lc->log_dev->name); | ||
463 | fail_log_device(lc); | ||
450 | return r; | 464 | return r; |
465 | } | ||
451 | 466 | ||
452 | /* set or clear any new bits -- device has grown */ | 467 | /* set or clear any new bits -- device has grown */ |
453 | if (lc->sync == NOSYNC) | 468 | if (lc->sync == NOSYNC) |
@@ -472,7 +487,14 @@ static int disk_resume(struct dirty_log *log) | |||
472 | lc->header.nr_regions = lc->region_count; | 487 | lc->header.nr_regions = lc->region_count; |
473 | 488 | ||
474 | /* write the new header */ | 489 | /* write the new header */ |
475 | return write_header(lc); | 490 | r = write_header(lc); |
491 | if (r) { | ||
492 | DMWARN("%s: Failed to write header on mirror log device", | ||
493 | lc->log_dev->name); | ||
494 | fail_log_device(lc); | ||
495 | } | ||
496 | |||
497 | return r; | ||
476 | } | 498 | } |
477 | 499 | ||
478 | static uint32_t core_get_region_size(struct dirty_log *log) | 500 | static uint32_t core_get_region_size(struct dirty_log *log) |
@@ -516,7 +538,9 @@ static int disk_flush(struct dirty_log *log) | |||
516 | return 0; | 538 | return 0; |
517 | 539 | ||
518 | r = write_header(lc); | 540 | r = write_header(lc); |
519 | if (!r) | 541 | if (r) |
542 | fail_log_device(lc); | ||
543 | else | ||
520 | lc->touched = 0; | 544 | lc->touched = 0; |
521 | 545 | ||
522 | return r; | 546 | return r; |