diff options
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/eba.c | 21 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/misc.c | 49 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 18 |
4 files changed, 81 insertions, 8 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 5b9834cf2..96fddb016 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -426,8 +426,25 @@ retry: pnum, vol_id, lnum); err = -EBADMSG; } else { - err = -EINVAL; - ubi_ro_mode(ubi); + /* + * Ending up here in the non-Fastmap case + * is a clear bug as the VID header had to + * be present at scan time to have it referenced. + * With fastmap the story is more complicated. + * Fastmap has the mapping info without the need + * of a full scan. So the LEB could have been + * unmapped, Fastmap cannot know this and keeps + * the LEB referenced. + * This is valid and works as the layer above UBI + * has to do bookkeeping about used/referenced + * LEBs in any case. + */ + if (ubi->fast_attach) { + err = -EBADMSG; + } else { + err = -EINVAL; + ubi_ro_mode(ubi); + } } } goto out_free; diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 263b439e2..990898b9d 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ubi_msg(ubi, "fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); ubi->fm_disabled = 0; + ubi->fast_attach = 1; ubi_free_vid_hdr(ubi, vh); kfree(ech); diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index 2a45ac210..989036c68 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -153,3 +153,52 @@ int ubi_check_pattern(const void *buf, uint8_t patt, int size) return 0; return 1; } + +/* Normal UBI messages */ +void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_notice(UBI_NAME_STR "%d: %pV\n", ubi->ubi_num, &vaf); + + va_end(args); +} + +/* UBI warning messages */ +void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_warn(UBI_NAME_STR "%d warning: %ps: %pV\n", + ubi->ubi_num, __builtin_return_address(0), &vaf); + + va_end(args); +} + +/* UBI error messages */ +void ubi_err(const struct ubi_device *ubi, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_err(UBI_NAME_STR "%d error: %ps: %pV\n", + ubi->ubi_num, __builtin_return_address(0), &vaf); + va_end(args); +} diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 2974b67f6..61d4e9975 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -49,15 +49,19 @@ /* UBI name used for character devices, sysfs, etc */ #define UBI_NAME_STR "ubi" +struct ubi_device; + /* Normal UBI messages */ -#define ubi_msg(ubi, fmt, ...) pr_notice(UBI_NAME_STR "%d: " fmt "\n", \ - ubi->ubi_num, ##__VA_ARGS__) +__printf(2, 3) +void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...); + /* UBI warning messages */ -#define ubi_warn(ubi, fmt, ...) pr_warn(UBI_NAME_STR "%d warning: %s: " fmt "\n", \ - ubi->ubi_num, __func__, ##__VA_ARGS__) +__printf(2, 3) +void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...); + /* UBI error messages */ -#define ubi_err(ubi, fmt, ...) pr_err(UBI_NAME_STR "%d error: %s: " fmt "\n", \ - ubi->ubi_num, __func__, ##__VA_ARGS__) +__printf(2, 3) +void ubi_err(const struct ubi_device *ubi, const char *fmt, ...); /* Background thread name pattern */ #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" @@ -462,6 +466,7 @@ struct ubi_debug_info { * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes * @fm_work: fastmap work queue * @fm_work_scheduled: non-zero if fastmap work was scheduled + * @fast_attach: non-zero if UBI was attached by fastmap * * @used: RB-tree of used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks @@ -570,6 +575,7 @@ struct ubi_device { size_t fm_size; struct work_struct fm_work; int fm_work_scheduled; + int fast_attach; /* Wear-leveling sub-system's stuff */ struct rb_root used; |