@@ -59,6 +59,14 @@ config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
This option emulates write failures with probability 1/100. Useful for
debugging and testing how UBI handlines errors.
+config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES_SAFE_ERASE
+ bool "Prevent write failure during the sync erase"
+ depends on MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
+ default n
+ help
+ This option prevents write failures during the sync erase that may
+ cause marking the block as bad.
+
config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES
bool "Emulate flash erase failures"
depends on MTD_UBI_DEBUG
@@ -194,6 +194,23 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
}
+#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
+/**
+ * ubi_dbg_is_write_failure - if it is time to emulate a write failure.
+ *
+ * Returns non-zero if a write failure should be emulated, otherwise returns
+ * zero.
+ */
+int ubi_dbg_is_write_failure(struct ubi_device *ubi)
+{
+#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES_SAFE_ERASE
+ return (!ubi->write_failure_masked && !(random32() % 500));
+#else
+ return !(random32() % 500);
+#endif
+}
+#endif
+
#endif /* CONFIG_MTD_UBI_DEBUG */
/*
@@ -114,18 +114,9 @@ static inline int ubi_dbg_is_bitflip(void)
#endif
#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
-/**
- * ubi_dbg_is_write_failure - if it is time to emulate a write failure.
- *
- * Returns non-zero if a write failure should be emulated, otherwise returns
- * zero.
- */
-static inline int ubi_dbg_is_write_failure(void)
-{
- return !(random32() % 500);
-}
+int ubi_dbg_is_write_failure(struct ubi_device *ubi);
#else
-#define ubi_dbg_is_write_failure() 0
+#define ubi_dbg_is_write_failure(ubi) 0
#endif
#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES
@@ -165,7 +156,7 @@ static inline int ubi_dbg_is_erase_failure(void)
#define UBI_IO_DEBUG 0
#define DBG_DISABLE_BGT 0
#define ubi_dbg_is_bitflip() 0
-#define ubi_dbg_is_write_failure() 0
+#define ubi_dbg_is_write_failure(ubi) 0
#define ubi_dbg_is_erase_failure() 0
#endif /* !CONFIG_MTD_UBI_DEBUG */
@@ -259,7 +259,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
return err > 0 ? -EINVAL : err;
}
- if (ubi_dbg_is_write_failure()) {
+ if (ubi_dbg_is_write_failure(ubi)) {
dbg_err("cannot write %d bytes to PEB %d:%d "
"(emulated)", len, pnum, offset);
ubi_dbg_dump_stack();
@@ -438,6 +438,9 @@ struct ubi_device {
#ifdef CONFIG_MTD_UBI_DEBUG
void *dbg_peb_buf;
struct mutex dbg_buf_mutex;
+#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES_SAFE_ERASE
+ int write_failure_masked;
+#endif
#endif
};
@@ -615,10 +615,15 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
ec_hdr->ec = cpu_to_be64(ec);
+#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES_SAFE_ERASE
+ ubi->write_failure_masked = 1;
+#endif
+
err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr);
if (err)
goto out_free;
+
e->ec = ec;
spin_lock(&ubi->wl_lock);
if (e->ec > ubi->max_ec)
@@ -626,6 +631,9 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
spin_unlock(&ubi->wl_lock);
out_free:
+#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES_SAFE_ERASE
+ ubi->write_failure_masked = 0;
+#endif
kfree(ec_hdr);
return err;
}