summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2021-03-11 21:27:29 +0300
committerMike Snitzer <snitzer@redhat.com>2021-03-26 21:53:41 +0300
commitc909085bb319c97b7eccbce4dcbd47a32016e0f7 (patch)
treef6019ee0d50293fa001d1d3dbad2eaca8fe99632 /drivers/md
parent8b638081bd4520f63db1defc660666ec5f65bc15 (diff)
downloadlinux-c909085bb319c97b7eccbce4dcbd47a32016e0f7.tar.xz
dm ioctl: filter the returned values according to name or uuid prefix
If we set non-empty param->name or param->uuid on the DM_LIST_DEVICES_CMD ioctl, the set values are considered filter prefixes. The ioctl will only return entries with matching name or uuid prefix. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-ioctl.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 0812ac6e9d70..2209cbcd84db 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -540,6 +540,30 @@ static void *get_result_buffer(struct dm_ioctl *param, size_t param_size,
return ((void *) param) + param->data_start;
}
+static bool filter_device(struct hash_cell *hc, const char *pfx_name, const char *pfx_uuid)
+{
+ const char *val;
+ size_t val_len, pfx_len;
+
+ val = hc->name;
+ val_len = strlen(val);
+ pfx_len = strnlen(pfx_name, DM_NAME_LEN);
+ if (pfx_len > val_len)
+ return false;
+ if (memcmp(val, pfx_name, pfx_len))
+ return false;
+
+ val = hc->uuid ? hc->uuid : "";
+ val_len = strlen(val);
+ pfx_len = strnlen(pfx_uuid, DM_UUID_LEN);
+ if (pfx_len > val_len)
+ return false;
+ if (memcmp(val, pfx_uuid, pfx_len))
+ return false;
+
+ return true;
+}
+
static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_size)
{
struct rb_node *n;
@@ -557,6 +581,8 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
*/
for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) {
hc = container_of(n, struct hash_cell, name_node);
+ if (!filter_device(hc, param->name, param->uuid))
+ continue;
needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1);
needed += align_val(sizeof(uint32_t) * 2);
if (param->flags & DM_UUID_FLAG && hc->uuid)
@@ -581,6 +607,8 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) {
void *uuid_ptr;
hc = container_of(n, struct hash_cell, name_node);
+ if (!filter_device(hc, param->name, param->uuid))
+ continue;
if (old_nl)
old_nl->next = (uint32_t) ((void *) nl -
(void *) old_nl);