Commit d8ddb1cf authored by Mike Snitzer's avatar Mike Snitzer Committed by Alasdair G Kergon

dm snapshot: report merge failure in status

Set 'merge_failed' flag if a snapshot fails to merge.  Update
snapshot_status() to report "Merge failed" if 'merge_failed' is set.
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 8a2d5286
...@@ -71,7 +71,10 @@ struct dm_snapshot { ...@@ -71,7 +71,10 @@ struct dm_snapshot {
/* List of snapshots per Origin */ /* List of snapshots per Origin */
struct list_head list; struct list_head list;
/* You can't use a snapshot if this is 0 (e.g. if full) */ /*
* You can't use a snapshot if this is 0 (e.g. if full).
* A snapshot-merge target never clears this.
*/
int valid; int valid;
/* Origin writes don't trigger exceptions until this is set */ /* Origin writes don't trigger exceptions until this is set */
...@@ -107,6 +110,21 @@ struct dm_snapshot { ...@@ -107,6 +110,21 @@ struct dm_snapshot {
spinlock_t tracked_chunk_lock; spinlock_t tracked_chunk_lock;
struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
/*
* The merge operation failed if this flag is set.
* Failure modes are handled as follows:
* - I/O error reading the header
* => don't load the target; abort.
* - Header does not have "valid" flag set
* => use the origin; forget about the snapshot.
* - I/O error when reading exceptions
* => don't load the target; abort.
* (We can't use the intermediate origin state.)
* - I/O error while merging
* => stop merging; set merge_failed; process I/O normally.
*/
int merge_failed;
/* Wait for events based on state_bits */ /* Wait for events based on state_bits */
unsigned long state_bits; unsigned long state_bits;
...@@ -900,9 +918,13 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) ...@@ -900,9 +918,13 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s)
linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk, linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk,
&new_chunk); &new_chunk);
if (linear_chunks <= 0) { if (linear_chunks <= 0) {
if (linear_chunks < 0) if (linear_chunks < 0) {
DMERR("Read error in exception store: " DMERR("Read error in exception store: "
"shutting down merge"); "shutting down merge");
down_write(&s->lock);
s->merge_failed = 1;
up_write(&s->lock);
}
goto shut; goto shut;
} }
...@@ -988,6 +1010,7 @@ static void merge_callback(int read_err, unsigned long write_err, void *context) ...@@ -988,6 +1010,7 @@ static void merge_callback(int read_err, unsigned long write_err, void *context)
shut: shut:
down_write(&s->lock); down_write(&s->lock);
s->merge_failed = 1;
b = __release_queued_bios_after_merge(s); b = __release_queued_bios_after_merge(s);
up_write(&s->lock); up_write(&s->lock);
error_bios(b); error_bios(b);
...@@ -1090,6 +1113,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -1090,6 +1113,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
INIT_LIST_HEAD(&s->list); INIT_LIST_HEAD(&s->list);
spin_lock_init(&s->pe_lock); spin_lock_init(&s->pe_lock);
s->state_bits = 0; s->state_bits = 0;
s->merge_failed = 0;
s->first_merging_chunk = 0; s->first_merging_chunk = 0;
s->num_merging_chunks = 0; s->num_merging_chunks = 0;
bio_list_init(&s->bios_queued_during_merge); bio_list_init(&s->bios_queued_during_merge);
...@@ -1835,6 +1859,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, ...@@ -1835,6 +1859,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
if (!snap->valid) if (!snap->valid)
DMEMIT("Invalid"); DMEMIT("Invalid");
else if (snap->merge_failed)
DMEMIT("Merge failed");
else { else {
if (snap->store->type->usage) { if (snap->store->type->usage) {
sector_t total_sectors, sectors_allocated, sector_t total_sectors, sectors_allocated,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment