[dm-devel] [PATCH v5 13/13] dm snapshot: report merge failure in status

Mike Snitzer snitzer at redhat.com
Fri Dec 4 02:23:54 UTC 2009


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: Mike Snitzer <snitzer at redhat.com>
---
 drivers/md/dm-snap.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index e1eafc2..1934455 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -102,6 +102,9 @@ struct dm_snapshot {
 	spinlock_t tracked_chunk_lock;
 	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
 
+	/* Merge operation failed if this is set */
+	int merge_failed;
+
 	/* Merge operation is in progress */
 	int merge_running;
 
@@ -775,9 +778,13 @@ static void snapshot_merge_process(struct dm_snapshot *s)
 	linear_chunks = s->store->type->prepare_merge(s->store,
 						      &old_chunk, &new_chunk);
 	if (linear_chunks <= 0) {
-		if (linear_chunks < 0)
+		if (linear_chunks < 0) {
 			DMERR("Read error in exception store, "
 			      "shutting down merge");
+			down_write(&s->lock);
+			s->merge_failed = 1;
+			up_write(&s->lock);
+		}
 		goto shut;
 	}
 	/* Adjust old_chunk and new_chunk to reflect start of linear region */
@@ -883,6 +890,7 @@ static void merge_callback(int read_err, unsigned long write_err, void *context)
 			DMERR("corruption detected: exception for block %llu "
 			      "is on disk but not in memory",
 			      (unsigned long long)old_chunk);
+			s->merge_failed = 1;
 			up_write(&s->lock);
 			goto shut;
 		}
@@ -898,6 +906,7 @@ static void merge_callback(int read_err, unsigned long write_err, void *context)
 				      (unsigned long long)e->old_chunk,
 				      (unsigned long long)e->old_chunk +
 				      dm_consecutive_chunk_count(e));
+				s->merge_failed = 1;
 				up_write(&s->lock);
 				goto shut;
 			}
@@ -1002,6 +1011,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	init_rwsem(&s->lock);
 	INIT_LIST_HEAD(&s->list);
 	spin_lock_init(&s->pe_lock);
+	s->merge_failed = 0;
 	s->merge_running = 0;
 	s->merge_shutdown = 0;
 	s->merge_write_interlock = 0;
@@ -1741,6 +1751,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
 
 		if (!snap->valid)
 			DMEMIT("Invalid");
+		else if (snap->merge_failed)
+			DMEMIT("Merge failed");
 		else {
 			if (snap->store->type->usage) {
 				sector_t total_sectors, sectors_allocated,
-- 
1.6.5.2




More information about the dm-devel mailing list