162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2006 462306a36Sopenharmony_ci * Copyright (c) Nokia Corporation, 2006 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Author: Artem Bityutskiy (Битюцкий Артём) 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Jan 2007: Alexander Schmidt, hacked per-volume update. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * This file contains implementation of the volume update and atomic LEB change 1362306a36Sopenharmony_ci * functionality. 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * The update operation is based on the per-volume update marker which is 1662306a36Sopenharmony_ci * stored in the volume table. The update marker is set before the update 1762306a36Sopenharmony_ci * starts, and removed after the update has been finished. So if the update was 1862306a36Sopenharmony_ci * interrupted by an unclean re-boot or due to some other reasons, the update 1962306a36Sopenharmony_ci * marker stays on the flash media and UBI finds it when it attaches the MTD 2062306a36Sopenharmony_ci * device next time. If the update marker is set for a volume, the volume is 2162306a36Sopenharmony_ci * treated as damaged and most I/O operations are prohibited. Only a new update 2262306a36Sopenharmony_ci * operation is allowed. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Note, in general it is possible to implement the update operation as a 2562306a36Sopenharmony_ci * transaction with a roll-back capability. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <linux/err.h> 2962306a36Sopenharmony_ci#include <linux/uaccess.h> 3062306a36Sopenharmony_ci#include <linux/math64.h> 3162306a36Sopenharmony_ci#include "ubi.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/** 3462306a36Sopenharmony_ci * set_update_marker - set update marker. 3562306a36Sopenharmony_ci * @ubi: UBI device description object 3662306a36Sopenharmony_ci * @vol: volume description object 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * This function sets the update marker flag for volume @vol. Returns zero 3962306a36Sopenharmony_ci * in case of success and a negative error code in case of failure. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_cistatic int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci int err; 4462306a36Sopenharmony_ci struct ubi_vtbl_record vtbl_rec; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci dbg_gen("set update marker for volume %d", vol->vol_id); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (vol->upd_marker) { 4962306a36Sopenharmony_ci ubi_assert(ubi->vtbl[vol->vol_id].upd_marker); 5062306a36Sopenharmony_ci dbg_gen("already set"); 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci vtbl_rec = ubi->vtbl[vol->vol_id]; 5562306a36Sopenharmony_ci vtbl_rec.upd_marker = 1; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci mutex_lock(&ubi->device_mutex); 5862306a36Sopenharmony_ci err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec); 5962306a36Sopenharmony_ci vol->upd_marker = 1; 6062306a36Sopenharmony_ci mutex_unlock(&ubi->device_mutex); 6162306a36Sopenharmony_ci return err; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/** 6562306a36Sopenharmony_ci * clear_update_marker - clear update marker. 6662306a36Sopenharmony_ci * @ubi: UBI device description object 6762306a36Sopenharmony_ci * @vol: volume description object 6862306a36Sopenharmony_ci * @bytes: new data size in bytes 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * This function clears the update marker for volume @vol, sets new volume 7162306a36Sopenharmony_ci * data size and clears the "corrupted" flag (static volumes only). Returns 7262306a36Sopenharmony_ci * zero in case of success and a negative error code in case of failure. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cistatic int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, 7562306a36Sopenharmony_ci long long bytes) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci int err; 7862306a36Sopenharmony_ci struct ubi_vtbl_record vtbl_rec; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci dbg_gen("clear update marker for volume %d", vol->vol_id); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci vtbl_rec = ubi->vtbl[vol->vol_id]; 8362306a36Sopenharmony_ci ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); 8462306a36Sopenharmony_ci vtbl_rec.upd_marker = 0; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (vol->vol_type == UBI_STATIC_VOLUME) { 8762306a36Sopenharmony_ci vol->corrupted = 0; 8862306a36Sopenharmony_ci vol->used_bytes = bytes; 8962306a36Sopenharmony_ci vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size, 9062306a36Sopenharmony_ci &vol->last_eb_bytes); 9162306a36Sopenharmony_ci if (vol->last_eb_bytes) 9262306a36Sopenharmony_ci vol->used_ebs += 1; 9362306a36Sopenharmony_ci else 9462306a36Sopenharmony_ci vol->last_eb_bytes = vol->usable_leb_size; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci mutex_lock(&ubi->device_mutex); 9862306a36Sopenharmony_ci err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec); 9962306a36Sopenharmony_ci vol->upd_marker = 0; 10062306a36Sopenharmony_ci mutex_unlock(&ubi->device_mutex); 10162306a36Sopenharmony_ci return err; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/** 10562306a36Sopenharmony_ci * ubi_start_update - start volume update. 10662306a36Sopenharmony_ci * @ubi: UBI device description object 10762306a36Sopenharmony_ci * @vol: volume description object 10862306a36Sopenharmony_ci * @bytes: update bytes 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * This function starts volume update operation. If @bytes is zero, the volume 11162306a36Sopenharmony_ci * is just wiped out. Returns zero in case of success and a negative error code 11262306a36Sopenharmony_ci * in case of failure. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ciint ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, 11562306a36Sopenharmony_ci long long bytes) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci int i, err; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes); 12062306a36Sopenharmony_ci ubi_assert(!vol->updating && !vol->changing_leb); 12162306a36Sopenharmony_ci vol->updating = 1; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci vol->upd_buf = vmalloc(ubi->leb_size); 12462306a36Sopenharmony_ci if (!vol->upd_buf) 12562306a36Sopenharmony_ci return -ENOMEM; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci err = set_update_marker(ubi, vol); 12862306a36Sopenharmony_ci if (err) 12962306a36Sopenharmony_ci return err; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Before updating - wipe out the volume */ 13262306a36Sopenharmony_ci for (i = 0; i < vol->reserved_pebs; i++) { 13362306a36Sopenharmony_ci err = ubi_eba_unmap_leb(ubi, vol, i); 13462306a36Sopenharmony_ci if (err) 13562306a36Sopenharmony_ci return err; 13662306a36Sopenharmony_ci } 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); 13962306a36Sopenharmony_ci if (err) 14062306a36Sopenharmony_ci return err; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if (bytes == 0) { 14362306a36Sopenharmony_ci err = clear_update_marker(ubi, vol, 0); 14462306a36Sopenharmony_ci if (err) 14562306a36Sopenharmony_ci return err; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci vfree(vol->upd_buf); 14862306a36Sopenharmony_ci vol->updating = 0; 14962306a36Sopenharmony_ci return 0; 15062306a36Sopenharmony_ci } 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, 15362306a36Sopenharmony_ci vol->usable_leb_size); 15462306a36Sopenharmony_ci vol->upd_bytes = bytes; 15562306a36Sopenharmony_ci vol->upd_received = 0; 15662306a36Sopenharmony_ci return 0; 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/** 16062306a36Sopenharmony_ci * ubi_start_leb_change - start atomic LEB change. 16162306a36Sopenharmony_ci * @ubi: UBI device description object 16262306a36Sopenharmony_ci * @vol: volume description object 16362306a36Sopenharmony_ci * @req: operation request 16462306a36Sopenharmony_ci * 16562306a36Sopenharmony_ci * This function starts atomic LEB change operation. Returns zero in case of 16662306a36Sopenharmony_ci * success and a negative error code in case of failure. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ciint ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, 16962306a36Sopenharmony_ci const struct ubi_leb_change_req *req) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci ubi_assert(!vol->updating && !vol->changing_leb); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci dbg_gen("start changing LEB %d:%d, %u bytes", 17462306a36Sopenharmony_ci vol->vol_id, req->lnum, req->bytes); 17562306a36Sopenharmony_ci if (req->bytes == 0) 17662306a36Sopenharmony_ci return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci vol->upd_bytes = req->bytes; 17962306a36Sopenharmony_ci vol->upd_received = 0; 18062306a36Sopenharmony_ci vol->changing_leb = 1; 18162306a36Sopenharmony_ci vol->ch_lnum = req->lnum; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size)); 18462306a36Sopenharmony_ci if (!vol->upd_buf) 18562306a36Sopenharmony_ci return -ENOMEM; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci return 0; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/** 19162306a36Sopenharmony_ci * write_leb - write update data. 19262306a36Sopenharmony_ci * @ubi: UBI device description object 19362306a36Sopenharmony_ci * @vol: volume description object 19462306a36Sopenharmony_ci * @lnum: logical eraseblock number 19562306a36Sopenharmony_ci * @buf: data to write 19662306a36Sopenharmony_ci * @len: data size 19762306a36Sopenharmony_ci * @used_ebs: how many logical eraseblocks will this volume contain (static 19862306a36Sopenharmony_ci * volumes only) 19962306a36Sopenharmony_ci * 20062306a36Sopenharmony_ci * This function writes update data to corresponding logical eraseblock. In 20162306a36Sopenharmony_ci * case of dynamic volume, this function checks if the data contains 0xFF bytes 20262306a36Sopenharmony_ci * at the end. If yes, the 0xFF bytes are cut and not written. So if the whole 20362306a36Sopenharmony_ci * buffer contains only 0xFF bytes, the LEB is left unmapped. 20462306a36Sopenharmony_ci * 20562306a36Sopenharmony_ci * The reason why we skip the trailing 0xFF bytes in case of dynamic volume is 20662306a36Sopenharmony_ci * that we want to make sure that more data may be appended to the logical 20762306a36Sopenharmony_ci * eraseblock in future. Indeed, writing 0xFF bytes may have side effects and 20862306a36Sopenharmony_ci * this PEB won't be writable anymore. So if one writes the file-system image 20962306a36Sopenharmony_ci * to the UBI volume where 0xFFs mean free space - UBI makes sure this free 21062306a36Sopenharmony_ci * space is writable after the update. 21162306a36Sopenharmony_ci * 21262306a36Sopenharmony_ci * We do not do this for static volumes because they are read-only. But this 21362306a36Sopenharmony_ci * also cannot be done because we have to store per-LEB CRC and the correct 21462306a36Sopenharmony_ci * data length. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * This function returns zero in case of success and a negative error code in 21762306a36Sopenharmony_ci * case of failure. 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_cistatic int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, 22062306a36Sopenharmony_ci void *buf, int len, int used_ebs) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci int err; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci if (vol->vol_type == UBI_DYNAMIC_VOLUME) { 22562306a36Sopenharmony_ci int l = ALIGN(len, ubi->min_io_size); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci memset(buf + len, 0xFF, l - len); 22862306a36Sopenharmony_ci len = ubi_calc_data_len(ubi, buf, l); 22962306a36Sopenharmony_ci if (len == 0) { 23062306a36Sopenharmony_ci dbg_gen("all %d bytes contain 0xFF - skip", len); 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len); 23562306a36Sopenharmony_ci } else { 23662306a36Sopenharmony_ci /* 23762306a36Sopenharmony_ci * When writing static volume, and this is the last logical 23862306a36Sopenharmony_ci * eraseblock, the length (@len) does not have to be aligned to 23962306a36Sopenharmony_ci * the minimal flash I/O unit. The 'ubi_eba_write_leb_st()' 24062306a36Sopenharmony_ci * function accepts exact (unaligned) length and stores it in 24162306a36Sopenharmony_ci * the VID header. And it takes care of proper alignment by 24262306a36Sopenharmony_ci * padding the buffer. Here we just make sure the padding will 24362306a36Sopenharmony_ci * contain zeros, not random trash. 24462306a36Sopenharmony_ci */ 24562306a36Sopenharmony_ci memset(buf + len, 0, vol->usable_leb_size - len); 24662306a36Sopenharmony_ci err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs); 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci return err; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci/** 25362306a36Sopenharmony_ci * ubi_more_update_data - write more update data. 25462306a36Sopenharmony_ci * @ubi: UBI device description object 25562306a36Sopenharmony_ci * @vol: volume description object 25662306a36Sopenharmony_ci * @buf: write data (user-space memory buffer) 25762306a36Sopenharmony_ci * @count: how much bytes to write 25862306a36Sopenharmony_ci * 25962306a36Sopenharmony_ci * This function writes more data to the volume which is being updated. It may 26062306a36Sopenharmony_ci * be called arbitrary number of times until all the update data arriveis. This 26162306a36Sopenharmony_ci * function returns %0 in case of success, number of bytes written during the 26262306a36Sopenharmony_ci * last call if the whole volume update has been successfully finished, and a 26362306a36Sopenharmony_ci * negative error code in case of failure. 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_ciint ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, 26662306a36Sopenharmony_ci const void __user *buf, int count) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci int lnum, offs, err = 0, len, to_write = count; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci dbg_gen("write %d of %lld bytes, %lld already passed", 27162306a36Sopenharmony_ci count, vol->upd_bytes, vol->upd_received); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (ubi->ro_mode) 27462306a36Sopenharmony_ci return -EROFS; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs); 27762306a36Sopenharmony_ci if (vol->upd_received + count > vol->upd_bytes) 27862306a36Sopenharmony_ci to_write = count = vol->upd_bytes - vol->upd_received; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci /* 28162306a36Sopenharmony_ci * When updating volumes, we accumulate whole logical eraseblock of 28262306a36Sopenharmony_ci * data and write it at once. 28362306a36Sopenharmony_ci */ 28462306a36Sopenharmony_ci if (offs != 0) { 28562306a36Sopenharmony_ci /* 28662306a36Sopenharmony_ci * This is a write to the middle of the logical eraseblock. We 28762306a36Sopenharmony_ci * copy the data to our update buffer and wait for more data or 28862306a36Sopenharmony_ci * flush it if the whole eraseblock is written or the update 28962306a36Sopenharmony_ci * is finished. 29062306a36Sopenharmony_ci */ 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci len = vol->usable_leb_size - offs; 29362306a36Sopenharmony_ci if (len > count) 29462306a36Sopenharmony_ci len = count; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci err = copy_from_user(vol->upd_buf + offs, buf, len); 29762306a36Sopenharmony_ci if (err) 29862306a36Sopenharmony_ci return -EFAULT; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if (offs + len == vol->usable_leb_size || 30162306a36Sopenharmony_ci vol->upd_received + len == vol->upd_bytes) { 30262306a36Sopenharmony_ci int flush_len = offs + len; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* 30562306a36Sopenharmony_ci * OK, we gathered either the whole eraseblock or this 30662306a36Sopenharmony_ci * is the last chunk, it's time to flush the buffer. 30762306a36Sopenharmony_ci */ 30862306a36Sopenharmony_ci ubi_assert(flush_len <= vol->usable_leb_size); 30962306a36Sopenharmony_ci err = write_leb(ubi, vol, lnum, vol->upd_buf, flush_len, 31062306a36Sopenharmony_ci vol->upd_ebs); 31162306a36Sopenharmony_ci if (err) 31262306a36Sopenharmony_ci return err; 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci vol->upd_received += len; 31662306a36Sopenharmony_ci count -= len; 31762306a36Sopenharmony_ci buf += len; 31862306a36Sopenharmony_ci lnum += 1; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci /* 32262306a36Sopenharmony_ci * If we've got more to write, let's continue. At this point we know we 32362306a36Sopenharmony_ci * are starting from the beginning of an eraseblock. 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_ci while (count) { 32662306a36Sopenharmony_ci if (count > vol->usable_leb_size) 32762306a36Sopenharmony_ci len = vol->usable_leb_size; 32862306a36Sopenharmony_ci else 32962306a36Sopenharmony_ci len = count; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci err = copy_from_user(vol->upd_buf, buf, len); 33262306a36Sopenharmony_ci if (err) 33362306a36Sopenharmony_ci return -EFAULT; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci if (len == vol->usable_leb_size || 33662306a36Sopenharmony_ci vol->upd_received + len == vol->upd_bytes) { 33762306a36Sopenharmony_ci err = write_leb(ubi, vol, lnum, vol->upd_buf, 33862306a36Sopenharmony_ci len, vol->upd_ebs); 33962306a36Sopenharmony_ci if (err) 34062306a36Sopenharmony_ci break; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci vol->upd_received += len; 34462306a36Sopenharmony_ci count -= len; 34562306a36Sopenharmony_ci lnum += 1; 34662306a36Sopenharmony_ci buf += len; 34762306a36Sopenharmony_ci } 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci ubi_assert(vol->upd_received <= vol->upd_bytes); 35062306a36Sopenharmony_ci if (vol->upd_received == vol->upd_bytes) { 35162306a36Sopenharmony_ci err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); 35262306a36Sopenharmony_ci if (err) 35362306a36Sopenharmony_ci return err; 35462306a36Sopenharmony_ci /* The update is finished, clear the update marker */ 35562306a36Sopenharmony_ci err = clear_update_marker(ubi, vol, vol->upd_bytes); 35662306a36Sopenharmony_ci if (err) 35762306a36Sopenharmony_ci return err; 35862306a36Sopenharmony_ci vol->updating = 0; 35962306a36Sopenharmony_ci err = to_write; 36062306a36Sopenharmony_ci vfree(vol->upd_buf); 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci return err; 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci/** 36762306a36Sopenharmony_ci * ubi_more_leb_change_data - accept more data for atomic LEB change. 36862306a36Sopenharmony_ci * @ubi: UBI device description object 36962306a36Sopenharmony_ci * @vol: volume description object 37062306a36Sopenharmony_ci * @buf: write data (user-space memory buffer) 37162306a36Sopenharmony_ci * @count: how much bytes to write 37262306a36Sopenharmony_ci * 37362306a36Sopenharmony_ci * This function accepts more data to the volume which is being under the 37462306a36Sopenharmony_ci * "atomic LEB change" operation. It may be called arbitrary number of times 37562306a36Sopenharmony_ci * until all data arrives. This function returns %0 in case of success, number 37662306a36Sopenharmony_ci * of bytes written during the last call if the whole "atomic LEB change" 37762306a36Sopenharmony_ci * operation has been successfully finished, and a negative error code in case 37862306a36Sopenharmony_ci * of failure. 37962306a36Sopenharmony_ci */ 38062306a36Sopenharmony_ciint ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, 38162306a36Sopenharmony_ci const void __user *buf, int count) 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci int err; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci dbg_gen("write %d of %lld bytes, %lld already passed", 38662306a36Sopenharmony_ci count, vol->upd_bytes, vol->upd_received); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci if (ubi->ro_mode) 38962306a36Sopenharmony_ci return -EROFS; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci if (vol->upd_received + count > vol->upd_bytes) 39262306a36Sopenharmony_ci count = vol->upd_bytes - vol->upd_received; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci err = copy_from_user(vol->upd_buf + vol->upd_received, buf, count); 39562306a36Sopenharmony_ci if (err) 39662306a36Sopenharmony_ci return -EFAULT; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci vol->upd_received += count; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if (vol->upd_received == vol->upd_bytes) { 40162306a36Sopenharmony_ci int len = ALIGN((int)vol->upd_bytes, ubi->min_io_size); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci memset(vol->upd_buf + vol->upd_bytes, 0xFF, 40462306a36Sopenharmony_ci len - vol->upd_bytes); 40562306a36Sopenharmony_ci len = ubi_calc_data_len(ubi, vol->upd_buf, len); 40662306a36Sopenharmony_ci err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum, 40762306a36Sopenharmony_ci vol->upd_buf, len); 40862306a36Sopenharmony_ci if (err) 40962306a36Sopenharmony_ci return err; 41062306a36Sopenharmony_ci } 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci ubi_assert(vol->upd_received <= vol->upd_bytes); 41362306a36Sopenharmony_ci if (vol->upd_received == vol->upd_bytes) { 41462306a36Sopenharmony_ci vol->changing_leb = 0; 41562306a36Sopenharmony_ci err = count; 41662306a36Sopenharmony_ci vfree(vol->upd_buf); 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci return err; 42062306a36Sopenharmony_ci} 421