Skip to contentSkip to conversation

Correct partition failed erase address

PATCH In review Adrian Hunter 3 participants 5 messages Mar 8, 2007 1 message not in the archive Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Correct partition failed erase address

If an erase operation fails, the address at which the failure occurred is returned by the driver. The MTD partition must adjust this address (by subtracting the partition offset) before returning to the caller. This was not happening, which caused JFFS2 to mark the wrong block bad!

---
drivers/mtd/mtdpart.c | 6 +++++-

1 files changed, 5 insertions(+), 1 deletions(-)
drivers/mtd/mtdpart.c +0 -0
index 633def3..476fbb6 100644
@@ -200,6 +200,11 @@ static int part_erase (struct mtd_info *
		return -EINVAL;
	instr->addr += part->offset;
	ret = part->master->erase(part->master, instr);

+ if (ret) {
+ if (instr->fail_addr != 0xffffffff)
+ instr->fail_addr -= part->offset;
+ instr->addr -= part->offset;
+ }

	return ret;
}

@@ -559,4 +564,3 @@ EXPORT_SYMBOL_GPL(deregister_mtd_parser) MODULE_LICENSE("GPL");
MODULE_AUTHOR("Nicolas Pitre <[email protected]>"); MODULE_DESCRIPTION("Generic support for partitioning of MTD devices"); -

Signature · 1 line
1.4.3
#1 lore raw
Quoted 17 lines · Adrian Hunter

If an erase operation fails, the address at which the failure occurred is returned by the driver. The MTD partition must adjust this address (by subtracting the partition offset) before returning to the caller. This was not happening, which caused JFFS2 to mark the wrong block bad!

---
 drivers/mtd/mtdpart.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/mtd/mtdpart.c +0 -0
index 633def3..476fbb6 100644

drivers/mtd/mtdpart.c static int part_erase (struct mtd_info * · line 209

Quoted 10 lines
drivers/mtd/mtdpart.c +5 -0
@@ -200,6 +200,11 @@ static int part_erase (struct mtd_info *
 		return -EINVAL;
 	instr->addr += part->offset;
 	ret = part->master->erase(part->master, instr);
+	if (ret) {
+		if (instr->fail_addr != 0xffffffff)
+			instr->fail_addr -= part->offset;
+		instr->addr -= part->offset;
+	}
 	return ret;
 }

Erase isn't always synchronous. It can return success (i.e. erase queued successfully) and later call the callback with an indication of failure.

Signature · 1 line
dwmw2
#2 lore raw
Quoted 3 lines · David Woodhouse

Erase isn't always synchronous. It can return success (i.e. erase queued successfully) and later call the callback with an indication of failure.

... and mtd_erase_callback() already subtracts the necessary offset.

I really don't like our API very much, but it doesn't seem to be broken in this particular way.

When we fix things to cope with flash larger than 4GiB, I think we should make larger changes to the way that partitioning works as well as reconsidering the read/write/erase API.

Signature · 1 line
dwmw2

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw
Quoted 5 lines · Adrian Hunter
Quoted 4 lines · ext David Woodhouse
Quoted 2 lines · David Woodhouse

Erase isn't always synchronous. It can return success (i.e. erase queued successfully) and later call the callback with an indication of failure.

Quoted 7 lines
Quoted 4 lines

... and mtd_erase_callback() already subtracts the necessary offset.

I really don't like our API very much, but it doesn't seem to be broken in this particular way.

Yes it is broken. Both when the callback is not used at all, and when an error occurs immediately and the callback is not called.

Ew, you're right -- and the API is worse than I thought.

Sorry (on both counts) :)

Signature · 1 line
dwmw2
#5 lore raw
Quoted 2 lines · David Woodhouse

Ew, you're right -- and the API is worse than I thought.

And the API is _never_ used asynchronously. For current drivers, it is pure overhead.

Jörn

Signature · 2 lines
Joern's library part 1:
http://lwn.net/Articles/2.6-kernel-api/