summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-07-05 14:32:42 +0000
committermav <mav@FreeBSD.org>2014-07-05 14:32:42 +0000
commit6a3d6f39825c967975be57c4826c2a2c91803940 (patch)
treeb3bd61abf4959a5fd0aa9484d9141b8715dc3bad
parentcd2bf77221bc5ca0b3bc700494ceb7267a9c276c (diff)
downloadFreeBSD-src-6a3d6f39825c967975be57c4826c2a2c91803940.zip
FreeBSD-src-6a3d6f39825c967975be57c4826c2a2c91803940.tar.gz
Improve CTL_BEARG_* flags support, including optional values copyout.
-rw-r--r--sys/cam/ctl/ctl.c64
-rw-r--r--sys/cam/ctl/ctl_backend.c4
2 files changed, 43 insertions, 25 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 126dbf2..cb41bf5 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -2013,40 +2013,40 @@ ctl_copyin_alloc(void *user_addr, int len, char *error_str,
}
static void
-ctl_free_args(int num_be_args, struct ctl_be_arg *be_args)
+ctl_free_args(int num_args, struct ctl_be_arg *args)
{
int i;
- if (be_args == NULL)
+ if (args == NULL)
return;
- for (i = 0; i < num_be_args; i++) {
- free(be_args[i].kname, M_CTL);
- free(be_args[i].kvalue, M_CTL);
+ for (i = 0; i < num_args; i++) {
+ free(args[i].kname, M_CTL);
+ free(args[i].kvalue, M_CTL);
}
- free(be_args, M_CTL);
+ free(args, M_CTL);
}
static struct ctl_be_arg *
-ctl_copyin_args(int num_be_args, struct ctl_be_arg *be_args,
+ctl_copyin_args(int num_args, struct ctl_be_arg *uargs,
char *error_str, size_t error_str_len)
{
struct ctl_be_arg *args;
int i;
- args = ctl_copyin_alloc(be_args, num_be_args * sizeof(*be_args),
+ args = ctl_copyin_alloc(uargs, num_args * sizeof(*args),
error_str, error_str_len);
if (args == NULL)
goto bailout;
- for (i = 0; i < num_be_args; i++) {
+ for (i = 0; i < num_args; i++) {
args[i].kname = NULL;
args[i].kvalue = NULL;
}
- for (i = 0; i < num_be_args; i++) {
+ for (i = 0; i < num_args; i++) {
uint8_t *tmpptr;
args[i].kname = ctl_copyin_alloc(args[i].name,
@@ -2060,31 +2060,43 @@ ctl_copyin_args(int num_be_args, struct ctl_be_arg *be_args,
goto bailout;
}
- args[i].kvalue = NULL;
-
- tmpptr = ctl_copyin_alloc(args[i].value,
- args[i].vallen, error_str, error_str_len);
- if (tmpptr == NULL)
- goto bailout;
-
- args[i].kvalue = tmpptr;
-
- if ((args[i].flags & CTL_BEARG_ASCII)
- && (tmpptr[args[i].vallen - 1] != '\0')) {
- snprintf(error_str, error_str_len, "Argument %d "
- "value is not NUL-terminated", i);
- goto bailout;
+ if (args[i].flags & CTL_BEARG_RD) {
+ tmpptr = ctl_copyin_alloc(args[i].value,
+ args[i].vallen, error_str, error_str_len);
+ if (tmpptr == NULL)
+ goto bailout;
+ if ((args[i].flags & CTL_BEARG_ASCII)
+ && (tmpptr[args[i].vallen - 1] != '\0')) {
+ snprintf(error_str, error_str_len, "Argument "
+ "%d value is not NUL-terminated", i);
+ goto bailout;
+ }
+ args[i].kvalue = tmpptr;
+ } else {
+ args[i].kvalue = malloc(args[i].vallen,
+ M_CTL, M_WAITOK | M_ZERO);
}
}
return (args);
bailout:
- ctl_free_args(num_be_args, args);
+ ctl_free_args(num_args, args);
return (NULL);
}
+static void
+ctl_copyout_args(int num_args, struct ctl_be_arg *args)
+{
+ int i;
+
+ for (i = 0; i < num_args; i++) {
+ if (args[i].flags & CTL_BEARG_WR)
+ copyout(args[i].kvalue, args[i].value, args[i].vallen);
+ }
+}
+
/*
* Escape characters that are illegal or not recommended in XML.
*/
@@ -2945,6 +2957,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
retval = backend->ioctl(dev, cmd, addr, flag, td);
if (lun_req->num_be_args > 0) {
+ ctl_copyout_args(lun_req->num_be_args,
+ lun_req->kern_be_args);
ctl_free_args(lun_req->num_be_args,
lun_req->kern_be_args);
}
diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c
index 9178c9d..0e1a76c 100644
--- a/sys/cam/ctl/ctl_backend.c
+++ b/sys/cam/ctl/ctl_backend.c
@@ -181,6 +181,10 @@ ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args)
STAILQ_INIT(opts);
for (i = 0; i < num_args; i++) {
+ if ((args[i].flags & CTL_BEARG_RD) == 0)
+ continue;
+ if ((args[i].flags & CTL_BEARG_ASCII) == 0)
+ continue;
opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
opt->name = malloc(strlen(args[i].kname) + 1, M_CTL, M_WAITOK);
strcpy(opt->name, args[i].kname);
OpenPOWER on IntegriCloud