Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2914cc2 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Alasdair G Kergon
Browse files

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: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 5f015204
Loading
Loading
Loading
Loading
+41 −23
Original line number Original line Diff line number Diff line
@@ -1478,39 +1478,52 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
	return r;
	return r;
}
}


/*
 * The ioctl parameter block consists of two parts, a dm_ioctl struct
 * followed by a data buffer.  This flag is set if the second part,
 * which has a variable size, is not used by the function processing
 * the ioctl.
 */
#define IOCTL_FLAGS_NO_PARAMS	1

/*-----------------------------------------------------------------
/*-----------------------------------------------------------------
 * Implementation of open/close/ioctl on the special char
 * Implementation of open/close/ioctl on the special char
 * device.
 * device.
 *---------------------------------------------------------------*/
 *---------------------------------------------------------------*/
static ioctl_fn lookup_ioctl(unsigned int cmd)
static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
{
{
	static struct {
	static struct {
		int cmd;
		int cmd;
		int flags;
		ioctl_fn fn;
		ioctl_fn fn;
	} _ioctls[] = {
	} _ioctls[] = {
		{DM_VERSION_CMD, NULL},	/* version is dealt with elsewhere */
		{DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */
		{DM_REMOVE_ALL_CMD, remove_all},
		{DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all},
		{DM_LIST_DEVICES_CMD, list_devices},
		{DM_LIST_DEVICES_CMD, 0, list_devices},


		{DM_DEV_CREATE_CMD, dev_create},
		{DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create},
		{DM_DEV_REMOVE_CMD, dev_remove},
		{DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove},
		{DM_DEV_RENAME_CMD, dev_rename},
		{DM_DEV_RENAME_CMD, 0, dev_rename},
		{DM_DEV_SUSPEND_CMD, dev_suspend},
		{DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend},
		{DM_DEV_STATUS_CMD, dev_status},
		{DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status},
		{DM_DEV_WAIT_CMD, dev_wait},
		{DM_DEV_WAIT_CMD, 0, dev_wait},


		{DM_TABLE_LOAD_CMD, table_load},
		{DM_TABLE_LOAD_CMD, 0, table_load},
		{DM_TABLE_CLEAR_CMD, table_clear},
		{DM_TABLE_CLEAR_CMD, IOCTL_FLAGS_NO_PARAMS, table_clear},
		{DM_TABLE_DEPS_CMD, table_deps},
		{DM_TABLE_DEPS_CMD, 0, table_deps},
		{DM_TABLE_STATUS_CMD, table_status},
		{DM_TABLE_STATUS_CMD, 0, table_status},


		{DM_LIST_VERSIONS_CMD, list_versions},
		{DM_LIST_VERSIONS_CMD, 0, list_versions},


		{DM_TARGET_MSG_CMD, target_message},
		{DM_TARGET_MSG_CMD, 0, target_message},
		{DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
		{DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
	};
	};


	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
	if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
		return NULL;

	*ioctl_flags = _ioctls[cmd].flags;
	return _ioctls[cmd].fn;
}
}


/*
/*
@@ -1652,6 +1665,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
{
{
	int r = 0;
	int r = 0;
	int ioctl_flags;
	int param_flags;
	int param_flags;
	unsigned int cmd;
	unsigned int cmd;
	struct dm_ioctl *uninitialized_var(param);
	struct dm_ioctl *uninitialized_var(param);
@@ -1681,7 +1695,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
	if (cmd == DM_VERSION_CMD)
	if (cmd == DM_VERSION_CMD)
		return 0;
		return 0;


	fn = lookup_ioctl(cmd);
	fn = lookup_ioctl(cmd, &ioctl_flags);
	if (!fn) {
	if (!fn) {
		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
		return -ENOTTY;
		return -ENOTTY;
@@ -1703,6 +1717,10 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
	param->data_size = sizeof(*param);
	param->data_size = sizeof(*param);
	r = fn(param, input_param_size);
	r = fn(param, input_param_size);


	if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
	    unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
		DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd);

	/*
	/*
	 * Copy the results back to userland.
	 * Copy the results back to userland.
	 */
	 */