1801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* 2801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Copyright (c) International Business Machines Corp., 2006 3801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 4801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This program is free software; you can redistribute it and/or modify 5801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * it under the terms of the GNU General Public License as published by 6801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the Free Software Foundation; either version 2 of the License, or 7801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * (at your option) any later version. 8801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 9801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This program is distributed in the hope that it will be useful, 10801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * but WITHOUT ANY WARRANTY; without even the implied warranty of 11801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the GNU General Public License for more details. 13801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 14801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * You should have received a copy of the GNU General Public License 15801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * along with this program; if not, write to the Free Software 16801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 18801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Author: Artem Bityutskiy (Битюцкий Артём) 19801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 20801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 21801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* 2285c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * The UBI Eraseblock Association (EBA) sub-system. 23801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 2485c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * This sub-system is responsible for I/O to/from logical eraseblock. 25801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 26801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Although in this implementation the EBA table is fully kept and managed in 27801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * RAM, which assumes poor scalability, it might be (partially) maintained on 28801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * flash in future implementations. 29801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 3085c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * The EBA sub-system implements per-logical eraseblock locking. Before 3185c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * accessing a logical eraseblock it is locked for reading or writing. The 3285c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * per-logical eraseblock locking is implemented by means of the lock tree. The 3385c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * lock tree is an RB-tree which refers all the currently locked logical 3485c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * eraseblocks. The lock tree elements are &struct ubi_ltree_entry objects. 3585c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * They are indexed by (@vol_id, @lnum) pairs. 36801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 37801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * EBA also maintains the global sequence counter which is incremented each 38801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * time a logical eraseblock is mapped to a physical eraseblock and it is 39801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * stored in the volume identifier header. This means that each VID header has 40801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * a unique sequence number. The sequence number is only increased an we assume 41801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 64 bits is enough to never overflow. 42801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 43801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 44801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include <linux/slab.h> 45801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include <linux/crc32.h> 46801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include <linux/err.h> 47801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy#include "ubi.h" 48801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 49e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy/* Number of physical eraseblocks reserved for atomic LEB change operation */ 50e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy#define EBA_RESERVED_PEBS 1 51e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy 52801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 53801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * next_sqnum - get next sequence number. 54801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 55801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 56801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns next sequence number to use, which is just the current 57801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * global sequence counter value. It also increases the global sequence 58801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * counter. 59801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 60801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic unsigned long long next_sqnum(struct ubi_device *ubi) 61801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 62801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy unsigned long long sqnum; 63801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 64801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_lock(&ubi->ltree_lock); 65801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy sqnum = ubi->global_sqnum++; 66801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_unlock(&ubi->ltree_lock); 67801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 68801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return sqnum; 69801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 70801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 71801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 72801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_get_compat - get compatibility flags of a volume. 73801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 74801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 75801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 76801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns compatibility flags for an internal volume. User 77801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * volumes have no compatibility flags, so %0 is returned. 78801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 79801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int ubi_get_compat(const struct ubi_device *ubi, int vol_id) 80801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 8191f2d53cd75a8fa3557246af965155208c4c69a7Artem Bityutskiy if (vol_id == UBI_LAYOUT_VOLUME_ID) 82801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return UBI_LAYOUT_VOLUME_COMPAT; 83801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 84801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 85801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 86801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 87801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ltree_lookup - look up the lock tree. 88801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 89801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 90801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 91801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 923a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy * This function returns a pointer to the corresponding &struct ubi_ltree_entry 93801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * object if the logical eraseblock is locked and %NULL if it is not. 94801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi->ltree_lock has to be locked. 95801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 963a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiystatic struct ubi_ltree_entry *ltree_lookup(struct ubi_device *ubi, int vol_id, 973a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy int lnum) 98801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 99801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct rb_node *p; 100801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 101801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = ubi->ltree.rb_node; 102801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy while (p) { 1033a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le; 104801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1053a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy le = rb_entry(p, struct ubi_ltree_entry, rb); 106801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 107801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id < le->vol_id) 108801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = p->rb_left; 109801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else if (vol_id > le->vol_id) 110801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = p->rb_right; 111801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else { 112801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (lnum < le->lnum) 113801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = p->rb_left; 114801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else if (lnum > le->lnum) 115801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = p->rb_right; 116801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else 117801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return le; 118801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 119801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 120801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 121801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return NULL; 122801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 123801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 124801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 125801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ltree_add_entry - add new entry to the lock tree. 126801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 127801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 128801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 129801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 130801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function adds new entry for logical eraseblock (@vol_id, @lnum) to the 131801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * lock tree. If such entry is already there, its usage counter is increased. 132801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Returns pointer to the lock tree entry or %-ENOMEM if memory allocation 133801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * failed. 134801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1353a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiystatic struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, 1363a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy int vol_id, int lnum) 137801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1383a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le, *le1, *le_free; 139801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 140b9a06623d9d0c6dff758d525ceb0d9e2bba8f7d6Artem Bityutskiy le = kmalloc(sizeof(struct ubi_ltree_entry), GFP_NOFS); 141801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!le) 142801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return ERR_PTR(-ENOMEM); 143801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 144b9a06623d9d0c6dff758d525ceb0d9e2bba8f7d6Artem Bityutskiy le->users = 0; 145b9a06623d9d0c6dff758d525ceb0d9e2bba8f7d6Artem Bityutskiy init_rwsem(&le->mutex); 146801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le->vol_id = vol_id; 147801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le->lnum = lnum; 148801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 149801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_lock(&ubi->ltree_lock); 150801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le1 = ltree_lookup(ubi, vol_id, lnum); 151801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 152801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (le1) { 153801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 154801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This logical eraseblock is already locked. The newly 155801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * allocated lock entry is not needed. 156801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 157801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le_free = le; 158801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le = le1; 159801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else { 160801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct rb_node **p, *parent = NULL; 161801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 162801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 163801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * No lock entry, add the newly allocated one to the 164801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi->ltree RB-tree. 165801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 166801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le_free = NULL; 167801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 168801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = &ubi->ltree.rb_node; 169801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy while (*p) { 170801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy parent = *p; 1713a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy le1 = rb_entry(parent, struct ubi_ltree_entry, rb); 172801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 173801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol_id < le1->vol_id) 174801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = &(*p)->rb_left; 175801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else if (vol_id > le1->vol_id) 176801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = &(*p)->rb_right; 177801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else { 178801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(lnum != le1->lnum); 179801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (lnum < le1->lnum) 180801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = &(*p)->rb_left; 181801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else 182801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy p = &(*p)->rb_right; 183801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 184801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 185801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 186801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy rb_link_node(&le->rb, parent, p); 187801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy rb_insert_color(&le->rb, &ubi->ltree); 188801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 189801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le->users += 1; 190801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_unlock(&ubi->ltree_lock); 191801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1929c9ec147709e63e4e8ac6a037c6bb50688ff8e9cArtem Bityutskiy kfree(le_free); 193801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return le; 194801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 195801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 196801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 197801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * leb_read_lock - lock logical eraseblock for reading. 198801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 199801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 200801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 201801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 202801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function locks a logical eraseblock for reading. Returns zero in case 203801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * of success and a negative error code in case of failure. 204801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 205801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int leb_read_lock(struct ubi_device *ubi, int vol_id, int lnum) 206801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 2073a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le; 208801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 209801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le = ltree_add_entry(ubi, vol_id, lnum); 210801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (IS_ERR(le)) 211801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return PTR_ERR(le); 212801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy down_read(&le->mutex); 213801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 214801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 215801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 216801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 217801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * leb_read_unlock - unlock logical eraseblock. 218801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 219801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 220801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 221801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 222801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic void leb_read_unlock(struct ubi_device *ubi, int vol_id, int lnum) 223801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 2243a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le; 225801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 226801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_lock(&ubi->ltree_lock); 227801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le = ltree_lookup(ubi, vol_id, lnum); 228801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le->users -= 1; 229801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(le->users >= 0); 23023add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy up_read(&le->mutex); 231801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (le->users == 0) { 232801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy rb_erase(&le->rb, &ubi->ltree); 23323add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy kfree(le); 234801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 235801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_unlock(&ubi->ltree_lock); 236801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 237801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 238801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 239801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * leb_write_lock - lock logical eraseblock for writing. 240801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 241801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 242801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 243801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 244801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function locks a logical eraseblock for writing. Returns zero in case 245801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * of success and a negative error code in case of failure. 246801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 247801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int leb_write_lock(struct ubi_device *ubi, int vol_id, int lnum) 248801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 2493a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le; 250801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 251801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le = ltree_add_entry(ubi, vol_id, lnum); 252801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (IS_ERR(le)) 253801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return PTR_ERR(le); 254801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy down_write(&le->mutex); 255801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 256801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 257801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 258801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 25943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * leb_write_lock - lock logical eraseblock for writing. 26043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * @ubi: UBI device description object 26143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * @vol_id: volume ID 26243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * @lnum: logical eraseblock number 26343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * 26443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * This function locks a logical eraseblock for writing if there is no 26543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * contention and does nothing if there is contention. Returns %0 in case of 26643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * success, %1 in case of contention, and and a negative error code in case of 26743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * failure. 26843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy */ 26943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiystatic int leb_write_trylock(struct ubi_device *ubi, int vol_id, int lnum) 27043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy{ 27143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy struct ubi_ltree_entry *le; 27243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy 27343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy le = ltree_add_entry(ubi, vol_id, lnum); 27443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy if (IS_ERR(le)) 27543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy return PTR_ERR(le); 27643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy if (down_write_trylock(&le->mutex)) 27743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy return 0; 27843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy 27943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy /* Contention, cancel */ 28043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy spin_lock(&ubi->ltree_lock); 28143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy le->users -= 1; 28243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy ubi_assert(le->users >= 0); 28343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy if (le->users == 0) { 28443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy rb_erase(&le->rb, &ubi->ltree); 285b9a06623d9d0c6dff758d525ceb0d9e2bba8f7d6Artem Bityutskiy kfree(le); 28623add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy } 28723add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy spin_unlock(&ubi->ltree_lock); 28843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy 28943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy return 1; 29043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy} 29143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy 29243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy/** 293801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * leb_write_unlock - unlock logical eraseblock. 294801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 295801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 296801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 297801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 298801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum) 299801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 3003a8d4642861fb69b62401949e490c0bcb19ceb40Artem Bityutskiy struct ubi_ltree_entry *le; 301801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 302801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_lock(&ubi->ltree_lock); 303801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le = ltree_lookup(ubi, vol_id, lnum); 304801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy le->users -= 1; 305801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(le->users >= 0); 30623add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy up_write(&le->mutex); 307801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (le->users == 0) { 308801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy rb_erase(&le->rb, &ubi->ltree); 309b9a06623d9d0c6dff758d525ceb0d9e2bba8f7d6Artem Bityutskiy kfree(le); 31023add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy } 31123add7455c42eef63f8719bd268328047d4aed69Artem Bityutskiy spin_unlock(&ubi->ltree_lock); 312801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 313801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 314801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 315801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_unmap_leb - un-map logical eraseblock. 316801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 31789b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol: volume description object 318801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 319801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 320801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function un-maps logical eraseblock @lnum and schedules corresponding 321801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * physical eraseblock for erasure. Returns zero in case of success and a 322801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * negative error code in case of failure. 323801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 32489b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiyint ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, 32589b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int lnum) 326801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 32789b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int err, pnum, vol_id = vol->vol_id; 328801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 329801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) 330801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 331801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 332801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = leb_write_lock(ubi, vol_id, lnum); 333801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 334801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 335801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 336801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = vol->eba_tbl[lnum]; 337801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum < 0) 338801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* This logical eraseblock is already unmapped */ 339801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_unlock; 340801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 341801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); 342801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 343801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; 344801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_wl_put_peb(ubi, pnum, 0); 345801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 346801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyout_unlock: 347801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 348801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 349801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 350801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 351801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 352801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_read_leb - read data. 353801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 35489b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol: volume description object 355801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 356801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: buffer to store the read data 357801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: offset from where to read 358801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to read 359801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @check: data CRC check flag 360801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 361801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * If the logical eraseblock @lnum is unmapped, @buf is filled with 0xFF 362801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * bytes. The @check flag only makes sense for static volumes and forces 363801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock data CRC checking. 364801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 365801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * In case of success this function returns zero. In case of a static volume, 366801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * if data CRC mismatches - %-EBADMSG is returned. %-EBADMSG may also be 367801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * returned for any volume type if an ECC error was detected by the MTD device 368801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * driver. Other negative error cored may be returned in case of other errors. 369801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 37089b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiyint ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, 37189b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy void *buf, int offset, int len, int check) 372801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 37389b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int err, pnum, scrub = 0, vol_id = vol->vol_id; 374801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 375a6343afb6e16b65b9f0b264f94f8207212e7e3aeJeff Garzik uint32_t uninitialized_var(crc); 376801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 377801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = leb_read_lock(ubi, vol_id, lnum); 378801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 379801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 380801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 381801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = vol->eba_tbl[lnum]; 382801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum < 0) { 383801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 384801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The logical eraseblock is not mapped, fill the whole buffer 385801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * with 0xFF bytes. The exception is static volumes for which 386801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * it is an error to read unmapped logical eraseblocks. 387801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 388801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("read %d bytes from offset %d of LEB %d:%d (unmapped)", 389801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, offset, vol_id, lnum); 390801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_read_unlock(ubi, vol_id, lnum); 391801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(vol->vol_type != UBI_STATIC_VOLUME); 392801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy memset(buf, 0xFF, len); 393801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 394801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 395801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 396801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("read %d bytes from offset %d of LEB %d:%d, PEB %d", 397801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, offset, vol_id, lnum, pnum); 398801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 399801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol->vol_type == UBI_DYNAMIC_VOLUME) 400801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy check = 0; 401801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 402801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 403801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (check) { 40433818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 405801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vid_hdr) { 406801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -ENOMEM; 407801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_unlock; 408801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 409801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 410801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); 411801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err && err != UBI_IO_BITFLIPS) { 412801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err > 0) { 413801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 414801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The header is either absent or corrupted. 415801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The former case means there is a bug - 416801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * switch to read-only mode just in case. 417801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The latter case means a real corruption - we 418801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * may try to recover data. FIXME: but this is 419801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * not implemented. 420801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 421756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy if (err == UBI_IO_BAD_HDR_EBADMSG || 422eb89580e1a8388d206bf143c6c39d001095106baArtem Bityutskiy err == UBI_IO_BAD_HDR) { 423b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy ubi_warn("corrupted VID header at PEB " 424b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy "%d, LEB %d:%d", pnum, vol_id, 425b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy lnum); 426801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EBADMSG; 427801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else 428801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 429801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 430801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_free; 431801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else if (err == UBI_IO_BITFLIPS) 432801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy scrub = 1; 433801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 4343261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ubi_assert(lnum < be32_to_cpu(vid_hdr->used_ebs)); 4353261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ubi_assert(len == be32_to_cpu(vid_hdr->data_size)); 436801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 4373261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig crc = be32_to_cpu(vid_hdr->data_crc); 438801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 439801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 440801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 441801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read_data(ubi, buf, pnum, offset, len); 442801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 443801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err == UBI_IO_BITFLIPS) { 444801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy scrub = 1; 445801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = 0; 446d57f40544a41fdfe90fd863b6865138c5a82f1ccBrian Norris } else if (mtd_is_eccerr(err)) { 447801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vol->vol_type == UBI_DYNAMIC_VOLUME) 448801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_unlock; 449801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy scrub = 1; 450801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!check) { 451801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("force data checking"); 452801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy check = 1; 453801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 454801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 455801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else 456801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_unlock; 457801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 458801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 459801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (check) { 4602ab934b8afa89b9b3e71b7fb66470a19772f5012Jeff Garzik uint32_t crc1 = crc32(UBI_CRC32_INIT, buf, len); 461801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (crc1 != crc) { 462801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("CRC error: calculated %#08x, must be %#08x", 463801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc1, crc); 464801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EBADMSG; 465801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_unlock; 466801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 467801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 468801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 469801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (scrub) 470801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_wl_scrub_peb(ubi, pnum); 471801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 472801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_read_unlock(ubi, vol_id, lnum); 473801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 474801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 475801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyout_free: 476801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 477801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyout_unlock: 478801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_read_unlock(ubi, vol_id, lnum); 479801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 480801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 481801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 482801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 483801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * recover_peb - recover from write failure. 484801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 485801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @pnum: the physical eraseblock to recover 486801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vol_id: volume ID 487801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 488801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: data which was not written because of the write failure 489801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: offset of the failed write 490801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes should have been written 491801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 492801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function is called in case of a write failure and moves all good data 493801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * from the potentially bad physical eraseblock to a good physical eraseblock. 494801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function also writes the data which was not written due to the failure. 495801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Returns new physical eraseblock number in case of success, and a negative 496801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * error code in case of failure. 497801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 498801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiystatic int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, 499801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const void *buf, int offset, int len) 500801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 501801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; 502801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_volume *vol = ubi->volumes[idx]; 503801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 504801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 50533818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 5069c9ec147709e63e4e8ac6a037c6bb50688ff8e9cArtem Bityutskiy if (!vid_hdr) 507801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 508801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 509801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 510801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); 511801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (new_pnum < 0) { 512801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 513801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return new_pnum; 514801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 515801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 516801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("recover PEB %d, move data to PEB %d", pnum, new_pnum); 517801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 518801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); 519801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err && err != UBI_IO_BITFLIPS) { 520801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err > 0) 521801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -EIO; 522801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_put; 523801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 524801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 5253261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 526801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); 527801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 528801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 529801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 530801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy data_size = offset + len; 5314df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiy mutex_lock(&ubi->buf_mutex); 532e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy memset(ubi->peb_buf1 + offset, 0xFF, len); 533801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 534801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* Read everything before the area where the write failure happened */ 535801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (offset > 0) { 536e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); 537e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy if (err && err != UBI_IO_BITFLIPS) 5384df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiy goto out_unlock; 539801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 540801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 541e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy memcpy(ubi->peb_buf1 + offset, buf, len); 542801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 543e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); 5444df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiy if (err) { 5454df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiy mutex_unlock(&ubi->buf_mutex); 546801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 5474df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiy } 548801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 549e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy mutex_unlock(&ubi->buf_mutex); 550801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 551801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 552801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = new_pnum; 553801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_wl_put_peb(ubi, pnum, 1); 554801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 555801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("data was successfully recovered"); 556801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 557801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 5584df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiyout_unlock: 559e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy mutex_unlock(&ubi->buf_mutex); 5604df581f3dc6a91a63b9965ac8bdb47d8db294e37Artem Bityutskiyout_put: 561801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_wl_put_peb(ubi, new_pnum, 1); 562801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 563801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 564801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 565801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiywrite_error: 566801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 567801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Bad luck? This physical eraseblock is bad too? Crud. Let's try to 568801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * get another one. 569801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 570801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write to PEB %d", new_pnum); 571801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_wl_put_peb(ubi, new_pnum, 1); 572801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (++tries > UBI_IO_RETRIES) { 573801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 574801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 575801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 576801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("try again"); 577801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 578801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 579801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 580801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 581801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_write_leb - write data to dynamic volume. 582801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 58389b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol: volume description object 584801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 585801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: the data to write 586801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @offset: offset within the logical eraseblock where to write 587801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to write 588801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @dtype: data type 589801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 590801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function writes data to logical eraseblock @lnum of a dynamic volume 59189b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol. Returns zero in case of success and a negative error code in case 592801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * of failure. In case of error, it is possible that something was still 593801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * written to the flash media, but may be some garbage. 594801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 59589b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiyint ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, 596801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy const void *buf, int offset, int len, int dtype) 597801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 59889b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int err, pnum, tries = 0, vol_id = vol->vol_id; 599801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 600801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 601801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) 602801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 603801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 604801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = leb_write_lock(ubi, vol_id, lnum); 605801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 606801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 607801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 608801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = vol->eba_tbl[lnum]; 609801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum >= 0) { 610801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", 611801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, offset, vol_id, lnum, pnum); 612801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 613801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_data(ubi, buf, pnum, offset, len); 614801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 615801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write data to PEB %d", pnum); 616801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err == -EIO && ubi->bad_allowed) 61789b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy err = recover_peb(ubi, pnum, vol_id, lnum, buf, 61889b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy offset, len); 619801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) 620801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 621801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 622801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 623801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 624801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 625801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 626801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 627801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * The logical eraseblock is not mapped. We have to get a free physical 628801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock and write the volume identifier header there first. 629801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 63033818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 631801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vid_hdr) { 632801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 633801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 634801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 635801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 636801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->vol_type = UBI_VID_DYNAMIC; 6373261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 6383261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->vol_id = cpu_to_be32(vol_id); 6393261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->lnum = cpu_to_be32(lnum); 640801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->compat = ubi_get_compat(ubi, vol_id); 6413261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_pad = cpu_to_be32(vol->data_pad); 642801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 643801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 644801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = ubi_wl_get_peb(ubi, dtype); 645801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum < 0) { 646801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 647801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 648801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return pnum; 649801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 650801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 651801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("write VID hdr and %d bytes at offset %d of LEB %d:%d, PEB %d", 652801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, offset, vol_id, lnum, pnum); 653801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 654801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); 655801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 656801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", 657801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol_id, lnum, pnum); 658801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 659801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 660801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 661393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy if (len) { 662393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy err = ubi_io_write_data(ubi, buf, pnum, offset, len); 663393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy if (err) { 664393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy ubi_warn("failed to write %d bytes at offset %d of " 665393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy "LEB %d:%d, PEB %d", len, offset, vol_id, 666393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy lnum, pnum); 667393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy goto write_error; 668393852ecfeec575ac78216b0eb58e4fd92f0816cArtem Bityutskiy } 669801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 670801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 671801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = pnum; 672801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 673801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 674801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 675801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 676801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 677801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiywrite_error: 678801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err != -EIO || !ubi->bad_allowed) { 679801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 680801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 681801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 682801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 683801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 684801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 685801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 686801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * Fortunately, this is the first write operation to this physical 687801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock, so just put it and request a new one. We assume that if 688801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * this physical eraseblock went bad, the erase code will handle that. 689801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 690801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_wl_put_peb(ubi, pnum, 1); 691801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err || ++tries > UBI_IO_RETRIES) { 692801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 693801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 694801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 695801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 696801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 697801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 6983261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 699801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("try another PEB"); 700801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 701801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 702801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 703801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 704801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_write_leb_st - write data to static volume. 705801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 70689b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol: volume description object 707801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 708801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: data to write 709801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to write 710801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @dtype: data type 711801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @used_ebs: how many logical eraseblocks will this volume contain 712801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 713801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function writes data to logical eraseblock @lnum of static volume 71489b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy * @vol. The @used_ebs argument should contain total number of logical 715801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * eraseblock in this static volume. 716801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 717801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * When writing to the last logical eraseblock, the @len argument doesn't have 718801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to be aligned to the minimal I/O unit size. Instead, it has to be equivalent 719801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to the real data size, although the @buf buffer has to contain the 720801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * alignment. In all other cases, @len has to be aligned. 721801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 722025dfdafe77f20b3890981a394774baab7b9c827Frederik Schwarzer * It is prohibited to write more than once to logical eraseblocks of static 723801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * volumes. This function returns zero in case of success and a negative error 724801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * code in case of failure. 725801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 72689b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiyint ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, 72789b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int lnum, const void *buf, int len, int dtype, 72889b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int used_ebs) 729801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 73089b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id; 731801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 732801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc; 733801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 734801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) 735801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 736801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 737801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (lnum == used_ebs - 1) 738801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* If this is the last LEB @len may be unaligned */ 739801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len = ALIGN(data_size, ubi->min_io_size); 740801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy else 741cadb40ccc16a26a738f1cbc963e35b21edd93e79Kyungmin Park ubi_assert(!(len & (ubi->min_io_size - 1))); 742801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 74333818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 744801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vid_hdr) 745801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 746801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 747801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = leb_write_lock(ubi, vol_id, lnum); 748801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 749801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 750801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 751801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 752801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 7533261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 7543261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->vol_id = cpu_to_be32(vol_id); 7553261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->lnum = cpu_to_be32(lnum); 756801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->compat = ubi_get_compat(ubi, vol_id); 7573261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_pad = cpu_to_be32(vol->data_pad); 758801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 759801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, buf, data_size); 760801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->vol_type = UBI_VID_STATIC; 7613261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_size = cpu_to_be32(data_size); 7623261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->used_ebs = cpu_to_be32(used_ebs); 7633261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_crc = cpu_to_be32(crc); 764801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 765801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 766801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = ubi_wl_get_peb(ubi, dtype); 767801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum < 0) { 768801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 769801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 770801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return pnum; 771801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 772801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 773801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("write VID hdr and %d bytes at LEB %d:%d, PEB %d, used_ebs %d", 774801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, vol_id, lnum, pnum, used_ebs); 775801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 776801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); 777801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 778801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", 779801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol_id, lnum, pnum); 780801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 781801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 782801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 783801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_data(ubi, buf, pnum, 0, len); 784801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 785801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write %d bytes of data to PEB %d", 786801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, pnum); 787801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 788801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 789801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 790801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(vol->eba_tbl[lnum] < 0); 791801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = pnum; 792801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 793801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 794801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 795801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 796801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 797801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiywrite_error: 798801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err != -EIO || !ubi->bad_allowed) { 799801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 800801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This flash device does not admit of bad eraseblocks or 801801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * something nasty and unexpected happened. Switch to read-only 802801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * mode just in case. 803801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 804801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 805801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 806801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 807801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 808801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 809801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 810801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_wl_put_peb(ubi, pnum, 1); 811801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err || ++tries > UBI_IO_RETRIES) { 812801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 813801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 814801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 815801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 816801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 817801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 8183261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 819801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("try another PEB"); 820801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 821801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 822801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 823801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/* 824801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_atomic_leb_change - change logical eraseblock atomically. 825801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 826c63a491d3737aec3c47c5e785d87021752ad9fa6Artem Bityutskiy * @vol: volume description object 827801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @lnum: logical eraseblock number 828801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @buf: data to write 829801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @len: how many bytes to write 830801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @dtype: data type 831801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 832801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function changes the contents of a logical eraseblock atomically. @buf 833801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * has to contain new logical eraseblock data, and @len - the length of the 834801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * data, which has to be aligned. This function guarantees that in case of an 835801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * unclean reboot the old contents is preserved. Returns zero in case of 836801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * success and a negative error code in case of failure. 837e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy * 838e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy * UBI reserves one LEB for the "atomic LEB change" operation, so only one 839e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. 840801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 84189b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiyint ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, 84289b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int lnum, const void *buf, int len, int dtype) 843801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 84489b96b69290668351a33b09372ec1c94cb5748e5Artem Bityutskiy int err, pnum, tries = 0, vol_id = vol->vol_id; 845801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr; 846801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc; 847801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 848801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->ro_mode) 849801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -EROFS; 850801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 85160c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy if (len == 0) { 85260c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy /* 85360c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy * Special case when data length is zero. In this case the LEB 85460c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy * has to be unmapped and mapped somewhere else. 85560c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy */ 85660c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy err = ubi_eba_unmap_leb(ubi, vol, lnum); 85760c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy if (err) 85860c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy return err; 85960c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); 86060c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy } 86160c031531a85b3580f66c2530f9b2802adcad4dfArtem Bityutskiy 86233818bbb84cd371b63ed8849cc5264d24c8b3aa2Artem Bityutskiy vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 863801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vid_hdr) 864801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return -ENOMEM; 865801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 866e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy mutex_lock(&ubi->alc_mutex); 867801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = leb_write_lock(ubi, vol_id, lnum); 868e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy if (err) 869e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy goto out_mutex; 870801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 8713261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 8723261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->vol_id = cpu_to_be32(vol_id); 8733261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->lnum = cpu_to_be32(lnum); 874801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->compat = ubi_get_compat(ubi, vol_id); 8753261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_pad = cpu_to_be32(vol->data_pad); 876801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 877801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy crc = crc32(UBI_CRC32_INIT, buf, len); 87884a925806210e002fab29966c09b9c92f382a79dArtem Bityutskiy vid_hdr->vol_type = UBI_VID_DYNAMIC; 8793261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_size = cpu_to_be32(len); 880801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->copy_flag = 1; 8813261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_crc = cpu_to_be32(crc); 882801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 883801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyretry: 884801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy pnum = ubi_wl_get_peb(ubi, dtype); 885801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (pnum < 0) { 886e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy err = pnum; 887e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy goto out_leb_unlock; 888801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 889801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 890801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", 891801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol_id, lnum, vol->eba_tbl[lnum], pnum); 892801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 893801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); 894801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 895801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", 896801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol_id, lnum, pnum); 897801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 898801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 899801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 900801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_data(ubi, buf, pnum, 0, len); 901801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 902801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("failed to write %d bytes of data to PEB %d", 903801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy len, pnum); 904801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto write_error; 905801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 906801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 907a443db48e05a8d2d8db0a17409655c58da65a35eArtem Bityutskiy if (vol->eba_tbl[lnum] >= 0) { 9084d88de4beb6f327dfc7c2221eab532dad5b2bb3eArtem Bityutskiy err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0); 909e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy if (err) 910e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy goto out_leb_unlock; 911801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 912801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 913801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = pnum; 914e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy 915e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiyout_leb_unlock: 916801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 917e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiyout_mutex: 918e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy mutex_unlock(&ubi->alc_mutex); 919801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_free_vid_hdr(ubi, vid_hdr); 920e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy return err; 921801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 922801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiywrite_error: 923801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err != -EIO || !ubi->bad_allowed) { 924801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 925801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This flash device does not admit of bad eraseblocks or 926801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * something nasty and unexpected happened. Switch to read-only 927801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * mode just in case. 928801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 929801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 930e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy goto out_leb_unlock; 931801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 932801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 933801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_wl_put_peb(ubi, pnum, 1); 934801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err || ++tries > UBI_IO_RETRIES) { 935801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_ro_mode(ubi); 936e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy goto out_leb_unlock; 937801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 938801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 9393261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 940801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_msg("try another PEB"); 941801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto retry; 942801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 943801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 944801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 9456b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * is_error_sane - check whether a read error is sane. 9466b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * @err: code of the error happened during reading 9476b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * 9486b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * This is a helper function for 'ubi_eba_copy_leb()' which is called when we 9496b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * cannot read data from the target PEB (an error @err happened). If the error 9506b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * code is sane, then we treat this error as non-fatal. Otherwise the error is 9516b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * fatal and UBI will be switched to R/O mode later. 9526b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * 9536b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * The idea is that we try not to switch to R/O mode if the read error is 9546b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * something which suggests there was a real read problem. E.g., %-EIO. Or a 9556b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * memory allocation failed (-%ENOMEM). Otherwise, it is safer to switch to R/O 9566b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * mode, simply because we do not know what happened at the MTD level, and we 9576b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * cannot handle this. E.g., the underlying driver may have become crazy, and 9586b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * it is safer to switch to R/O mode to preserve the data. 9596b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * 9606b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * And bear in mind, this is about reading from the target PEB, i.e. the PEB 9616b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy * which we have just written. 9626b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy */ 9636b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiystatic int is_error_sane(int err) 9646b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy{ 965786d78318586cbdc8aec539fe5a4942490267fefArtem Bityutskiy if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR || 966756e1df1d2b8b572a92dd1b82d2a432d5b280b1cArtem Bityutskiy err == UBI_IO_BAD_HDR_EBADMSG || err == -ETIMEDOUT) 9676b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy return 0; 9686b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy return 1; 9696b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy} 9706b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy 9716b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy/** 972801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * ubi_eba_copy_leb - copy logical eraseblock. 973801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 974801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @from: physical eraseblock number from where to copy 975801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @to: physical eraseblock number where to copy 976801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr: VID header of the @from physical eraseblock 977801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 978801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function copies logical eraseblock from physical eraseblock @from to 979801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * physical eraseblock @to. The @vid_hdr buffer may be changed by this 98043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * function. Returns: 9816fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy * o %0 in case of success; 982815bc5f8fe516f55291aef90f2142073821e7a9cArtem Bityutskiy * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, %MOVE_CANCEL_BITFLIPS, etc; 9836fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy * o a negative error code in case of failure. 984801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 985801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyint ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, 986801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_vid_hdr *vid_hdr) 987801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 98843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy int err, vol_id, lnum, data_size, aldata_size, idx; 989801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_volume *vol; 990801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy uint32_t crc; 991801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 9923261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vol_id = be32_to_cpu(vid_hdr->vol_id); 9933261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig lnum = be32_to_cpu(vid_hdr->lnum); 994801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 99587960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy dbg_wl("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to); 996801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 997801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vid_hdr->vol_type == UBI_VID_STATIC) { 9983261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig data_size = be32_to_cpu(vid_hdr->data_size); 999801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy aldata_size = ALIGN(data_size, ubi->min_io_size); 1000801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else 1001801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy data_size = aldata_size = 10023261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); 1003801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1004801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy idx = vol_id2idx(ubi, vol_id); 100543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy spin_lock(&ubi->volumes_lock); 1006801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 100743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * Note, we may race with volume deletion, which means that the volume 100843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * this logical eraseblock belongs to might be being deleted. Since the 10096fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy * volume deletion un-maps all the volume's logical eraseblocks, it will 101043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. 1011801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1012801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol = ubi->volumes[idx]; 101390bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy spin_unlock(&ubi->volumes_lock); 1014801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vol) { 101543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy /* No need to do further work, cancel */ 101687960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy dbg_wl("volume %d is being removed, cancel", vol_id); 101790bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy return MOVE_CANCEL_RACE; 1018801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1019801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 102043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy /* 102143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * We do not want anybody to write to this logical eraseblock while we 102243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * are moving it, so lock it. 102343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * 102443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * Note, we are using non-waiting locking here, because we cannot sleep 102543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * on the LEB, since it may cause deadlocks. Indeed, imagine a task is 102643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * unmapping the LEB which is mapped to the PEB we are going to move 102743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * (@from). This task locks the LEB and goes sleep in the 102843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are 102943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the 103090bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy * LEB is already locked, we just do not move it and return 1031e801e128b2200c40a0ec236cf2330b2586b6e05aBhavesh Parekh * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because 1032e801e128b2200c40a0ec236cf2330b2586b6e05aBhavesh Parekh * we do not know the reasons of the contention - it may be just a 1033e801e128b2200c40a0ec236cf2330b2586b6e05aBhavesh Parekh * normal I/O on this LEB, so we want to re-try. 103443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy */ 103543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy err = leb_write_trylock(ubi, vol_id, lnum); 103643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy if (err) { 103787960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum); 1038e801e128b2200c40a0ec236cf2330b2586b6e05aBhavesh Parekh return MOVE_RETRY; 1039801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1040801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 104143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy /* 104243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * The LEB might have been put meanwhile, and the task which put it is 104343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * probably waiting on @ubi->move_mutex. No need to continue the work, 104443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * cancel it. 104543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy */ 104643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy if (vol->eba_tbl[lnum] != from) { 104787960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy dbg_wl("LEB %d:%d is no longer mapped to PEB %d, mapped to " 104887960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy "PEB %d, cancel", vol_id, lnum, from, 104987960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy vol->eba_tbl[lnum]); 105090bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy err = MOVE_CANCEL_RACE; 105143f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_leb; 105243f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy } 1053801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 105443f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy /* 1055b77bcb07897f1a9cd9d1d78691896dcdb0fd1a22Zoltan Sogor * OK, now the LEB is locked and we can safely start moving it. Since 105690bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy * this function utilizes the @ubi->peb_buf1 buffer which is shared 105790bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy * with some other functions - we lock the buffer by taking the 105843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy * @ubi->buf_mutex. 105943f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy */ 106043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy mutex_lock(&ubi->buf_mutex); 106187960c0b12d0c5a0b37e0c79aef77aa1a0b10d44Artem Bityutskiy dbg_wl("read %d bytes of data", aldata_size); 1062e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); 1063801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err && err != UBI_IO_BITFLIPS) { 1064801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_warn("error %d while reading data from PEB %d", 1065801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err, from); 10666b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy err = MOVE_SOURCE_RD_ERR; 106743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 1068801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1069801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1070801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 1071fd589a8f0a13f53a2dd580b1fe170633cf6b095fAnand Gadiyar * Now we have got to calculate how much data we have to copy. In 1072801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * case of a static volume it is fairly easy - the VID header contains 1073801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the data size. In case of a dynamic volume it is more difficult - we 1074801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * have to read the contents, cut 0xFF bytes from the end and copy only 1075801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * the first part. We must do this to avoid writing 0xFF bytes as it 1076801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * may have some side-effects. And not only this. It is important not 1077801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * to include those 0xFFs to CRC because later the they may be filled 1078801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * by data. 1079801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1080801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (vid_hdr->vol_type == UBI_VID_DYNAMIC) 1081801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy aldata_size = data_size = 1082e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); 1083801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1084801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy cond_resched(); 1085e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); 1086801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy cond_resched(); 1087801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1088801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 108990bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy * It may turn out to be that the whole @from physical eraseblock 1090801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * contains only 0xFF bytes. Then we have to only write the VID header 1091801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * and do not write any data. This also means we should not set 1092801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @vid_hdr->copy_flag, @vid_hdr->data_size, and @vid_hdr->data_crc. 1093801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1094801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size > 0) { 1095801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vid_hdr->copy_flag = 1; 10963261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_size = cpu_to_be32(data_size); 10973261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->data_crc = cpu_to_be32(crc); 1098801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 10993261ebd7d4194ff30d0eae7ba8d937dcccf7235dChristoph Hellwig vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); 1100801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1101801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); 11026fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy if (err) { 11036fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy if (err == -EIO) 110490bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy err = MOVE_TARGET_WR_ERR; 110543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 11066fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy } 1107801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1108801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy cond_resched(); 1109801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1110801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* Read the VID header back and check if it was written correctly */ 1111801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); 1112801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 1113b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy if (err != UBI_IO_BITFLIPS) { 11146b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy ubi_warn("error %d while reading VID header back from " 11156b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy "PEB %d", err, to); 11166b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy if (is_error_sane(err)) 1117b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy err = MOVE_TARGET_RD_ERR; 1118b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy } else 111990bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy err = MOVE_CANCEL_BITFLIPS; 112043f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 1121801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1122801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1123801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (data_size > 0) { 1124e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); 11256fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy if (err) { 11266fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy if (err == -EIO) 112790bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy err = MOVE_TARGET_WR_ERR; 112843f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 11296fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy } 1130801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1131e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy cond_resched(); 1132e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy 1133801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 1134801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * We've written the data and are going to read it back to make 1135801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * sure it was written correctly. 1136801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1137801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1138e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); 1139801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (err) { 1140b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy if (err != UBI_IO_BITFLIPS) { 11416b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy ubi_warn("error %d while reading data back " 11426b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy "from PEB %d", err, to); 11436b5c94c6b4e1630a8e1ee7d30383d9396603749fArtem Bityutskiy if (is_error_sane(err)) 1144b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy err = MOVE_TARGET_RD_ERR; 1145b86a2c56e512f46d140a4bcb4e35e8a7d4a99a4bArtem Bityutskiy } else 114690bf0265e5b0d561f215a69bb7a46c4071b2c93bArtem Bityutskiy err = MOVE_CANCEL_BITFLIPS; 114743f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 1148801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1149801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1150801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy cond_resched(); 1151801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1152e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { 11536fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy ubi_warn("read data back from PEB %d and it is " 11546fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy "different", to); 11556fa6f5bbc3a2ad833a3d4b798140602004f70f5aArtem Bityutskiy err = -EINVAL; 115643f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiy goto out_unlock_buf; 1157801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1158801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1159801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1160801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_assert(vol->eba_tbl[lnum] == from); 1161801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[lnum] = to; 1162801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 116343f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiyout_unlock_buf: 1164e88d6e10e5c848fd5be8f89e09e3bce2570886b7Artem Bityutskiy mutex_unlock(&ubi->buf_mutex); 116543f9b25a9cdd7b177f77f026b1461abd1abbd174Artem Bityutskiyout_unlock_leb: 1166801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy leb_write_unlock(ubi, vol_id, lnum); 1167801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1168801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1169801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1170801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy/** 117164d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * print_rsvd_warning - warn about not having enough reserved PEBs. 117264d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * @ubi: UBI device description object 117364d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * 117464d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * This is a helper function for 'ubi_eba_init_scan()' which is called when UBI 117564d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * cannot reserve enough PEBs for bad block handling. This function makes a 117664d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * decision whether we have to print a warning or not. The algorithm is as 117764d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * follows: 117864d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * o if this is a new UBI image, then just print the warning 117964d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * o if this is an UBI image which has already been used for some time, print 118064d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * a warning only if we can reserve less than 10% of the expected amount of 118164d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * the reserved PEB. 118264d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * 118364d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * The idea is that when UBI is used, PEBs become bad, and the reserved pool 118464d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * of PEBs becomes smaller, which is normal and we do not want to scare users 118564d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * with a warning every time they attach the MTD device. This was an issue 118664d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * reported by real users. 118764d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy */ 118864d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiystatic void print_rsvd_warning(struct ubi_device *ubi, 118964d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy struct ubi_scan_info *si) 119064d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy{ 119164d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy /* 119264d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * The 1 << 18 (256KiB) number is picked randomly, just a reasonably 119364d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy * large number to distinguish between newly flashed and used images. 119464d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy */ 119564d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy if (si->max_sqnum > (1 << 18)) { 119664d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy int min = ubi->beb_rsvd_level / 10; 119764d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy 119864d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy if (!min) 119964d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy min = 1; 120064d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy if (ubi->beb_rsvd_pebs > min) 120164d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy return; 120264d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy } 120364d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy 120464d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d," 120564d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy " need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); 12065fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy if (ubi->corr_peb_count) 12075fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy ubi_warn("%d PEBs are corrupted and not used", 12085fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy ubi->corr_peb_count); 120964d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy} 121064d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy 121164d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy/** 121285c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy * ubi_eba_init_scan - initialize the EBA sub-system using scanning information. 1213801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @ubi: UBI device description object 1214801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * @si: scanning information 1215801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * 1216801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This function returns zero in case of success and a negative error code in 1217801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * case of failure. 1218801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1219801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyint ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) 1220801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy{ 1221801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy int i, j, err, num_volumes; 1222801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_scan_volume *sv; 1223801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_volume *vol; 1224801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct ubi_scan_leb *seb; 1225801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy struct rb_node *rb; 1226801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 122785c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy dbg_eba("initialize EBA sub-system"); 1228801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1229801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy spin_lock_init(&ubi->ltree_lock); 1230e8823bd63d50bb1f9bd73f1197230e1f7217456aArtem Bityutskiy mutex_init(&ubi->alc_mutex); 1231801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->ltree = RB_ROOT; 1232801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1233801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->global_sqnum = si->max_sqnum + 1; 1234801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; 1235801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1236801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy for (i = 0; i < num_volumes; i++) { 1237801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol = ubi->volumes[i]; 1238801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vol) 1239801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy continue; 1240801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1241801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy cond_resched(); 1242801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1243801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl = kmalloc(vol->reserved_pebs * sizeof(int), 1244801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy GFP_KERNEL); 1245801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!vol->eba_tbl) { 1246801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy err = -ENOMEM; 1247801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy goto out_free; 1248801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1249801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1250801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy for (j = 0; j < vol->reserved_pebs; j++) 1251801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[j] = UBI_LEB_UNMAPPED; 1252801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1253801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy sv = ubi_scan_find_sv(si, idx2vol_id(ubi, i)); 1254801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!sv) 1255801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy continue; 1256801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1257801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { 1258801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (seb->lnum >= vol->reserved_pebs) 1259801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* 1260801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * This may happen in case of an unclean reboot 1261801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy * during re-size. 1262801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy */ 1263801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_scan_move_to_list(sv, seb, &si->erase); 1264801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy vol->eba_tbl[seb->lnum] = seb->pnum; 1265801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1266801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1267801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 126894780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy if (ubi->avail_pebs < EBA_RESERVED_PEBS) { 126994780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy ubi_err("no enough physical eraseblocks (%d, need %d)", 127094780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy ubi->avail_pebs, EBA_RESERVED_PEBS); 12715fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy if (ubi->corr_peb_count) 12725fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy ubi_err("%d PEBs are corrupted and not used", 12735fc01ab6934c43b42c41bc753fe1123c16d7f38fArtem Bityutskiy ubi->corr_peb_count); 127494780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy err = -ENOSPC; 127594780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy goto out_free; 127694780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy } 127794780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy ubi->avail_pebs -= EBA_RESERVED_PEBS; 127894780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy ubi->rsvd_pebs += EBA_RESERVED_PEBS; 127994780d4de2e9339ab93df63420db70f11882634dArtem Bityutskiy 1280801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->bad_allowed) { 1281801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi_calculate_reserved(ubi); 1282801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1283801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (ubi->avail_pebs < ubi->beb_rsvd_level) { 1284801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy /* No enough free physical eraseblocks */ 1285801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->beb_rsvd_pebs = ubi->avail_pebs; 128664d4b4c90a876401e503c3a3260e9d0ed066f271Artem Bityutskiy print_rsvd_warning(ubi, si); 1287801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } else 1288801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->beb_rsvd_pebs = ubi->beb_rsvd_level; 1289801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1290801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->avail_pebs -= ubi->beb_rsvd_pebs; 1291801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy ubi->rsvd_pebs += ubi->beb_rsvd_pebs; 1292801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1293801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 129485c6e6e28259e9b58b8984db536c45bc3161f40cArtem Bityutskiy dbg_eba("EBA sub-system is initialized"); 1295801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return 0; 1296801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy 1297801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiyout_free: 1298801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy for (i = 0; i < num_volumes; i++) { 1299801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy if (!ubi->volumes[i]) 1300801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy continue; 1301801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy kfree(ubi->volumes[i]->eba_tbl); 13027194e6f9c083e87171ddfc8b746f05e007f58132Adrian Hunter ubi->volumes[i]->eba_tbl = NULL; 1303801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy } 1304801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy return err; 1305801c135ce73d5df1caf3eca35b66a10824ae0707Artem B. Bityutskiy} 1306