Commit 4f7f590b authored by yangerkun's avatar yangerkun Committed by Mike Snitzer

dm dust: report some message results directly back to user

Some messages (queryblock, countbadblocks, removebadblock) are best
reported directly to user directly. Do so with DMEMIT.

[Bryan: maintain __func__ output in DMEMIT messages]
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 e1fef0b0
...@@ -69,10 +69,11 @@ Create the dm-dust device: ...@@ -69,10 +69,11 @@ Create the dm-dust device:
$ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096' $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096'
Check the status of the read behavior ("bypass" indicates that all I/O Check the status of the read behavior ("bypass" indicates that all I/O
will be passed through to the underlying device):: will be passed through to the underlying device; "verbose" indicates that
bad block additions, removals, and remaps will be verbosely logged)::
$ sudo dmsetup status dust1 $ sudo dmsetup status dust1
0 33552384 dust 252:17 bypass 0 33552384 dust 252:17 bypass verbose
$ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct
128+0 records in 128+0 records in
...@@ -164,7 +165,7 @@ following message command:: ...@@ -164,7 +165,7 @@ following message command::
A message will print with the number of bad blocks currently A message will print with the number of bad blocks currently
configured on the device:: configured on the device::
kernel: device-mapper: dust: countbadblocks: 895 badblock(s) found countbadblocks: 895 badblock(s) found
Querying for specific bad blocks Querying for specific bad blocks
-------------------------------- --------------------------------
...@@ -176,11 +177,11 @@ following message command:: ...@@ -176,11 +177,11 @@ following message command::
The following message will print if the block is in the list:: The following message will print if the block is in the list::
device-mapper: dust: queryblock: block 72 found in badblocklist dust_query_block: block 72 found in badblocklist
The following message will print if the block is not in the list:: The following message will print if the block is not in the list::
device-mapper: dust: queryblock: block 72 not found in badblocklist dust_query_block: block 72 not found in badblocklist
The "queryblock" message command will work in both the "enabled" The "queryblock" message command will work in both the "enabled"
and "disabled" modes, allowing the verification of whether a block and "disabled" modes, allowing the verification of whether a block
...@@ -198,12 +199,12 @@ following message command:: ...@@ -198,12 +199,12 @@ following message command::
After clearing the bad block list, the following message will appear:: After clearing the bad block list, the following message will appear::
kernel: device-mapper: dust: clearbadblocks: badblocks cleared dust_clear_badblocks: badblocks cleared
If there were no bad blocks to clear, the following message will If there were no bad blocks to clear, the following message will
appear:: appear::
kernel: device-mapper: dust: clearbadblocks: no badblocks found dust_clear_badblocks: no badblocks found
Message commands list Message commands list
--------------------- ---------------------
......
...@@ -138,20 +138,22 @@ static int dust_add_block(struct dust_device *dd, unsigned long long block, ...@@ -138,20 +138,22 @@ static int dust_add_block(struct dust_device *dd, unsigned long long block,
return 0; return 0;
} }
static int dust_query_block(struct dust_device *dd, unsigned long long block) static int dust_query_block(struct dust_device *dd, unsigned long long block, char *result,
unsigned int maxlen, unsigned int *sz_ptr)
{ {
struct badblock *bblock; struct badblock *bblock;
unsigned long flags; unsigned long flags;
unsigned int sz = *sz_ptr;
spin_lock_irqsave(&dd->dust_lock, flags); spin_lock_irqsave(&dd->dust_lock, flags);
bblock = dust_rb_search(&dd->badblocklist, block); bblock = dust_rb_search(&dd->badblocklist, block);
if (bblock != NULL) if (bblock != NULL)
DMINFO("%s: block %llu found in badblocklist", __func__, block); DMEMIT("%s: block %llu found in badblocklist", __func__, block);
else else
DMINFO("%s: block %llu not found in badblocklist", __func__, block); DMEMIT("%s: block %llu not found in badblocklist", __func__, block);
spin_unlock_irqrestore(&dd->dust_lock, flags); spin_unlock_irqrestore(&dd->dust_lock, flags);
return 0; return 1;
} }
static int __dust_map_read(struct dust_device *dd, sector_t thisblock) static int __dust_map_read(struct dust_device *dd, sector_t thisblock)
...@@ -259,11 +261,13 @@ static bool __dust_clear_badblocks(struct rb_root *tree, ...@@ -259,11 +261,13 @@ static bool __dust_clear_badblocks(struct rb_root *tree,
return true; return true;
} }
static int dust_clear_badblocks(struct dust_device *dd) static int dust_clear_badblocks(struct dust_device *dd, char *result, unsigned int maxlen,
unsigned int *sz_ptr)
{ {
unsigned long flags; unsigned long flags;
struct rb_root badblocklist; struct rb_root badblocklist;
unsigned long long badblock_count; unsigned long long badblock_count;
unsigned int sz = *sz_ptr;
spin_lock_irqsave(&dd->dust_lock, flags); spin_lock_irqsave(&dd->dust_lock, flags);
badblocklist = dd->badblocklist; badblocklist = dd->badblocklist;
...@@ -273,11 +277,11 @@ static int dust_clear_badblocks(struct dust_device *dd) ...@@ -273,11 +277,11 @@ static int dust_clear_badblocks(struct dust_device *dd)
spin_unlock_irqrestore(&dd->dust_lock, flags); spin_unlock_irqrestore(&dd->dust_lock, flags);
if (!__dust_clear_badblocks(&badblocklist, badblock_count)) if (!__dust_clear_badblocks(&badblocklist, badblock_count))
DMINFO("%s: no badblocks found", __func__); DMEMIT("%s: no badblocks found", __func__);
else else
DMINFO("%s: badblocks cleared", __func__); DMEMIT("%s: badblocks cleared", __func__);
return 0; return 1;
} }
/* /*
...@@ -383,7 +387,7 @@ static void dust_dtr(struct dm_target *ti) ...@@ -383,7 +387,7 @@ static void dust_dtr(struct dm_target *ti)
} }
static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, static int dust_message(struct dm_target *ti, unsigned int argc, char **argv,
char *result_buf, unsigned int maxlen) char *result, unsigned int maxlen)
{ {
struct dust_device *dd = ti->private; struct dust_device *dd = ti->private;
sector_t size = i_size_read(dd->dev->bdev->bd_inode) >> SECTOR_SHIFT; sector_t size = i_size_read(dd->dev->bdev->bd_inode) >> SECTOR_SHIFT;
...@@ -393,6 +397,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, ...@@ -393,6 +397,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv,
unsigned char wr_fail_cnt; unsigned char wr_fail_cnt;
unsigned int tmp_ui; unsigned int tmp_ui;
unsigned long flags; unsigned long flags;
unsigned int sz = 0;
char dummy; char dummy;
if (argc == 1) { if (argc == 1) {
...@@ -410,12 +415,12 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, ...@@ -410,12 +415,12 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv,
r = 0; r = 0;
} else if (!strcasecmp(argv[0], "countbadblocks")) { } else if (!strcasecmp(argv[0], "countbadblocks")) {
spin_lock_irqsave(&dd->dust_lock, flags); spin_lock_irqsave(&dd->dust_lock, flags);
DMINFO("countbadblocks: %llu badblock(s) found", DMEMIT("countbadblocks: %llu badblock(s) found",
dd->badblock_count); dd->badblock_count);
spin_unlock_irqrestore(&dd->dust_lock, flags); spin_unlock_irqrestore(&dd->dust_lock, flags);
r = 0; r = 1;
} else if (!strcasecmp(argv[0], "clearbadblocks")) { } else if (!strcasecmp(argv[0], "clearbadblocks")) {
r = dust_clear_badblocks(dd); r = dust_clear_badblocks(dd, result, maxlen, &sz);
} else if (!strcasecmp(argv[0], "quiet")) { } else if (!strcasecmp(argv[0], "quiet")) {
if (!dd->quiet_mode) if (!dd->quiet_mode)
dd->quiet_mode = true; dd->quiet_mode = true;
...@@ -441,7 +446,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, ...@@ -441,7 +446,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv,
else if (!strcasecmp(argv[0], "removebadblock")) else if (!strcasecmp(argv[0], "removebadblock"))
r = dust_remove_block(dd, block); r = dust_remove_block(dd, block);
else if (!strcasecmp(argv[0], "queryblock")) else if (!strcasecmp(argv[0], "queryblock"))
r = dust_query_block(dd, block); r = dust_query_block(dd, block, result, maxlen, &sz);
else else
invalid_msg = true; invalid_msg = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment