mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
![Sascha Hauer](/assets/img/avatar_default.png)
When a new fastmap is about to be written UBI must make sure it has a free block for a fastmap anchor available. For this ubi_update_fastmap() calls ubi_ensure_anchor_pebs(). This stopped working with2e8f08deab
("ubi: Fix races around ubi_refill_pools()"), with this commit the wear leveling code is blocked and can no longer produce free PEBs. UBI then more often than not falls back to write the new fastmap anchor to the same block it was already on which means the same erase block gets erased during each fastmap write and wears out quite fast. As the locking prevents us from producing the anchor PEB when we actually need it, this patch changes the strategy for creating the anchor PEB. We no longer create it on demand right before we want to write a fastmap, but instead we create an anchor PEB right after we have written a fastmap. This gives us enough time to produce a new anchor PEB before it is needed. To make sure we have an anchor PEB for the very first fastmap write we call ubi_ensure_anchor_pebs() during initialisation as well. Fixes:2e8f08deab
("ubi: Fix races around ubi_refill_pools()") Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Richard Weinberger <richard@nod.at>
28 lines
1.2 KiB
C
28 lines
1.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef UBI_WL_H
|
|
#define UBI_WL_H
|
|
#ifdef CONFIG_MTD_UBI_FASTMAP
|
|
static void update_fastmap_work_fn(struct work_struct *wrk);
|
|
static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
|
|
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
|
|
static void ubi_fastmap_close(struct ubi_device *ubi);
|
|
static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
|
|
{
|
|
/* Reserve enough LEBs to store two fastmaps. */
|
|
*count += (ubi->fm_size / ubi->leb_size) * 2;
|
|
INIT_WORK(&ubi->fm_work, update_fastmap_work_fn);
|
|
}
|
|
static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
|
|
struct ubi_wl_entry *e,
|
|
struct rb_root *root);
|
|
#else /* !CONFIG_MTD_UBI_FASTMAP */
|
|
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
|
|
static inline void ubi_fastmap_close(struct ubi_device *ubi) { }
|
|
static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) { }
|
|
static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
|
|
struct ubi_wl_entry *e,
|
|
struct rb_root *root) {
|
|
return e;
|
|
}
|
|
#endif /* CONFIG_MTD_UBI_FASTMAP */
|
|
#endif /* UBI_WL_H */
|