open-cas-linux/modules/cas_cache/service_ui_ioctl.c
Michal Mielewczyk 0208375202 Unified management functions prefix
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
2019-06-06 09:46:40 -04:00

348 lines
7.7 KiB
C

/*
* Copyright(c) 2012-2019 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "cas_cache.h"
#include "utils/cas_err.h"
#define _GET_CMD_INFO(cmd_info, arg, size) ({ \
cmd_info = vmalloc(size); \
if (!cmd_info) \
return -ENOMEM; \
if (copy_from_user(cmd_info, (void __user *)arg, size)) { \
printk(KERN_ALERT "Cannot copy cmd info from user space\n"); \
vfree(cmd_info); \
return -EINVAL; \
} \
})
#define GET_CMD_INFO(cmd_info, arg) _GET_CMD_INFO(cmd_info, arg, \
sizeof(*cmd_info))
#define RETURN_CMD_RESULT(cmd_info, arg, result) ({ \
int ret = result; \
cmd_info->ext_err_code = abs(result); \
if (copy_to_user((void __user *)arg, cmd_info, sizeof(*cmd_info))) { \
printk(KERN_ALERT "Unable to copy response to user\n"); \
ret = -EFAULT; \
} \
vfree(cmd_info); \
return map_cas_err_to_generic(ret); \
})
/* this handles IOctl for /dev/cas */
/*********************************************/
long cas_service_ioctl_ctrl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int retval = 0;
if (_IOC_TYPE(cmd) != KCAS_IOCTL_MAGIC)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) {
/* Must be root to issue ioctls */
return -EPERM;
}
if (cas_upgrade_is_in_upgrade() &&
cmd != KCAS_IOCTL_CACHE_INFO &&
cmd != KCAS_IOCTL_LIST_CACHE &&
cmd != KCAS_IOCTL_GET_CACHE_COUNT &&
cmd != KCAS_IOCTL_CORE_INFO &&
cmd != KCAS_IOCTL_PARTITION_STATS &&
cmd != KCAS_IOCTL_GET_CAPABILITIES) {
return -EFAULT;
}
switch (cmd) {
case KCAS_IOCTL_START_CACHE: {
struct kcas_start_cache *cmd_info;
struct ocf_mngt_cache_config cfg;
struct ocf_mngt_cache_device_config device_cfg;
struct atomic_dev_params atomic_params = { 0 };
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_prepare_cache_cfg(&cfg, &device_cfg,
&atomic_params, cmd_info);
if (retval)
RETURN_CMD_RESULT(cmd_info, arg, retval);
retval = cache_mngt_init_instance(&cfg, &device_cfg, cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_STOP_CACHE: {
struct kcas_stop_cache *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_exit_instance(cmd_info->cache_id,
cmd_info->flush_data);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_SET_CACHE_STATE: {
struct kcas_set_cache_state *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_set_cache_mode(cmd_info->cache_id,
cmd_info->caching_mode, cmd_info->flush_data);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_INSERT_CORE: {
struct kcas_insert_core *cmd_info;
struct ocf_mngt_core_config cfg;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_prepare_core_cfg(&cfg, cmd_info);
if (retval)
RETURN_CMD_RESULT(cmd_info, arg, retval);
retval = cache_mngt_add_core_to_cache(&cfg, cmd_info->cache_id,
cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_REMOVE_CORE: {
struct kcas_remove_core *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_remove_core_from_cache(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_RESET_STATS: {
struct kcas_reset_stats *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_reset_stats(cmd_info->cache_id,
cmd_info->core_id);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_FLUSH_CACHE: {
struct kcas_flush_cache *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_flush_device(cmd_info->cache_id);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_INTERRUPT_FLUSHING: {
struct kcas_interrupt_flushing *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_interrupt_flushing(cmd_info->cache_id);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_FLUSH_CORE: {
struct kcas_flush_core *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_flush_object(cmd_info->cache_id,
cmd_info->core_id);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_CACHE_INFO: {
struct kcas_cache_info *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_get_info(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_CORE_INFO: {
struct kcas_core_info *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_get_core_info(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_PARTITION_STATS: {
struct kcas_io_class *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_get_io_class_info(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_PARTITION_SET: {
struct kcas_io_classes *cmd_info;
/* copy entire memory from user, including array of
* ocf_io_class_info structs past the end of kcas_io_classes */
_GET_CMD_INFO(cmd_info, arg, KCAS_IO_CLASSES_SIZE);
retval = cache_mngt_set_partitions(cmd_info);
/* return just sizeof(struct kcas_io_classes) bytes of data */
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_GET_CACHE_COUNT: {
struct kcas_cache_count *cmd_info;
GET_CMD_INFO(cmd_info, arg);
cmd_info->cache_count = ocf_mngt_cache_get_count(cas_ctx);
RETURN_CMD_RESULT(cmd_info, arg, 0);
}
case KCAS_IOCTL_LIST_CACHE: {
struct kcas_cache_list *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_list_caches(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval > 0 ? 0 : retval);
}
case KCAS_IOCTL_GET_CAPABILITIES: {
struct kcas_capabilites *cmd_info;
GET_CMD_INFO(cmd_info, arg);
memset(cmd_info, 0, sizeof(*cmd_info));
#ifdef CAS_NVME_FULL
cmd_info->nvme_format = 1;
#endif
RETURN_CMD_RESULT(cmd_info, arg, 0);
}
case KCAS_IOCTL_UPGRADE: {
struct kcas_upgrade *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cas_upgrade();
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
#if defined(CAS_NVME_FULL)
case KCAS_IOCTL_NVME_FORMAT: {
struct kcas_nvme_format *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cas_nvme_format_optimal(
cmd_info->device_path_name,
cmd_info->metadata_mode,
cmd_info->force);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
#endif
case KCAS_IOCTL_GET_CORE_POOL_COUNT: {
struct kcas_core_pool_count *cmd_info;
GET_CMD_INFO(cmd_info, arg);
cmd_info->core_pool_count =
ocf_mngt_core_pool_get_count(cas_ctx);
RETURN_CMD_RESULT(cmd_info, arg, 0);
}
case KCAS_IOCTL_GET_CORE_POOL_PATHS: {
struct kcas_core_pool_path *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_core_pool_get_paths(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_CORE_POOL_REMOVE: {
struct kcas_core_pool_remove *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_core_pool_remove(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_CACHE_CHECK_DEVICE: {
struct kcas_cache_check_device *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_cache_check_device(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_SET_CORE_PARAM: {
struct kcas_set_core_param *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_set_core_params(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_GET_CORE_PARAM: {
struct kcas_get_core_param *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_get_core_params(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_SET_CACHE_PARAM: {
struct kcas_set_cache_param *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_set_cache_params(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
case KCAS_IOCTL_GET_CACHE_PARAM: {
struct kcas_get_cache_param *cmd_info;
GET_CMD_INFO(cmd_info, arg);
retval = cache_mngt_get_cache_params(cmd_info);
RETURN_CMD_RESULT(cmd_info, arg, retval);
}
default:
return -EINVAL;
}
}