// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2006 * Copyright (c) Nokia Corporation, 2006 * * Author: Artem Bityutskiy (Битюцкий Артём) * * Jan 2007: Alexander Schmidt, hacked per-volume update. */ /* * This file contains implementation of the volume update and atomic LEB change * functionality. * * The update operation is based on the per-volume update marker which is * stored in the volume table. The update marker is set before the update * starts, and removed after the update has been finished. So if the update was * interrupted by an unclean re-boot or due to some other reasons, the update * marker stays on the flash media and UBI finds it when it attaches the MTD * device next time. If the update marker is set for a volume, the volume is * treated as damaged and most I/O operations are prohibited. Only a new update * operation is allowed. * * Note, in general it is possible to implement the update operation as a * transaction with a roll-back capability. */ #include <linux/err.h> #include <linux/uaccess.h> #include <linux/math64.h> #include "ubi.h" /** * set_update_marker - set update marker. * @ubi: UBI device description object * @vol: volume description object * * This function sets the update marker flag for volume @vol. Returns zero * in case of success and a negative error code in case of failure. */ static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol) { … } /** * clear_update_marker - clear update marker. * @ubi: UBI device description object * @vol: volume description object * @bytes: new data size in bytes * * This function clears the update marker for volume @vol, sets new volume * data size and clears the "corrupted" flag (static volumes only). Returns * zero in case of success and a negative error code in case of failure. */ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, long long bytes) { … } /** * ubi_start_update - start volume update. * @ubi: UBI device description object * @vol: volume description object * @bytes: update bytes * * This function starts volume update operation. If @bytes is zero, the volume * is just wiped out. Returns zero in case of success and a negative error code * in case of failure. */ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, long long bytes) { … } /** * ubi_start_leb_change - start atomic LEB change. * @ubi: UBI device description object * @vol: volume description object * @req: operation request * * This function starts atomic LEB change operation. Returns zero in case of * success and a negative error code in case of failure. */ int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, const struct ubi_leb_change_req *req) { … } /** * write_leb - write update data. * @ubi: UBI device description object * @vol: volume description object * @lnum: logical eraseblock number * @buf: data to write * @len: data size * @used_ebs: how many logical eraseblocks will this volume contain (static * volumes only) * * This function writes update data to corresponding logical eraseblock. In * case of dynamic volume, this function checks if the data contains 0xFF bytes * at the end. If yes, the 0xFF bytes are cut and not written. So if the whole * buffer contains only 0xFF bytes, the LEB is left unmapped. * * The reason why we skip the trailing 0xFF bytes in case of dynamic volume is * that we want to make sure that more data may be appended to the logical * eraseblock in future. Indeed, writing 0xFF bytes may have side effects and * this PEB won't be writable anymore. So if one writes the file-system image * to the UBI volume where 0xFFs mean free space - UBI makes sure this free * space is writable after the update. * * We do not do this for static volumes because they are read-only. But this * also cannot be done because we have to store per-LEB CRC and the correct * data length. * * This function returns zero in case of success and a negative error code in * case of failure. */ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, void *buf, int len, int used_ebs) { … } /** * ubi_more_update_data - write more update data. * @ubi: UBI device description object * @vol: volume description object * @buf: write data (user-space memory buffer) * @count: how much bytes to write * * This function writes more data to the volume which is being updated. It may * be called arbitrary number of times until all the update data arriveis. This * function returns %0 in case of success, number of bytes written during the * last call if the whole volume update has been successfully finished, and a * negative error code in case of failure. */ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, const void __user *buf, int count) { … } /** * ubi_more_leb_change_data - accept more data for atomic LEB change. * @ubi: UBI device description object * @vol: volume description object * @buf: write data (user-space memory buffer) * @count: how much bytes to write * * This function accepts more data to the volume which is being under the * "atomic LEB change" operation. It may be called arbitrary number of times * until all data arrives. This function returns %0 in case of success, number * of bytes written during the last call if the whole "atomic LEB change" * operation has been successfully finished, and a negative error code in case * of failure. */ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, const void __user *buf, int count) { … }