Patchwork Emulated write failures cause block marking as bad

login
register
mail settings
Submitter Marek Skuczynski
Date Feb. 5, 2010, 9:23 a.m.
Message ID <a328840c1002050123u15be6d75s1c6f27fca6452137@mail.gmail.com>
Download mbox | patch
Permalink /patch/44617/
State New
Headers show

Comments

Marek Skuczynski - Feb. 5, 2010, 9:23 a.m.
> Okay, maybe my case is isolated because of tested system configuration,
> I will try manage this case myself.
>
I have prepared a patch, maybe someone will find it useful.
Artem Bityutskiy - Feb. 15, 2010, 2:10 p.m.
On Fri, 2010-02-05 at 10:23 +0100, Marek Skuczynski wrote:
> > Okay, maybe my case is isolated because of tested system configuration,
> > I will try manage this case myself.
> >
> I have prepared a patch, maybe someone will find it useful.

Something like this is useful, but I disapprove of adding another
configuration option. Instead, I think you should just improve the
current debugging code.

Patch

diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug
index 1e2ee22..fa1a92c 100644
--- a/drivers/mtd/ubi/Kconfig.debug
+++ b/drivers/mtd/ubi/Kconfig.debug
@@ -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
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index c949cb4..8ff0d6a 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -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 */
 
 /*
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index fa4cffe..ff77a26 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -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 */
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 2904991..c164299 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -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();
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index d8f5915..1194549 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -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
 };
 
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index dc38fc5..6799c25 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -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;
 }