diff options
Diffstat (limited to 'kernel/xloop_file_fmt.c')
| -rw-r--r-- | kernel/xloop_file_fmt.c | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/kernel/xloop_file_fmt.c b/kernel/xloop_file_fmt.c deleted file mode 100644 index 6c4902f..0000000 --- a/kernel/xloop_file_fmt.c +++ /dev/null @@ -1,356 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * xloop_file_fmt.c - * - * File format subsystem for the xloop device module. - * - * Copyright (C) 2019 Manuel Bentele <development@manuel-bentele.de> - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include <linux/module.h> - -#include "xloop_file_fmt.h" -#include "xloop_main.h" - -/* storage for all registered file format drivers */ -static struct xloop_file_fmt_driver *xloop_file_fmt_drivers[MAX_XLO_FILE_FMT] = { - NULL -}; - -int xloop_file_fmt_register_driver(struct xloop_file_fmt_driver *drv) -{ - int ret = 0; - - if (drv == NULL) - return -EFAULT; - - if (drv->file_fmt_type > MAX_XLO_FILE_FMT) - return -EINVAL; - - if (xloop_file_fmt_drivers[drv->file_fmt_type] == NULL) { - xloop_file_fmt_drivers[drv->file_fmt_type] = drv; - pr_info("successfully registered file format driver %s\n", drv->name); - } else { - pr_warn("driver for file format already registered\n"); - ret = -EBUSY; - } - - return ret; -} -EXPORT_SYMBOL(xloop_file_fmt_register_driver); - -void xloop_file_fmt_unregister_driver(struct xloop_file_fmt_driver *drv) -{ - if (drv == NULL) - return; - - if (drv->file_fmt_type > MAX_XLO_FILE_FMT) - return; - - xloop_file_fmt_drivers[drv->file_fmt_type] = NULL; - pr_info("successfully unregistered file format driver %s\n", drv->name); -} -EXPORT_SYMBOL(xloop_file_fmt_unregister_driver); - -struct xloop_file_fmt *xloop_file_fmt_alloc(void) -{ - return kzalloc(sizeof(struct xloop_file_fmt), GFP_KERNEL); -} - -void xloop_file_fmt_free(struct xloop_file_fmt *xlo_fmt) -{ - kfree(xlo_fmt); -} - -int xloop_file_fmt_set_xlo(struct xloop_file_fmt *xlo_fmt, struct xloop_device *xlo) -{ - if (xlo_fmt == NULL) - return -EINVAL; - - xlo_fmt->xlo = xlo; - - return 0; -} -EXPORT_SYMBOL(xloop_file_fmt_set_xlo); - -struct xloop_device *xloop_file_fmt_get_xlo(struct xloop_file_fmt *xlo_fmt) -{ - return xlo_fmt->xlo; -} -EXPORT_SYMBOL(xloop_file_fmt_get_xlo); - -struct device *xloop_file_fmt_to_dev(struct xloop_file_fmt *xlo_fmt) -{ - struct xloop_device *xlo = xloop_file_fmt_get_xlo(xlo_fmt); - return xloop_device_to_dev(xlo); -} -EXPORT_SYMBOL(xloop_file_fmt_to_dev); - -int xloop_file_fmt_init(struct xloop_file_fmt *xlo_fmt, - u32 file_fmt_type) -{ - struct xloop_file_fmt_ops *ops; - struct module *drv; - int ret = 0; - - if (file_fmt_type > MAX_XLO_FILE_FMT) - return -EINVAL; - - xlo_fmt->file_fmt_type = file_fmt_type; - - if (xlo_fmt->file_fmt_state != file_fmt_uninitialized) { - dev_warn(xloop_file_fmt_to_dev(xlo_fmt), "file format is " - "initialized already\n"); - return -EINVAL; - } - - /* check if new file format driver is registered */ - if (xloop_file_fmt_drivers[xlo_fmt->file_fmt_type] == NULL) { - dev_err(xloop_file_fmt_to_dev(xlo_fmt), "file format driver is " - "not available\n"); - return -ENODEV; - } - - dev_info(xloop_file_fmt_to_dev(xlo_fmt), "use file format driver %s\n", - xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->name); - - drv = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->owner; - if (!try_module_get(drv)) { - dev_err(xloop_file_fmt_to_dev(xlo_fmt), "file format driver %s can " - "not be accessed\n", - xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->name); - return -ENODEV; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->init)) { - ret = ops->init(xlo_fmt); - if (ret < 0) - goto free_drv; - } - - /* after increasing the refcount of file format driver module and - * the successful initialization, the file format is initialized */ - xlo_fmt->file_fmt_state = file_fmt_initialized; - - return ret; - -free_drv: - module_put(drv); - xlo_fmt->file_fmt_state = file_fmt_uninitialized; - return ret; -} - -void xloop_file_fmt_exit(struct xloop_file_fmt *xlo_fmt) -{ - struct xloop_file_fmt_ops *ops; - struct module *drv; - - if (xlo_fmt->file_fmt_state != file_fmt_initialized) { - dev_warn(xloop_file_fmt_to_dev(xlo_fmt), "file format is " - "uninitialized already\n"); - return; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->exit)) - ops->exit(xlo_fmt); - - drv = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->owner; - module_put(drv); - - /* after decreasing the refcount of file format driver module, - * the file format is uninitialized */ - xlo_fmt->file_fmt_state = file_fmt_uninitialized; -} - -int xloop_file_fmt_read(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not read\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->read)) - return ops->read(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_read_aio(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not read aio\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->read_aio)) - return ops->read_aio(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_write(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not write\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->write)) - return ops->write(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_write_aio(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not write aio\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->write_aio)) - return ops->write_aio(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_write_zeros(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not write zeros\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->write_zeros)) - return ops->write_zeros(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_discard(struct xloop_file_fmt *xlo_fmt, - struct request *rq) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not discard\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->discard)) - return ops->discard(xlo_fmt, rq); - else - return -EIO; -} - -int xloop_file_fmt_flush(struct xloop_file_fmt *xlo_fmt) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not flush\n"); - return -EINVAL; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->flush)) - return ops->flush(xlo_fmt); - - return 0; -} - -loff_t xloop_file_fmt_sector_size(struct xloop_file_fmt *xlo_fmt, - struct file *file, loff_t offset, loff_t sizelimit) -{ - struct xloop_file_fmt_ops *ops; - - if (unlikely(xlo_fmt->file_fmt_state != file_fmt_initialized)) { - dev_err_ratelimited(xloop_file_fmt_to_dev(xlo_fmt), "file format " - "is not initialized, can not read sector size\n"); - return 0; - } - - ops = xloop_file_fmt_drivers[xlo_fmt->file_fmt_type]->ops; - if (likely(ops->sector_size)) - return ops->sector_size(xlo_fmt, file, offset, sizelimit); - else - return 0; -} - -int xloop_file_fmt_change(struct xloop_file_fmt *xlo_fmt, - u32 file_fmt_type_new) -{ - if (file_fmt_type_new > MAX_XLO_FILE_FMT) - return -EINVAL; - - dev_info(xloop_file_fmt_to_dev(xlo_fmt), "change file format\n"); - - /* Unload the old file format driver if the file format is - * initialized */ - if (xlo_fmt->file_fmt_state == file_fmt_initialized) - xloop_file_fmt_exit(xlo_fmt); - - /* Load the new file format driver because the file format is - * uninitialized now */ - return xloop_file_fmt_init(xlo_fmt, file_fmt_type_new); -} - -ssize_t xloop_file_fmt_print_type(u32 file_fmt_type, char *file_fmt_name) -{ - ssize_t len = 0; - - switch (file_fmt_type) { - case XLO_FILE_FMT_RAW: - len = sprintf(file_fmt_name, "%s", "RAW"); - break; - case XLO_FILE_FMT_QCOW: - len = sprintf(file_fmt_name, "%s", "QCOW"); - break; - case XLO_FILE_FMT_VDI: - len = sprintf(file_fmt_name, "%s", "VDI"); - break; - case XLO_FILE_FMT_VMDK: - len = sprintf(file_fmt_name, "%s", "VMDK"); - break; - default: - len = sprintf(file_fmt_name, "%s", "ERROR: Unsupported xloop " - "file format!"); - break; - } - - return len; -} -EXPORT_SYMBOL(xloop_file_fmt_print_type); |
