// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2006 * * Author: Artem Bityutskiy (Битюцкий Артём) */ /* * This file includes implementation of UBI character device operations. * * There are two kinds of character devices in UBI: UBI character devices and * UBI volume character devices. UBI character devices allow users to * manipulate whole volumes: create, remove, and re-size them. Volume character * devices provide volume I/O capabilities. * * Major and minor numbers are assigned dynamically to both UBI and volume * character devices. * * Well, there is the third kind of character devices - the UBI control * character device, which allows to manipulate by UBI devices - create and * delete them. In other words, it is used for attaching and detaching MTD * devices. */ #include <linux/module.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/ioctl.h> #include <linux/capability.h> #include <linux/uaccess.h> #include <linux/compat.h> #include <linux/math64.h> #include <mtd/ubi-user.h> #include "ubi.h" /** * get_exclusive - get exclusive access to an UBI volume. * @desc: volume descriptor * * This function changes UBI volume open mode to "exclusive". Returns previous * mode value (positive integer) in case of success and a negative error code * in case of failure. */ static int get_exclusive(struct ubi_volume_desc *desc) { … } /** * revoke_exclusive - revoke exclusive mode. * @desc: volume descriptor * @mode: new mode to switch to */ static void revoke_exclusive(struct ubi_volume_desc *desc, int mode) { … } static int vol_cdev_open(struct inode *inode, struct file *file) { … } static int vol_cdev_release(struct inode *inode, struct file *file) { … } static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) { … } static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync) { … } static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, loff_t *offp) { … } /* * This function allows to directly write to dynamic UBI volumes, without * issuing the volume update operation. */ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *offp) { … } static ssize_t vol_cdev_write(struct file *file, const char __user *buf, size_t count, loff_t *offp) { … } static long vol_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } /** * verify_mkvol_req - verify volume creation request. * @ubi: UBI device description object * @req: the request to check * * This function zero if the request is correct, and %-EINVAL if not. */ static int verify_mkvol_req(const struct ubi_device *ubi, const struct ubi_mkvol_req *req) { … } /** * verify_rsvol_req - verify volume re-size request. * @ubi: UBI device description object * @req: the request to check * * This function returns zero if the request is correct, and %-EINVAL if not. */ static int verify_rsvol_req(const struct ubi_device *ubi, const struct ubi_rsvol_req *req) { … } /** * rename_volumes - rename UBI volumes. * @ubi: UBI device description object * @req: volumes re-name request * * This is a helper function for the volume re-name IOCTL which validates the * request, opens the volume and calls corresponding volumes management * function. Returns zero in case of success and a negative error code in case * of failure. */ static int rename_volumes(struct ubi_device *ubi, struct ubi_rnvol_req *req) { … } static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } /* UBI volume character device operations */ const struct file_operations ubi_vol_cdev_operations = …; /* UBI character device operations */ const struct file_operations ubi_cdev_operations = …; /* UBI control character device operations */ const struct file_operations ubi_ctrl_cdev_operations = …;