diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2013-03-01 17:45:48 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2013-03-01 17:45:48 -0500 |
commit | e2914cc26bbca67fd30fff02c6777e8477fc8a6a (patch) | |
tree | b772ab680661d3bbedd35cbd48e4f19c5ffad854 /drivers/md | |
parent | 5f01520415e82f8e354807484ef842335070a3bd (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.c | 64 |
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 | *---------------------------------------------------------------*/ |
1485 | static ioctl_fn lookup_ioctl(unsigned int cmd) | 1493 | static 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) | |||
1652 | static int ctl_ioctl(uint command, struct dm_ioctl __user *user) | 1665 | static 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 | */ |