Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright (c) International Business Machines Corp., 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Author: Artem Bityutskiy (Битюцкий Артём)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * This file includes implementation of UBI character device operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * There are two kinds of character devices in UBI: UBI character devices and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * UBI volume character devices. UBI character devices allow users to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * manipulate whole volumes: create, remove, and re-size them. Volume character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * devices provide volume I/O capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Major and minor numbers are assigned dynamically to both UBI and volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * character devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * Well, there is the third kind of character devices - the UBI control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * character device, which allows to manipulate by UBI devices - create and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * delete them. In other words, it is used for attaching and detaching MTD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <mtd/ubi-user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "ubi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * get_exclusive - get exclusive access to an UBI volume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * @desc: volume descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * This function changes UBI volume open mode to "exclusive". Returns previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * mode value (positive integer) in case of success and a negative error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) static int get_exclusive(struct ubi_volume_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	int users, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	spin_lock(&vol->ubi->volumes_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	users = vol->readers + vol->writers + vol->exclusive + vol->metaonly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	ubi_assert(users > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	if (users > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 		ubi_err(vol->ubi, "%d users for volume %d", users, vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 		err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		vol->readers = vol->writers = vol->metaonly = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 		vol->exclusive = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		err = desc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		desc->mode = UBI_EXCLUSIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	spin_unlock(&vol->ubi->volumes_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  * revoke_exclusive - revoke exclusive mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  * @desc: volume descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  * @mode: new mode to switch to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	spin_lock(&vol->ubi->volumes_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	ubi_assert(vol->readers == 0 && vol->writers == 0 && vol->metaonly == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	vol->exclusive = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	if (mode == UBI_READONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		vol->readers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	else if (mode == UBI_READWRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		vol->writers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	else if (mode == UBI_METAONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		vol->metaonly = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		vol->exclusive = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	spin_unlock(&vol->ubi->volumes_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	desc->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) static int vol_cdev_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	struct ubi_volume_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	int vol_id = iminor(inode) - 1, mode, ubi_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	ubi_num = ubi_major2num(imajor(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	if (ubi_num < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		return ubi_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	if (file->f_mode & FMODE_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		mode = UBI_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		mode = UBI_READONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	dbg_gen("open device %d, volume %d, mode %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		ubi_num, vol_id, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	desc = ubi_open_volume(ubi_num, vol_id, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	if (IS_ERR(desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		return PTR_ERR(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	file->private_data = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) static int vol_cdev_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	dbg_gen("release device %d, volume %d, mode %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		vol->ubi->ubi_num, vol->vol_id, desc->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	if (vol->updating) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		ubi_warn(vol->ubi, "update of volume %d not finished, volume is damaged",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 			 vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		ubi_assert(!vol->changing_leb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		vol->updating = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		vfree(vol->upd_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	} else if (vol->changing_leb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 			vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		vol->changing_leb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 		vfree(vol->upd_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	ubi_close_volume(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	if (vol->updating) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		/* Update is in progress, seeking is prohibited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		ubi_err(vol->ubi, "updating");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	return fixed_size_llseek(file, offset, origin, vol->used_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			  int datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	struct ubi_device *ubi = desc->vol->ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	err = ubi_sync(ubi->ubi_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 			     loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct ubi_device *ubi = vol->ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	int err, lnum, off, len,  tbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	size_t count_save = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	void *tbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	dbg_gen("read %zd bytes from offset %lld of volume %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		count, *offp, vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	if (vol->updating) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		ubi_err(vol->ubi, "updating");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	if (vol->upd_marker) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		ubi_err(vol->ubi, "damaged volume, update marker is set");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	if (*offp == vol->used_bytes || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	if (vol->corrupted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		dbg_gen("read from corrupted volume %d", vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	if (*offp + count > vol->used_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		count_save = count = vol->used_bytes - *offp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	tbuf_size = vol->usable_leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	if (count < tbuf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		tbuf_size = ALIGN(count, ubi->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	tbuf = vmalloc(tbuf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	if (!tbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	len = count > tbuf_size ? tbuf_size : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		if (off + len >= vol->usable_leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			len = vol->usable_leb_size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		off += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		if (off == vol->usable_leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			lnum += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			off -= vol->usable_leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		count -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		*offp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		err = copy_to_user(buf, tbuf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		buf += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		len = count > tbuf_size ? tbuf_size : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	} while (count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	vfree(tbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	return err ? err : count_save - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  * This function allows to directly write to dynamic UBI volumes, without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  * issuing the volume update operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 				     size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	struct ubi_device *ubi = vol->ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int lnum, off, len, tbuf_size, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	size_t count_save = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	char *tbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (!vol->direct_writes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		count, *offp, vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	if (vol->vol_type == UBI_STATIC_VOLUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		return -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	if (off & (ubi->min_io_size - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		ubi_err(ubi, "unaligned position");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	if (*offp + count > vol->used_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		count_save = count = vol->used_bytes - *offp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	/* We can write only in fractions of the minimum I/O unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (count & (ubi->min_io_size - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		ubi_err(ubi, "unaligned write length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	tbuf_size = vol->usable_leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	if (count < tbuf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		tbuf_size = ALIGN(count, ubi->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	tbuf = vmalloc(tbuf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	if (!tbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	len = count > tbuf_size ? tbuf_size : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		if (off + len >= vol->usable_leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 			len = vol->usable_leb_size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		err = copy_from_user(tbuf, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		off += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		if (off == vol->usable_leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 			lnum += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			off -= vol->usable_leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		count -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		*offp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		buf += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		len = count > tbuf_size ? tbuf_size : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	vfree(tbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	return err ? err : count_save - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			      size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	struct ubi_device *ubi = vol->ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	if (!vol->updating && !vol->changing_leb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		return vol_cdev_direct_write(file, buf, count, offp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if (vol->updating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		err = ubi_more_update_data(ubi, vol, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		err = ubi_more_leb_change_data(ubi, vol, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		ubi_err(ubi, "cannot accept more %zd bytes of data, error %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			count, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		 * The operation is finished, @err contains number of actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		 * written bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		count = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		if (vol->changing_leb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			revoke_exclusive(desc, UBI_READWRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		 * We voluntarily do not take into account the skip_check flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		 * as we want to make sure what we wrote was correctly written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		err = ubi_check_volume(ubi, vol->vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			ubi_warn(ubi, "volume %d on UBI device %d is corrupted",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 				 vol->vol_id, ubi->ubi_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			vol->corrupted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		vol->checked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		revoke_exclusive(desc, UBI_READWRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 			   unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	struct ubi_volume_desc *desc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	struct ubi_volume *vol = desc->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	struct ubi_device *ubi = vol->ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	/* Volume update command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	case UBI_IOCVOLUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		int64_t bytes, rsvd_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		if (!capable(CAP_SYS_RESOURCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 			err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		err = copy_from_user(&bytes, argp, sizeof(int64_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		if (desc->mode == UBI_READONLY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			err = -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		rsvd_bytes = (long long)vol->reserved_pebs *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 					vol->usable_leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		if (bytes < 0 || bytes > rsvd_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		err = get_exclusive(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		err = ubi_start_update(ubi, vol, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		if (bytes == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			revoke_exclusive(desc, UBI_READWRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	/* Atomic logical eraseblock change command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	case UBI_IOCEBCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		struct ubi_leb_change_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		err = copy_from_user(&req, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				     sizeof(struct ubi_leb_change_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		if (desc->mode == UBI_READONLY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		    vol->vol_type == UBI_STATIC_VOLUME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			err = -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		/* Validate the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		if (!ubi_leb_valid(vol, req.lnum) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		    req.bytes < 0 || req.bytes > vol->usable_leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		err = get_exclusive(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		err = ubi_start_leb_change(ubi, vol, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		if (req.bytes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			revoke_exclusive(desc, UBI_READWRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	/* Logical eraseblock erasure command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	case UBI_IOCEBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		int32_t lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		err = get_user(lnum, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		if (desc->mode == UBI_READONLY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		    vol->vol_type == UBI_STATIC_VOLUME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			err = -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		if (!ubi_leb_valid(vol, lnum)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		dbg_gen("erase LEB %d:%d", vol->vol_id, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		err = ubi_eba_unmap_leb(ubi, vol, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	/* Logical eraseblock map command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	case UBI_IOCEBMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		struct ubi_map_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		err = copy_from_user(&req, argp, sizeof(struct ubi_map_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		err = ubi_leb_map(desc, req.lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	/* Logical eraseblock un-map command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	case UBI_IOCEBUNMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		int32_t lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		err = get_user(lnum, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		err = ubi_leb_unmap(desc, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	/* Check if logical eraseblock is mapped command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	case UBI_IOCEBISMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		int32_t lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		err = get_user(lnum, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		err = ubi_is_mapped(desc, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	/* Set volume property command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	case UBI_IOCSETVOLPROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		struct ubi_set_vol_prop_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		err = copy_from_user(&req, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 				     sizeof(struct ubi_set_vol_prop_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		switch (req.property) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		case UBI_VOL_PROP_DIRECT_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			mutex_lock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			desc->vol->direct_writes = !!req.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			mutex_unlock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	/* Create a R/O block device on top of the UBI volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	case UBI_IOCVOLCRBLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		struct ubi_volume_info vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		ubi_get_volume_info(desc, &vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		err = ubiblock_create(&vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* Remove the R/O block device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	case UBI_IOCVOLRMBLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		struct ubi_volume_info vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		ubi_get_volume_info(desc, &vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		err = ubiblock_remove(&vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587)  * verify_mkvol_req - verify volume creation request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)  * @ubi: UBI device description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  * @req: the request to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591)  * This function zero if the request is correct, and %-EINVAL if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) static int verify_mkvol_req(const struct ubi_device *ubi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 			    const struct ubi_mkvol_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	int n, err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	    req->name_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	if ((req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	    req->vol_id != UBI_VOL_NUM_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	if (req->alignment == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (req->bytes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	if (req->vol_type != UBI_DYNAMIC_VOLUME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	    req->vol_type != UBI_STATIC_VOLUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (req->flags & ~UBI_VOL_VALID_FLGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	    req->vol_type != UBI_STATIC_VOLUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	if (req->alignment > ubi->leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	n = req->alignment & (ubi->min_io_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	if (req->alignment != 1 && n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (!req->name[0] || !req->name_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	if (req->name_len > UBI_VOL_NAME_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		err = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	n = strnlen(req->name, req->name_len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	if (n != req->name_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	ubi_err(ubi, "bad volume creation request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	ubi_dump_mkvol_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651)  * verify_rsvol_req - verify volume re-size request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652)  * @ubi: UBI device description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653)  * @req: the request to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * This function returns zero if the request is correct, and %-EINVAL if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static int verify_rsvol_req(const struct ubi_device *ubi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			    const struct ubi_rsvol_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	if (req->bytes <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if (req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  * rename_volumes - rename UBI volumes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)  * @ubi: UBI device description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)  * @req: volumes re-name request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)  * This is a helper function for the volume re-name IOCTL which validates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * the request, opens the volume and calls corresponding volumes management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * function. Returns zero in case of success and a negative error code in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  * of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) static int rename_volumes(struct ubi_device *ubi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			  struct ubi_rnvol_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	int i, n, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	struct list_head rename_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	struct ubi_rename_entry *re, *re1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	if (req->count < 0 || req->count > UBI_MAX_RNVOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	if (req->count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	/* Validate volume IDs and names in the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	for (i = 0; i < req->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		if (req->ents[i].vol_id < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		    req->ents[i].vol_id >= ubi->vtbl_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		if (req->ents[i].name_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		if (req->ents[i].name_len > UBI_VOL_NAME_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		req->ents[i].name[req->ents[i].name_len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		n = strlen(req->ents[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		if (n != req->ents[i].name_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	/* Make sure volume IDs and names are unique */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	for (i = 0; i < req->count - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		for (n = i + 1; n < req->count; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			if (req->ents[i].vol_id == req->ents[n].vol_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				ubi_err(ubi, "duplicated volume id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 					req->ents[i].vol_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			if (!strcmp(req->ents[i].name, req->ents[n].name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 				ubi_err(ubi, "duplicated volume name \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 					req->ents[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	/* Create the re-name list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	INIT_LIST_HEAD(&rename_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	for (i = 0; i < req->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		int vol_id = req->ents[i].vol_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		int name_len = req->ents[i].name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		const char *name = req->ents[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		if (!re) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_METAONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		if (IS_ERR(re->desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			err = PTR_ERR(re->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			ubi_err(ubi, "cannot open volume %d, error %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 				vol_id, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			kfree(re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		/* Skip this re-naming if the name does not really change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		if (re->desc->vol->name_len == name_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		    !memcmp(re->desc->vol->name, name, name_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			ubi_close_volume(re->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			kfree(re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		re->new_name_len = name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		memcpy(re->new_name, name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		list_add_tail(&re->list, &rename_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		dbg_gen("will rename volume %d from \"%s\" to \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			vol_id, re->desc->vol->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	if (list_empty(&rename_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	/* Find out the volumes which have to be removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	list_for_each_entry(re, &rename_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		struct ubi_volume_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		int no_remove_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		 * Volume @re->vol_id is going to be re-named to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		 * @re->new_name, while its current name is @name. If a volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		 * with name @re->new_name currently exists, it has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		 * removed, unless it is also re-named in the request (@req).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		list_for_each_entry(re1, &rename_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			if (re->new_name_len == re1->desc->vol->name_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			    !memcmp(re->new_name, re1->desc->vol->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				    re1->desc->vol->name_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				no_remove_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		if (no_remove_needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		 * It seems we need to remove volume with name @re->new_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		 * if it exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 					  UBI_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		if (IS_ERR(desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			err = PTR_ERR(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			if (err == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 				/* Re-naming into a non-existing volume name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			/* The volume exists but busy, or an error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			ubi_err(ubi, "cannot open volume \"%s\", error %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				re->new_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		if (!re1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 			ubi_close_volume(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		re1->remove = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		re1->desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		list_add(&re1->list, &rename_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		dbg_gen("will remove volume %d, name \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			re1->desc->vol->vol_id, re1->desc->vol->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	mutex_lock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	err = ubi_rename_volumes(ubi, &rename_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	mutex_unlock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	list_for_each_entry_safe(re, re1, &rename_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		ubi_close_volume(re->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		list_del(&re->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		kfree(re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			   unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	struct ubi_device *ubi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	struct ubi_volume_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	ubi = ubi_get_by_major(imajor(file->f_mapping->host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	if (!ubi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	/* Create volume command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	case UBI_IOCMKVOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		struct ubi_mkvol_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		dbg_gen("create volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		err = copy_from_user(&req, argp, sizeof(struct ubi_mkvol_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		err = verify_mkvol_req(ubi, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		mutex_lock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		err = ubi_create_volume(ubi, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		mutex_unlock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		err = put_user(req.vol_id, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	/* Remove volume command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	case UBI_IOCRMVOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		int vol_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		dbg_gen("remove volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		err = get_user(vol_id, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		if (IS_ERR(desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			err = PTR_ERR(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		mutex_lock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		err = ubi_remove_volume(desc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		mutex_unlock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		 * The volume is deleted (unless an error occurred), and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		 * 'struct ubi_volume' object will be freed when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		 * 'ubi_close_volume()' will call 'put_device()'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		ubi_close_volume(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	/* Re-size volume command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	case UBI_IOCRSVOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		int pebs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		struct ubi_rsvol_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		dbg_gen("re-size volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		err = copy_from_user(&req, argp, sizeof(struct ubi_rsvol_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		err = verify_rsvol_req(ubi, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		desc = ubi_open_volume(ubi->ubi_num, req.vol_id, UBI_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		if (IS_ERR(desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			err = PTR_ERR(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			       desc->vol->usable_leb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		mutex_lock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		err = ubi_resize_volume(desc, pebs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		mutex_unlock(&ubi->device_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		ubi_close_volume(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	/* Re-name volumes command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	case UBI_IOCRNVOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		struct ubi_rnvol_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		dbg_gen("re-name volumes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		err = copy_from_user(req, argp, sizeof(struct ubi_rnvol_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		err = rename_volumes(ubi, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	/* Check a specific PEB for bitflips and scrub it if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	case UBI_IOCRPEB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		int pnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		err = get_user(pnum, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		err = ubi_bitflip_check(ubi, pnum, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	/* Force scrubbing for a specific PEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	case UBI_IOCSPEB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		int pnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		err = get_user(pnum, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		err = ubi_bitflip_check(ubi, pnum, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	ubi_put_device(ubi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 			    unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	/* Attach an MTD device command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	case UBI_IOCATT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		struct ubi_attach_req req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		struct mtd_info *mtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		dbg_gen("attach MTD device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		err = copy_from_user(&req, argp, sizeof(struct ubi_attach_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		if (req.mtd_num < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		    (req.ubi_num < 0 && req.ubi_num != UBI_DEV_NUM_AUTO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		mtd = get_mtd_device(NULL, req.mtd_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		if (IS_ERR(mtd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			err = PTR_ERR(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		 * Note, further request verification is done by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		 * 'ubi_attach_mtd_dev()'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		mutex_lock(&ubi_devices_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 					 req.max_beb_per1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		mutex_unlock(&ubi_devices_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			put_mtd_device(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			/* @err contains UBI device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			err = put_user(err, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	/* Detach an MTD device command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	case UBI_IOCDET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		int ubi_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		dbg_gen("detach MTD device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		err = get_user(ubi_num, (__user int32_t *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		mutex_lock(&ubi_devices_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		err = ubi_detach_mtd_dev(ubi_num, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		mutex_unlock(&ubi_devices_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* UBI volume character device operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) const struct file_operations ubi_vol_cdev_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	.owner          = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	.open           = vol_cdev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	.release        = vol_cdev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	.llseek         = vol_cdev_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	.read           = vol_cdev_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	.write          = vol_cdev_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	.fsync		= vol_cdev_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	.unlocked_ioctl = vol_cdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	.compat_ioctl   = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /* UBI character device operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const struct file_operations ubi_cdev_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	.owner          = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	.llseek         = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	.unlocked_ioctl = ubi_cdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	.compat_ioctl   = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* UBI control character device operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) const struct file_operations ubi_ctrl_cdev_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	.owner          = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	.unlocked_ioctl = ctrl_cdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	.compat_ioctl   = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	.llseek		= no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) };