Commit e2914cc26bbca67fd30fff02c6777e8477fc8a6a
Committed by
Alasdair G Kergon
1 parent
5f01520415
Exists in
master
and in
20 other branches
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>
Showing 1 changed file with 41 additions and 23 deletions Side-by-side Diff
drivers/md/dm-ioctl.c
... | ... | @@ -1478,39 +1478,52 @@ |
1478 | 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 | 1490 | * Implementation of open/close/ioctl on the special char |
1483 | 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 | 1495 | static struct { |
1488 | 1496 | int cmd; |
1497 | + int flags; | |
1489 | 1498 | ioctl_fn fn; |
1490 | 1499 | } _ioctls[] = { |
1491 | - {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ | |
1492 | - {DM_REMOVE_ALL_CMD, remove_all}, | |
1493 | - {DM_LIST_DEVICES_CMD, list_devices}, | |
1500 | + {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */ | |
1501 | + {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all}, | |
1502 | + {DM_LIST_DEVICES_CMD, 0, list_devices}, | |
1494 | 1503 | |
1495 | - {DM_DEV_CREATE_CMD, dev_create}, | |
1496 | - {DM_DEV_REMOVE_CMD, dev_remove}, | |
1497 | - {DM_DEV_RENAME_CMD, dev_rename}, | |
1498 | - {DM_DEV_SUSPEND_CMD, dev_suspend}, | |
1499 | - {DM_DEV_STATUS_CMD, dev_status}, | |
1500 | - {DM_DEV_WAIT_CMD, dev_wait}, | |
1504 | + {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create}, | |
1505 | + {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove}, | |
1506 | + {DM_DEV_RENAME_CMD, 0, dev_rename}, | |
1507 | + {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend}, | |
1508 | + {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status}, | |
1509 | + {DM_DEV_WAIT_CMD, 0, dev_wait}, | |
1501 | 1510 | |
1502 | - {DM_TABLE_LOAD_CMD, table_load}, | |
1503 | - {DM_TABLE_CLEAR_CMD, table_clear}, | |
1504 | - {DM_TABLE_DEPS_CMD, table_deps}, | |
1505 | - {DM_TABLE_STATUS_CMD, table_status}, | |
1511 | + {DM_TABLE_LOAD_CMD, 0, table_load}, | |
1512 | + {DM_TABLE_CLEAR_CMD, IOCTL_FLAGS_NO_PARAMS, table_clear}, | |
1513 | + {DM_TABLE_DEPS_CMD, 0, table_deps}, | |
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}, | |
1510 | - {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} | |
1518 | + {DM_TARGET_MSG_CMD, 0, target_message}, | |
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 @@ |
1652 | 1665 | static int ctl_ioctl(uint command, struct dm_ioctl __user *user) |
1653 | 1666 | { |
1654 | 1667 | int r = 0; |
1668 | + int ioctl_flags; | |
1655 | 1669 | int param_flags; |
1656 | 1670 | unsigned int cmd; |
1657 | 1671 | struct dm_ioctl *uninitialized_var(param); |
... | ... | @@ -1681,7 +1695,7 @@ |
1681 | 1695 | if (cmd == DM_VERSION_CMD) |
1682 | 1696 | return 0; |
1683 | 1697 | |
1684 | - fn = lookup_ioctl(cmd); | |
1698 | + fn = lookup_ioctl(cmd, &ioctl_flags); | |
1685 | 1699 | if (!fn) { |
1686 | 1700 | DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); |
1687 | 1701 | return -ENOTTY; |
... | ... | @@ -1702,6 +1716,10 @@ |
1702 | 1716 | |
1703 | 1717 | param->data_size = sizeof(*param); |
1704 | 1718 | r = fn(param, input_param_size); |
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); | |
1705 | 1723 | |
1706 | 1724 | /* |
1707 | 1725 | * Copy the results back to userland. |