@@ -902,6 +902,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
mutex_init(&ubi->buf_mutex);
mutex_init(&ubi->ckvol_mutex);
mutex_init(&ubi->device_mutex);
+ mutex_init(&ubi->fm_pool_mutex);
mutex_init(&ubi->fm_mutex);
spin_lock_init(&ubi->volumes_lock);
@@ -383,6 +383,7 @@ struct ubi_wl_entry;
* @old_fm: in-memory data structure old fastmap.
* (only valid while writing a new one)
* @fm_pool: in-memory data structure of the fastmap pool
+ * @fm_pool_mutex: serializes ubi_wl_get_peb()
* @fm_mutex: serializes ubi_update_fastmap()
* @attached_by_scanning: this UBI device was attached by the old scanning
* methold. All fastmap volumes have to be deleted.
@@ -483,6 +484,7 @@ struct ubi_device {
struct ubi_fastmap_layout *old_fm;
struct ubi_fm_pool fm_pool;
struct mutex fm_mutex;
+ struct mutex fm_pool_mutex;
int attached_by_scanning;
/* Wear-leveling sub-system's stuff */
@@ -520,6 +520,8 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
struct ubi_fm_pool *pool = &ubi->fm_pool;
int ret;
+ mutex_lock(&ubi->fm_pool_mutex);
+
/* pool contains no free blocks, create a new one
* and write a fastmap */
if (pool->used == pool->size || !pool->size) {
@@ -534,10 +536,12 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
ret = ubi_update_fastmap(ubi);
if (ret) {
ubi_ro_mode(ubi);
+ mutex_unlock(&ubi->fm_pool_mutex);
return ret > 0 ? -EINVAL : ret;
}
}
+ mutex_unlock(&ubi->fm_pool_mutex);
/* we got not a single free PEB */
if (!pool->size)
Signed-off-by: Richard Weinberger <richard@nod.at> --- drivers/mtd/ubi/build.c | 1 + drivers/mtd/ubi/ubi.h | 2 ++ drivers/mtd/ubi/wl.c | 4 ++++ 3 files changed, 7 insertions(+), 0 deletions(-)