History

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.

Mikulas Patocka committed 13 years ago

Commit e2914cc1 parent 5f015201 file · +41 −23Browse files

Unified · Split

drivers/md/dm-ioctl.c+41−23
@@ -1478,39 +1478,52 @@ static int target_message(struct dm_ioctl *param, size_t param_size) · 1477 unmodified lines
14781478 return r;
14791479 }
14801480
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+
14811489 /*-----------------------------------------------------------------
14821490 * Implementation of open/close/ioctl on the special char
14831491 * device.
14841492 *---------------------------------------------------------------*/
1485−static ioctl_fn lookup_ioctl(unsigned int cmd)
1493+static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
14861494 {
14871495 static struct {
14881496 int cmd;
1497+ int flags;
14891498 ioctl_fn fn;
14901499 } _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},
1494−
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},
1501−
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},
1506−
1507− {DM_LIST_VERSIONS_CMD, list_versions},
1508−
1509− {DM_TARGET_MSG_CMD, target_message},
1510− {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
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},
1503+
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},
1510+
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},
1515+
1516+ {DM_LIST_VERSIONS_CMD, 0, list_versions},
1517+
1518+ {DM_TARGET_MSG_CMD, 0, target_message},
1519+ {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
15111520 };
15121521
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;
15141527 }
15151528
15161529 /*
@@ -1652,6 +1665,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param) · 135 unmodified lines
16521665 static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
16531666 {
16541667 int r = 0;
1668+ int ioctl_flags;
16551669 int param_flags;
16561670 unsigned int cmd;
16571671 struct dm_ioctl *uninitialized_var(param);
@@ -1681,7 +1695,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) · 23 unmodified lines
16811695 if (cmd == DM_VERSION_CMD)
16821696 return 0;
16831697
1684− fn = lookup_ioctl(cmd);
1698+ fn = lookup_ioctl(cmd, &ioctl_flags);
16851699 if (!fn) {
16861700 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
16871701 return -ENOTTY;
@@ -1703,6 +1717,10 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) · 15 unmodified lines
17031717 param->data_size = sizeof(*param);
17041718 r = fn(param, input_param_size);
17051719
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+
17061724 /*
17071725 * Copy the results back to userland.
17081726 */