Commit 0c248ea2 authored by yangerkun's avatar yangerkun Committed by Mike Snitzer
Browse files

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: default avataryangerkun <yangerkun@huawei.com>
Signed-off-by: default avatarBryan Gurney <bgurney@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 4f7f590b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -206,6 +206,22 @@ appear::

        dust_clear_badblocks: no badblocks found

Listing the bad block list
--------------------------

To list all bad blocks in the bad block list (using an example device
with blocks 1 and 2 in the bad block list), run the following message
command::

        $ sudo dmsetup message dust1 0 listbadblocks
        1
        2

If there are no bad blocks in the bad block list, the command will
execute with no output::

        $ sudo dmsetup message dust1 0 listbadblocks

Message commands list
---------------------

@@ -224,6 +240,7 @@ Single argument message commands::

        countbadblocks
        clearbadblocks
        listbadblocks
        disable
        enable
        quiet
+27 −0
Original line number Diff line number Diff line
@@ -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;
		}