Commit b93ddaf8 authored by Alasdair G. Kergon's avatar Alasdair G. Kergon Committed by Linus Torvalds

[PATCH] device-mapper: Add DM_TARGET_MSG

Add DM_TARGET_MSG ioctl so data can be passed to a dm target after its table
has been loaded.
Signed-Off-By: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 589eaffd
/* /*
* Copyright (C) 2001, 2002 Sistina Software (UK) Limited. * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* *
* This file is released under the GPL. * This file is released under the GPL.
*/ */
...@@ -1097,6 +1098,67 @@ static int table_status(struct dm_ioctl *param, size_t param_size) ...@@ -1097,6 +1098,67 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
return r; return r;
} }
/*
* Pass a message to the target that's at the supplied device offset.
*/
static int target_message(struct dm_ioctl *param, size_t param_size)
{
int r, argc;
char **argv;
struct mapped_device *md;
struct dm_table *table;
struct dm_target *ti;
struct dm_target_msg *tmsg = (void *) param + param->data_start;
md = find_device(param);
if (!md)
return -ENXIO;
r = __dev_status(md, param);
if (r)
goto out;
if (tmsg < (struct dm_target_msg *) (param + 1) ||
invalid_str(tmsg->message, (void *) param + param_size)) {
DMWARN("Invalid target message parameters.");
r = -EINVAL;
goto out;
}
r = dm_split_args(&argc, &argv, tmsg->message);
if (r) {
DMWARN("Failed to split target message parameters");
goto out;
}
table = dm_get_table(md);
if (!table)
goto out_argv;
if (tmsg->sector >= dm_table_get_size(table)) {
DMWARN("Target message sector outside device.");
r = -EINVAL;
goto out_table;
}
ti = dm_table_find_target(table, tmsg->sector);
if (ti->type->message)
r = ti->type->message(ti, argc, argv);
else {
DMWARN("Target type does not support messages");
r = -EINVAL;
}
out_table:
dm_table_put(table);
out_argv:
kfree(argv);
out:
param->data_size = 0;
dm_put(md);
return r;
}
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
* Implementation of open/close/ioctl on the special char * Implementation of open/close/ioctl on the special char
* device. * device.
...@@ -1123,7 +1185,9 @@ static ioctl_fn lookup_ioctl(unsigned int cmd) ...@@ -1123,7 +1185,9 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
{DM_TABLE_DEPS_CMD, table_deps}, {DM_TABLE_DEPS_CMD, table_deps},
{DM_TABLE_STATUS_CMD, table_status}, {DM_TABLE_STATUS_CMD, table_status},
{DM_LIST_VERSIONS_CMD, list_versions} {DM_LIST_VERSIONS_CMD, list_versions},
{DM_TARGET_MSG_CMD, target_message}
}; };
return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
......
/* /*
* Copyright (C) 2001 Sistina Software (UK) Limited. * Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* *
* This file is released under the GPL. * This file is released under the GPL.
*/ */
...@@ -575,7 +576,7 @@ static char **realloc_argv(unsigned *array_size, char **old_argv) ...@@ -575,7 +576,7 @@ static char **realloc_argv(unsigned *array_size, char **old_argv)
/* /*
* Destructively splits up the argument list to pass to ctr. * Destructively splits up the argument list to pass to ctr.
*/ */
static int split_args(int *argc, char ***argvp, char *input) int dm_split_args(int *argc, char ***argvp, char *input)
{ {
char *start, *end = input, *out, **argv = NULL; char *start, *end = input, *out, **argv = NULL;
unsigned array_size = 0; unsigned array_size = 0;
...@@ -688,7 +689,7 @@ int dm_table_add_target(struct dm_table *t, const char *type, ...@@ -688,7 +689,7 @@ int dm_table_add_target(struct dm_table *t, const char *type,
goto bad; goto bad;
} }
r = split_args(&argc, &argv, params); r = dm_split_args(&argc, &argv, params);
if (r) { if (r) {
tgt->error = "couldn't split parameters (insufficient memory)"; tgt->error = "couldn't split parameters (insufficient memory)";
goto bad; goto bad;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Internal header file for device mapper * Internal header file for device mapper
* *
* Copyright (C) 2001, 2002 Sistina Software * Copyright (C) 2001, 2002 Sistina Software
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* *
* This file is released under the LGPL. * This file is released under the LGPL.
*/ */
...@@ -165,6 +166,8 @@ static inline unsigned long to_bytes(sector_t n) ...@@ -165,6 +166,8 @@ static inline unsigned long to_bytes(sector_t n)
return (n << 9); return (n << 9);
} }
int dm_split_args(int *argc, char ***argvp, char *input);
/* /*
* The device-mapper can be driven through one of two interfaces; * The device-mapper can be driven through one of two interfaces;
* ioctl or filesystem, depending which patch you have applied. * ioctl or filesystem, depending which patch you have applied.
......
...@@ -140,6 +140,7 @@ COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32) ...@@ -140,6 +140,7 @@ COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32)
COMPATIBLE_IOCTL(DM_TABLE_DEPS_32) COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
COMPATIBLE_IOCTL(DM_TABLE_STATUS_32) COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32) COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
COMPATIBLE_IOCTL(DM_VERSION) COMPATIBLE_IOCTL(DM_VERSION)
COMPATIBLE_IOCTL(DM_REMOVE_ALL) COMPATIBLE_IOCTL(DM_REMOVE_ALL)
COMPATIBLE_IOCTL(DM_LIST_DEVICES) COMPATIBLE_IOCTL(DM_LIST_DEVICES)
...@@ -154,6 +155,7 @@ COMPATIBLE_IOCTL(DM_TABLE_CLEAR) ...@@ -154,6 +155,7 @@ COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
COMPATIBLE_IOCTL(DM_TABLE_DEPS) COMPATIBLE_IOCTL(DM_TABLE_DEPS)
COMPATIBLE_IOCTL(DM_TABLE_STATUS) COMPATIBLE_IOCTL(DM_TABLE_STATUS)
COMPATIBLE_IOCTL(DM_LIST_VERSIONS) COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
COMPATIBLE_IOCTL(DM_TARGET_MSG)
/* Big K */ /* Big K */
COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(PIO_FONT)
COMPATIBLE_IOCTL(GIO_FONT) COMPATIBLE_IOCTL(GIO_FONT)
......
/* /*
* Copyright (C) 2001 Sistina Software (UK) Limited. * Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* *
* This file is released under the LGPL. * This file is released under the LGPL.
*/ */
...@@ -57,6 +58,8 @@ typedef void (*dm_resume_fn) (struct dm_target *ti); ...@@ -57,6 +58,8 @@ typedef void (*dm_resume_fn) (struct dm_target *ti);
typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
char *result, unsigned int maxlen); char *result, unsigned int maxlen);
typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
void dm_error(const char *message); void dm_error(const char *message);
/* /*
...@@ -82,6 +85,7 @@ struct target_type { ...@@ -82,6 +85,7 @@ struct target_type {
dm_suspend_fn suspend; dm_suspend_fn suspend;
dm_resume_fn resume; dm_resume_fn resume;
dm_status_fn status; dm_status_fn status;
dm_message_fn message;
}; };
struct io_restrictions { struct io_restrictions {
......
/* /*
* Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* *
* This file is released under the LGPL. * This file is released under the LGPL.
*/ */
...@@ -76,6 +77,9 @@ ...@@ -76,6 +77,9 @@
* *
* DM_TABLE_STATUS: * DM_TABLE_STATUS:
* Return the targets status for the 'active' table. * Return the targets status for the 'active' table.
*
* DM_TARGET_MSG:
* Pass a message string to the target at a specific offset of a device.
*/ */
/* /*
...@@ -178,6 +182,15 @@ struct dm_target_versions { ...@@ -178,6 +182,15 @@ struct dm_target_versions {
char name[0]; char name[0];
}; };
/*
* Used to pass message to a target
*/
struct dm_target_msg {
uint64_t sector; /* Device sector */
char message[0];
};
/* /*
* If you change this make sure you make the corresponding change * If you change this make sure you make the corresponding change
* to dm-ioctl.c:lookup_ioctl() * to dm-ioctl.c:lookup_ioctl()
...@@ -204,6 +217,7 @@ enum { ...@@ -204,6 +217,7 @@ enum {
/* Added later */ /* Added later */
DM_LIST_VERSIONS_CMD, DM_LIST_VERSIONS_CMD,
DM_TARGET_MSG_CMD,
}; };
/* /*
...@@ -232,6 +246,7 @@ typedef char ioctl_struct[308]; ...@@ -232,6 +246,7 @@ typedef char ioctl_struct[308];
#define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct) #define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct)
#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) #define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct)
#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) #define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct)
#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct)
#endif #endif
#define DM_IOCTL 0xfd #define DM_IOCTL 0xfd
...@@ -254,10 +269,12 @@ typedef char ioctl_struct[308]; ...@@ -254,10 +269,12 @@ typedef char ioctl_struct[308];
#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) #define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4 #define DM_VERSION_MAJOR 4
#define DM_VERSION_MINOR 1 #define DM_VERSION_MINOR 2
#define DM_VERSION_PATCHLEVEL 0 #define DM_VERSION_PATCHLEVEL 0
#define DM_VERSION_EXTRA "-ioctl (2003-12-10)" #define DM_VERSION_EXTRA "-ioctl (2004-06-08)"
/* Status bits */ /* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */
......
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