summaryrefslogtreecommitdiff
path: root/drivers/md/dm-dust.c
diff options
context:
space:
mode:
authoryangerkun <yangerkun@huawei.com>2020-06-20 00:12:42 +0300
committerMike Snitzer <snitzer@redhat.com>2020-07-20 18:17:41 +0300
commit0c248ea27fc88cf8a3035ba0ed75b210be9abf80 (patch)
tree71b4b586f35944e129f8db51e660b0ff922bf48c /drivers/md/dm-dust.c
parent4f7f590b152444c1403ece9eeeddd1e8b22ba04e (diff)
downloadlinux-0c248ea27fc88cf8a3035ba0ed75b210be9abf80.tar.xz
dm dust: add interface to list all badblocks
This interface may help anyone who want to know all badblocks without querying for each block. [Bryan: DMEMIT message if no blocks are in the bad block list.] Signed-off-by: yangerkun <yangerkun@huawei.com> Signed-off-by: Bryan Gurney <bgurney@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-dust.c')
-rw-r--r--drivers/md/dm-dust.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/md/dm-dust.c b/drivers/md/dm-dust.c
index f1f2dd6a4e84..072ea913cebc 100644
--- a/drivers/md/dm-dust.c
+++ b/drivers/md/dm-dust.c
@@ -284,6 +284,31 @@ static int dust_clear_badblocks(struct dust_device *dd, char *result, unsigned i
return 1;
}
+static int dust_list_badblocks(struct dust_device *dd, char *result, unsigned int maxlen,
+ unsigned int *sz_ptr)
+{
+ unsigned long flags;
+ struct rb_root badblocklist;
+ struct rb_node *node;
+ struct badblock *bblk;
+ unsigned int sz = *sz_ptr;
+ unsigned long long num = 0;
+
+ spin_lock_irqsave(&dd->dust_lock, flags);
+ badblocklist = dd->badblocklist;
+ for (node = rb_first(&badblocklist); node; node = rb_next(node)) {
+ bblk = rb_entry(node, struct badblock, node);
+ DMEMIT("%llu\n", bblk->bb);
+ num++;
+ }
+
+ spin_unlock_irqrestore(&dd->dust_lock, flags);
+ if (!num)
+ DMEMIT("No blocks in badblocklist");
+
+ return 1;
+}
+
/*
* Target parameters:
*
@@ -427,6 +452,8 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv,
else
dd->quiet_mode = false;
r = 0;
+ } else if (!strcasecmp(argv[0], "listbadblocks")) {
+ r = dust_list_badblocks(dd, result, maxlen, &sz);
} else {
invalid_msg = true;
}