Cleanmarker length change in nandflash
Ricard Wanderlof
ricard.wanderlof at axis.com
Mon Mar 30 05:36:23 EDT 2009
Between Linux 2.6.23 and 2.6.24, the size of the jffs2 cleanmarker was
changed from 12 to 8 bytes (wbuf.c:OOB_CM_SIZE).
wbuf.c:jffs2_check_oob_empty() uses this constant when it's checking that
the oob is empty. Thus, if scanning an image written with Linux <= 2.6.23,
in Linux >= 2.6.24 it will consider the block as dirty since, there are
four extra zeros after the 8-byte cleanmarker.
This means that if one has a completely empty jffs2 image, written with
Linux <= 2.6.23, it will refuse to mount under Linux >= 2.6.24 . Mount
will fail with an I/O error (from scan.c:jffs2_scan_medium()), becuase
scan.c:jffs2_scan_eraseblock() will find all blocks dirty, but not one of
them containing a valid jffs2 node. As soon as there is a single data
note, it's not a problem, as it will find the data node and consider the
file system valid, ultimately allowing it to be mounted.
This is a problem in a system where there is a partition of the flash with
potential persistant data that must be maintained over kernel version
upgrades. If for some reason this partition is empty, it cannot be mounted
when going from Linux < 2.6.24 to >= 2.6.24 . While it would be possible
to implement a workaround in userspace when mounting the partition, it
seems to me that the underlaying problem should be fixed.
I can work on a patch, but I'd like a brief discussion first. Does jffs2
ever use the oob for anything else but cleanmarkers? Why does it matter to
jffs2 if the whole oob is empty or not? Wouldn't it suffice just to verify
the main memory array in the block (actually only 4KiB's are scanned
anyway), and the fact that a cleanmarker was present in the oob?
I.e. solution #1 would be to omit the call to jffs2_check_oob_empty() in
jffs2_scan_eraseblock, and simply set return BLK_STATE_ALLFF, even if the
oob wasn't empty. This would force the block to be erased later on and the
cleanmarker rewritten. However, I suspect the call to
jffs2_check_oob_empty() is there for a reason.
Solution #2 would be to add another state indicating that the block was
considered empty but should be erased anyway, but I thought that was what
BLK_STATE_ALLFF was for?
The call to jffs2_check_oob_empty() is inside an #ifdef
CONFIG_JFFS2_FS_WRITEBUFFER which I don't really understand either.
FS_WRITEBUFFER is required for NAND flash which have oobs but I suppose
could be enabled for NOR as well which doesn't.
Any thoughts?
/Ricard
--
Ricard Wolf Wanderlöf ricardw(at)axis.com
Axis Communications AB, Lund, Sweden www.axis.com
Phone +46 46 272 2016 Fax +46 46 13 61 30
More information about the linux-mtd
mailing list