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>
This commit is contained in:
parent
2cd54d9bed
commit
01d03a660e
|
@ -152,6 +152,7 @@ struct log_c {
|
||||||
/*
|
/*
|
||||||
* Disk log fields
|
* Disk log fields
|
||||||
*/
|
*/
|
||||||
|
int log_dev_failed;
|
||||||
struct dm_dev *log_dev;
|
struct dm_dev *log_dev;
|
||||||
struct log_header header;
|
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;
|
lc->disk_header = NULL;
|
||||||
} else {
|
} else {
|
||||||
lc->log_dev = dev;
|
lc->log_dev = dev;
|
||||||
|
lc->log_dev_failed = 0;
|
||||||
lc->header_location.bdev = lc->log_dev->bdev;
|
lc->header_location.bdev = lc->log_dev->bdev;
|
||||||
lc->header_location.sector = 0;
|
lc->header_location.sector = 0;
|
||||||
|
|
||||||
|
@ -437,6 +439,15 @@ static int count_bits32(uint32_t *addr, unsigned size)
|
||||||
return count;
|
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)
|
static int disk_resume(struct dirty_log *log)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
@ -446,8 +457,12 @@ static int disk_resume(struct dirty_log *log)
|
||||||
|
|
||||||
/* read the disk header */
|
/* read the disk header */
|
||||||
r = read_header(lc);
|
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;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* set or clear any new bits -- device has grown */
|
/* set or clear any new bits -- device has grown */
|
||||||
if (lc->sync == NOSYNC)
|
if (lc->sync == NOSYNC)
|
||||||
|
@ -472,7 +487,14 @@ static int disk_resume(struct dirty_log *log)
|
||||||
lc->header.nr_regions = lc->region_count;
|
lc->header.nr_regions = lc->region_count;
|
||||||
|
|
||||||
/* write the new header */
|
/* 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)
|
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;
|
return 0;
|
||||||
|
|
||||||
r = write_header(lc);
|
r = write_header(lc);
|
||||||
if (!r)
|
if (r)
|
||||||
|
fail_log_device(lc);
|
||||||
|
else
|
||||||
lc->touched = 0;
|
lc->touched = 0;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
Loading…
Reference in New Issue