aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJonathan E Brassow <jbrassow@redhat.com>2007-05-09 05:32:57 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:30:47 -0400
commit01d03a660e73fb524957c09825a3eb7c2ae7c205 (patch)
tree8f87a5b6b6e34f9baab8661c127bf427cb4eaf41 /drivers
parent2cd54d9bedb79a97f014e86c0da393416b264eb3 (diff)
dm log: fault detection
This patch gives the disk logging code the ability to store the fact that an error occured on the log device. In addition, an event is raised when an error is encountered during I/O to the log device. Signed-off-by: Jonathan E Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-log.c30
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
442static 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
440static int disk_resume(struct dirty_log *log) 451static 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
478static uint32_t core_get_region_size(struct dirty_log *log) 500static 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;