Linux Device Mapper development
 help / color / mirror / Atom feed
* [dm-devel] [PATCH -next] dm snapshot: record cause of invalidating snapshot
@ 2023-08-10  6:44 Li Lingfeng
  2023-09-09 11:09 ` Li Lingfeng
  0 siblings, 1 reply; 3+ messages in thread
From: Li Lingfeng @ 2023-08-10  6:44 UTC (permalink / raw)
  To: dm-devel
  Cc: yi.zhang, yangerkun, snitzer, lilingfeng, linan122, houtao1,
	yukuai3, lilingfeng3, agk

The cause of invalidating snapshot will be print in log. However, if we
lost the log, we will never get the cause. What we can get by "dmsetup
status" is the state of "Invalid" without the cause.

Record cause of invalidating snapshot in snapshot->valid, so that we can
query the cause by "dmsetup status".

Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
---
 drivers/md/dm-snap.c | 60 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 41735a25d50a..48788431e7bf 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -39,6 +39,28 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge";
 #define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
 					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
 
+#define INVALID_CAUSE_BIT		16
+#define DM_SNAPSHOT_VALID(s)		(s->valid & \
+					((1 << INVALID_CAUSE_BIT) - 1))
+#define DM_SNAPSHOT_INVALID_CAUSE(s)	(s->valid >> INVALID_CAUSE_BIT)
+#define SET_INVALID_CAUSE(s, cause)	(s->valid = \
+					(DM_SNAPSHOT_VALID(s) | \
+					(cause << INVALID_CAUSE_BIT)))
+
+enum invalid_cause {
+	INVALID_BY_METADATA = 1,
+	INVALID_BY_HANDOVER = 2,
+	INVALID_BY_CACELLING_HANDOVER = 3,
+	INVALID_BY_EIO = 4,
+	INVALID_BY_ENOMEM = 5
+};
+
+char *display_invalid_cause[] = {"by METADATA",
+				 "by HANDOVER",
+				 "by CANCELLING HANDOVER",
+				 "by EIO",
+				 "by ENOMEM"};
+
 struct dm_exception_table {
 	uint32_t hash_mask;
 	unsigned hash_shift;
@@ -1054,7 +1076,7 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s)
 	/*
 	 * valid flag never changes during merge, so no lock required.
 	 */
-	if (!s->valid) {
+	if (!DM_SNAPSHOT_VALID(s)) {
 		DMERR("Snapshot is invalid: can't merge");
 		goto shut;
 	}
@@ -1403,6 +1425,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		goto bad_read_metadata;
 	} else if (r > 0) {
 		s->valid = 0;
+		SET_INVALID_CAUSE(s, INVALID_BY_METADATA);
 		DMWARN("Snapshot is marked invalid.");
 	}
 
@@ -1480,6 +1503,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src,
 	 * Set source invalid to ensure it receives no further I/O.
 	 */
 	snap_src->valid = 0;
+	SET_INVALID_CAUSE(snap_src, INVALID_BY_HANDOVER);
 }
 
 static void snapshot_dtr(struct dm_target *ti)
@@ -1496,6 +1520,7 @@ static void snapshot_dtr(struct dm_target *ti)
 	if (snap_src && snap_dest && (s == snap_src)) {
 		down_write(&snap_dest->lock);
 		snap_dest->valid = 0;
+		SET_INVALID_CAUSE(snap_dest, INVALID_BY_HANDOVER);
 		up_write(&snap_dest->lock);
 		DMERR("Cancelling snapshot handover.");
 	}
@@ -1635,18 +1660,21 @@ static void error_bios(struct bio *bio)
 
 static void __invalidate_snapshot(struct dm_snapshot *s, int err)
 {
-	if (!s->valid)
+	if (!DM_SNAPSHOT_VALID(s))
 		return;
 
-	if (err == -EIO)
-		DMERR("Invalidating snapshot: Error reading/writing.");
-	else if (err == -ENOMEM)
-		DMERR("Invalidating snapshot: Unable to allocate exception.");
-
 	if (s->store->type->drop_snapshot)
 		s->store->type->drop_snapshot(s->store);
 
 	s->valid = 0;
+	if (err == -EIO) {
+		SET_INVALID_CAUSE(s, INVALID_BY_EIO);
+		DMERR("Invalidating snapshot: Error reading/writing.");
+	} else if (err == -ENOMEM) {
+		SET_INVALID_CAUSE(s, INVALID_BY_ENOMEM);
+		DMERR("Invalidating snapshot: Unable to allocate exception.");
+	}
+
 
 	dm_table_event(s->ti->table);
 }
@@ -1692,7 +1720,7 @@ static void pending_complete(void *context, int success)
 
 	down_read(&s->lock);
 	dm_exception_table_lock(&lock);
-	if (!s->valid) {
+	if (!DM_SNAPSHOT_VALID(s)) {
 		up_read(&s->lock);
 		free_completed_exception(e);
 		error = 1;
@@ -1984,7 +2012,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
 
 	/* Full snapshots are not usable */
 	/* To get here the table must be live so s->active is always set. */
-	if (!s->valid)
+	if (!DM_SNAPSHOT_VALID(s))
 		return DM_MAPIO_KILL;
 
 	if (bio_data_dir(bio) == WRITE) {
@@ -1995,7 +2023,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
 	down_read(&s->lock);
 	dm_exception_table_lock(&lock);
 
-	if (!s->valid || (unlikely(s->snapshot_overflowed) &&
+	if (!DM_SNAPSHOT_VALID(s) || (unlikely(s->snapshot_overflowed) &&
 	    bio_data_dir(bio) == WRITE)) {
 		r = DM_MAPIO_KILL;
 		goto out_unlock;
@@ -2068,7 +2096,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
 				down_write(&s->lock);
 
 				if (s->store->userspace_supports_overflow) {
-					if (s->valid && !s->snapshot_overflowed) {
+					if (DM_SNAPSHOT_VALID(s) && !s->snapshot_overflowed) {
 						s->snapshot_overflowed = 1;
 						DMERR("Snapshot overflowed: Unable to allocate exception.");
 					}
@@ -2159,7 +2187,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
 	down_write(&s->lock);
 
 	/* Full merging snapshots are redirected to the origin */
-	if (!s->valid)
+	if (!DM_SNAPSHOT_VALID(s))
 		goto redirect_to_origin;
 
 	/* If the block is already remapped - use that */
@@ -2344,8 +2372,10 @@ static void snapshot_status(struct dm_target *ti, status_type_t type,
 
 		down_write(&snap->lock);
 
-		if (!snap->valid)
-			DMEMIT("Invalid");
+		if (!DM_SNAPSHOT_VALID(snap))
+			DMEMIT("Invalid %s", DM_SNAPSHOT_INVALID_CAUSE(snap) ?
+					display_invalid_cause[DM_SNAPSHOT_INVALID_CAUSE(snap) - 1] :
+					"");
 		else if (snap->merge_failed)
 			DMEMIT("Merge failed");
 		else if (snap->snapshot_overflowed)
@@ -2477,7 +2507,7 @@ static int __origin_write(struct list_head *snapshots, sector_t sector,
 		dm_exception_table_lock(&lock);
 
 		/* Only deal with valid and active snapshots */
-		if (!snap->valid || !snap->active)
+		if (!DM_SNAPSHOT_VALID(snap) || !snap->active)
 			goto next_snapshot;
 
 		pe = __lookup_pending_exception(snap, chunk);
-- 
2.31.1

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-10-11  2:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-10  6:44 [dm-devel] [PATCH -next] dm snapshot: record cause of invalidating snapshot Li Lingfeng
2023-09-09 11:09 ` Li Lingfeng
2023-10-11  2:36   ` Li Lingfeng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox