aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2013-03-01 17:45:48 -0500
committerAlasdair G Kergon <agk@redhat.com>2013-03-01 17:45:48 -0500
commite2914cc26bbca67fd30fff02c6777e8477fc8a6a (patch)
treeb772ab680661d3bbedd35cbd48e4f19c5ffad854 /drivers/md
parent5f01520415e82f8e354807484ef842335070a3bd (diff)
dm ioctl: introduce ioctl_flags
This patch introduces flags for each ioctl function. So far, one flag is defined, IOCTL_FLAGS_NO_PARAMS. It is set if the function processing the ioctl doesn't take or produce any parameters in the section of the data buffer that has a variable size. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-ioctl.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index eee353da3742..9ae11b2994f8 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1478,39 +1478,52 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
1478 return r; 1478 return r;
1479} 1479}
1480 1480
1481/*
1482 * The ioctl parameter block consists of two parts, a dm_ioctl struct
1483 * followed by a data buffer. This flag is set if the second part,
1484 * which has a variable size, is not used by the function processing
1485 * the ioctl.
1486 */
1487#define IOCTL_FLAGS_NO_PARAMS 1
1488
1481/*----------------------------------------------------------------- 1489/*-----------------------------------------------------------------
1482 * Implementation of open/close/ioctl on the special char 1490 * Implementation of open/close/ioctl on the special char
1483 * device. 1491 * device.
1484 *---------------------------------------------------------------*/ 1492 *---------------------------------------------------------------*/
1485static ioctl_fn lookup_ioctl(unsigned int cmd) 1493static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
1486{ 1494{
1487 static struct { 1495 static struct {
1488 int cmd; 1496 int cmd;
1497 int flags;
1489 ioctl_fn fn; 1498 ioctl_fn fn;
1490 } _ioctls[] = { 1499 } _ioctls[] = {
1491 {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ 1500 {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */
1492 {DM_REMOVE_ALL_CMD, remove_all}, 1501 {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all},
1493 {DM_LIST_DEVICES_CMD, list_devices}, 1502 {DM_LIST_DEVICES_CMD, 0, list_devices},
1494 1503
1495 {DM_DEV_CREATE_CMD, dev_create}, 1504 {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create},
1496 {DM_DEV_REMOVE_CMD, dev_remove}, 1505 {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove},
1497 {DM_DEV_RENAME_CMD, dev_rename}, 1506 {DM_DEV_RENAME_CMD, 0, dev_rename},
1498 {DM_DEV_SUSPEND_CMD, dev_suspend}, 1507 {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend},
1499 {DM_DEV_STATUS_CMD, dev_status}, 1508 {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status},
1500 {DM_DEV_WAIT_CMD, dev_wait}, 1509 {DM_DEV_WAIT_CMD, 0, dev_wait},
1501 1510
1502 {DM_TABLE_LOAD_CMD, table_load}, 1511 {DM_TABLE_LOAD_CMD, 0, table_load},
1503 {DM_TABLE_CLEAR_CMD, table_clear}, 1512 {DM_TABLE_CLEAR_CMD, IOCTL_FLAGS_NO_PARAMS, table_clear},
1504 {DM_TABLE_DEPS_CMD, table_deps}, 1513 {DM_TABLE_DEPS_CMD, 0, table_deps},
1505 {DM_TABLE_STATUS_CMD, table_status}, 1514 {DM_TABLE_STATUS_CMD, 0, table_status},
1506 1515
1507 {DM_LIST_VERSIONS_CMD, list_versions}, 1516 {DM_LIST_VERSIONS_CMD, 0, list_versions},
1508 1517
1509 {DM_TARGET_MSG_CMD, target_message}, 1518 {DM_TARGET_MSG_CMD, 0, target_message},
1510 {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} 1519 {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
1511 }; 1520 };
1512 1521
1513 return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; 1522 if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
1523 return NULL;
1524
1525 *ioctl_flags = _ioctls[cmd].flags;
1526 return _ioctls[cmd].fn;
1514} 1527}
1515 1528
1516/* 1529/*
@@ -1652,6 +1665,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
1652static int ctl_ioctl(uint command, struct dm_ioctl __user *user) 1665static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
1653{ 1666{
1654 int r = 0; 1667 int r = 0;
1668 int ioctl_flags;
1655 int param_flags; 1669 int param_flags;
1656 unsigned int cmd; 1670 unsigned int cmd;
1657 struct dm_ioctl *uninitialized_var(param); 1671 struct dm_ioctl *uninitialized_var(param);
@@ -1681,7 +1695,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
1681 if (cmd == DM_VERSION_CMD) 1695 if (cmd == DM_VERSION_CMD)
1682 return 0; 1696 return 0;
1683 1697
1684 fn = lookup_ioctl(cmd); 1698 fn = lookup_ioctl(cmd, &ioctl_flags);
1685 if (!fn) { 1699 if (!fn) {
1686 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); 1700 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
1687 return -ENOTTY; 1701 return -ENOTTY;
@@ -1703,6 +1717,10 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
1703 param->data_size = sizeof(*param); 1717 param->data_size = sizeof(*param);
1704 r = fn(param, input_param_size); 1718 r = fn(param, input_param_size);
1705 1719
1720 if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
1721 unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
1722 DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd);
1723
1706 /* 1724 /*
1707 * Copy the results back to userland. 1725 * Copy the results back to userland.
1708 */ 1726 */