diff options
Diffstat (limited to 'drivers/md/dm-log.c')
-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 { /* * Disk log fields */ + int log_dev_failed; struct dm_dev *log_dev; struct log_header header; @@ -315,6 +316,7 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, lc->disk_header = NULL; } else { lc->log_dev = dev; + lc->log_dev_failed = 0; lc->header_location.bdev = lc->log_dev->bdev; lc->header_location.sector = 0; @@ -437,6 +439,15 @@ static int count_bits32(uint32_t *addr, unsigned size) return count; } +static void fail_log_device(struct log_c *lc) +{ + if (lc->log_dev_failed) + return; + + lc->log_dev_failed = 1; + dm_table_event(lc->ti->table); +} + static int disk_resume(struct dirty_log *log) { int r; @@ -446,8 +457,12 @@ static int disk_resume(struct dirty_log *log) /* read the disk header */ r = read_header(lc); - if (r) + if (r) { + DMWARN("%s: Failed to read header on mirror log device", + lc->log_dev->name); + fail_log_device(lc); return r; + } /* set or clear any new bits -- device has grown */ if (lc->sync == NOSYNC) @@ -472,7 +487,14 @@ static int disk_resume(struct dirty_log *log) lc->header.nr_regions = lc->region_count; /* write the new header */ - return write_header(lc); + r = write_header(lc); + if (r) { + DMWARN("%s: Failed to write header on mirror log device", + lc->log_dev->name); + fail_log_device(lc); + } + + return r; } static uint32_t core_get_region_size(struct dirty_log *log) @@ -516,7 +538,9 @@ static int disk_flush(struct dirty_log *log) return 0; r = write_header(lc); - if (!r) + if (r) + fail_log_device(lc); + else lc->touched = 0; return r; |