From: Li Lingfeng <lilingfeng3@huawei.com>
To: <dm-devel@redhat.com>
Cc: yi.zhang@huawei.com, yangerkun@huawei.com, snitzer@kernel.org,
lilingfeng@huaweicloud.com, linan122@huawei.com,
houtao1@huawei.com, yukuai3@huawei.com, lilingfeng3@huawei.com,
agk@redhat.com
Subject: [dm-devel] [PATCH -next] dm snapshot: record cause of invalidating snapshot
Date: Thu, 10 Aug 2023 14:44:06 +0800 [thread overview]
Message-ID: <20230810064406.1672148-1-lilingfeng3@huawei.com> (raw)
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
next reply other threads:[~2023-08-10 6:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-10 6:44 Li Lingfeng [this message]
2023-09-09 11:09 ` [dm-devel] [PATCH -next] dm snapshot: record cause of invalidating snapshot Li Lingfeng
2023-10-11 2:36 ` Li Lingfeng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230810064406.1672148-1-lilingfeng3@huawei.com \
--to=lilingfeng3@huawei.com \
--cc=agk@redhat.com \
--cc=dm-devel@redhat.com \
--cc=houtao1@huawei.com \
--cc=lilingfeng@huaweicloud.com \
--cc=linan122@huawei.com \
--cc=snitzer@kernel.org \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.com \
--cc=yukuai3@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox