// SPDX-License-Identifier: GPL-2.0+
/*
 * 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.
 */

#ifndef __UBOOT__
#include <log.h>
#include <malloc.h>
#include <linux/uaccess.h>
#else
#include <div64.h>
#include <ubi_uboot.h>
#endif
#include <linux/err.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)
{
	int err;
	struct ubi_vtbl_record vtbl_rec;

	dbg_gen("set update marker for volume %d", vol->vol_id);

	if (vol->upd_marker) {
		ubi_assert(ubi->vtbl[vol->vol_id].upd_marker);
		dbg_gen("already set");
		return 0;
	}

	vtbl_rec = ubi->vtbl[vol->vol_id];
	vtbl_rec.upd_marker = 1;

	mutex_lock(&ubi->device_mutex);
	err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
	vol->upd_marker = 1;
	mutex_unlock(&ubi->device_mutex);
	return err;
}

/**
 * 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)
{
	int err;
	struct ubi_vtbl_record vtbl_rec;

	dbg_gen("clear update marker for volume %d", vol->vol_id);

	vtbl_rec = ubi->vtbl[vol->vol_id];
	ubi_assert(vol->upd_marker && vtbl_rec.upd_marker);
	vtbl_rec.upd_marker = 0;

	if (vol->vol_type == UBI_STATIC_VOLUME) {
		vol->corrupted = 0;
		vol->used_bytes = bytes;
		vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size,
					    &vol->last_eb_bytes);
		if (vol->last_eb_bytes)
			vol->used_ebs += 1;
		else
			vol->last_eb_bytes = vol->usable_leb_size;
	}

	mutex_lock(&ubi->device_mutex);
	err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
	vol->upd_marker = 0;
	mutex_unlock(&ubi->device_mutex);
	return err;
}

/**
 * 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)
{
	int i, err;

	dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes);
	ubi_assert(!vol->updating && !vol->changing_leb);
	vol->updating = 1;

	vol->upd_buf = vmalloc(ubi->leb_size);
	if (!vol->upd_buf)
		return -ENOMEM;

	err = set_update_marker(ubi, vol);
	if (err)
		return err;

	/* Before updating - wipe out the volume */
	for (i = 0; i < vol->reserved_pebs; i++) {
		err = ubi_eba_unmap_leb(ubi, vol, i);
		if (err)
			return err;
	}

	if (bytes == 0) {
		err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
		if (err)
			return err;

		err = clear_update_marker(ubi, vol, 0);
		if (err)
			return err;

		vfree(vol->upd_buf);
		vol->updating = 0;
		return 0;
	}

	vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1,
			       vol->usable_leb_size);
	vol->upd_bytes = bytes;
	vol->upd_received = 0;
	return 0;
}

/**
 * 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)
{
	ubi_assert(!vol->updating && !vol->changing_leb);

	dbg_gen("start changing LEB %d:%d, %u bytes",
		vol->vol_id, req->lnum, req->bytes);
	if (req->bytes == 0)
		return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0);

	vol->upd_bytes = req->bytes;
	vol->upd_received = 0;
	vol->changing_leb = 1;
	vol->ch_lnum = req->lnum;

	vol->upd_buf = vmalloc(req->bytes);
	if (!vol->upd_buf)
		return -ENOMEM;

	return 0;
}

/**
 * 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)
{
	int err;

	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
		int l = ALIGN(len, ubi->min_io_size);

		memset(buf + len, 0xFF, l - len);
		len = ubi_calc_data_len(ubi, buf, l);
		if (len == 0) {
			dbg_gen("all %d bytes contain 0xFF - skip", len);
			return 0;
		}

		err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len);
	} else {
		/*
		 * When writing static volume, and this is the last logical
		 * eraseblock, the length (@len) does not have to be aligned to
		 * the minimal flash I/O unit. The 'ubi_eba_write_leb_st()'
		 * function accepts exact (unaligned) length and stores it in
		 * the VID header. And it takes care of proper alignment by
		 * padding the buffer. Here we just make sure the padding will
		 * contain zeros, not random trash.
		 */
		memset(buf + len, 0, vol->usable_leb_size - len);
		err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs);
	}

	return err;
}

/**
 * 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)
{
#ifndef __UBOOT__
	int lnum, offs, err = 0, len, to_write = count;
#else
	int lnum, err = 0, len, to_write = count;
	u32 offs;
#endif

	dbg_gen("write %d of %lld bytes, %lld already passed",
		count, vol->upd_bytes, vol->upd_received);

	if (ubi->ro_mode)
		return -EROFS;

	lnum = div_u64_rem(vol->upd_received,  vol->usable_leb_size, &offs);
	if (vol->upd_received + count > vol->upd_bytes)
		to_write = count = vol->upd_bytes - vol->upd_received;

	/*
	 * When updating volumes, we accumulate whole logical eraseblock of
	 * data and write it at once.
	 */
	if (offs != 0) {
		/*
		 * This is a write to the middle of the logical eraseblock. We
		 * copy the data to our update buffer and wait for more data or
		 * flush it if the whole eraseblock is written or the update
		 * is finished.
		 */

		len = vol->usable_leb_size - offs;
		if (len > count)
			len = count;

		err = copy_from_user(vol->upd_buf + offs, buf, len);
		if (err)
			return -EFAULT;

		if (offs + len == vol->usable_leb_size ||
		    vol->upd_received + len == vol->upd_bytes) {
			int flush_len = offs + len;

			/*
			 * OK, we gathered either the whole eraseblock or this
			 * is the last chunk, it's time to flush the buffer.
			 */
			ubi_assert(flush_len <= vol->usable_leb_size);
			err = write_leb(ubi, vol, lnum, vol->upd_buf, flush_len,
					vol->upd_ebs);
			if (err)
				return err;
		}

		vol->upd_received += len;
		count -= len;
		buf += len;
		lnum += 1;
	}

	/*
	 * If we've got more to write, let's continue. At this point we know we
	 * are starting from the beginning of an eraseblock.
	 */
	while (count) {
		if (count > vol->usable_leb_size)
			len = vol->usable_leb_size;
		else
			len = count;

		err = copy_from_user(vol->upd_buf, buf, len);
		if (err)
			return -EFAULT;

		if (len == vol->usable_leb_size ||
		    vol->upd_received + len == vol->upd_bytes) {
			err = write_leb(ubi, vol, lnum, vol->upd_buf,
					len, vol->upd_ebs);
			if (err)
				break;
		}

		vol->upd_received += len;
		count -= len;
		lnum += 1;
		buf += len;
	}

	ubi_assert(vol->upd_received <= vol->upd_bytes);
	if (vol->upd_received == vol->upd_bytes) {
		err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
		if (err)
			return err;
		/* The update is finished, clear the update marker */
		err = clear_update_marker(ubi, vol, vol->upd_bytes);
		if (err)
			return err;
		vol->updating = 0;
		err = to_write;
		vfree(vol->upd_buf);
	}

	return err;
}

/**
 * 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)
{
	int err;

	dbg_gen("write %d of %lld bytes, %lld already passed",
		count, vol->upd_bytes, vol->upd_received);

	if (ubi->ro_mode)
		return -EROFS;

	if (vol->upd_received + count > vol->upd_bytes)
		count = vol->upd_bytes - vol->upd_received;

	err = copy_from_user(vol->upd_buf + vol->upd_received, buf, count);
	if (err)
		return -EFAULT;

	vol->upd_received += count;

	if (vol->upd_received == vol->upd_bytes) {
		int len = ALIGN((int)vol->upd_bytes, ubi->min_io_size);

		memset(vol->upd_buf + vol->upd_bytes, 0xFF,
		       len - vol->upd_bytes);
		len = ubi_calc_data_len(ubi, vol->upd_buf, len);
		err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum,
						vol->upd_buf, len);
		if (err)
			return err;
	}

	ubi_assert(vol->upd_received <= vol->upd_bytes);
	if (vol->upd_received == vol->upd_bytes) {
		vol->changing_leb = 0;
		err = count;
		vfree(vol->upd_buf);
	}

	return err;
}
