Hi, I've been chasing a problem with mounting a corrupted (by power loss) YAFFS2 filesystem. The mount would fail during the initial backward scan and as a result the system wouldn't boot. Traced it to a piece of code circa line 1226 of yaffs_yaffs2.c (hopefully enough context here for people to find it.) } else { /*HERE --> */ in->variant_type = tags.extra_obj_type; parent = yaffs_find_or_create_by_number(dev, tags.extra_parent_id, YAFFS_OBJECT_TYPE_DIRECTORY); file_size = tags.extra_length; is_shrink = tags.extra_is_shrink; equiv_id = tags.extra_equiv_id; in->lazy_loaded = 1; } in->dirty = 0; if (!parent) alloc_failed = 1; /* directory stuff... * hook up to parent */ Anyway this assignment changes the object type but does not make any changes or checks of the variant union within the object. In our case changing a directory to a plain file caused the linked list headers in the variant.dir_variant part of the union to become corrupt values in variant.file_variant.top_level. This in turn caused the next call to yaffs_put_chunk_in_file() on this object to fail and the entire backwards scan to be abandoned with a fatal error. One solution I've tried, and it works as far as getting to a login prompt, is to refuse the make the change if it would change a directory into something else. diff --git a/yaffs_yaffs2.c b/yaffs_yaffs2.c index 961f01e..46162de 100644 --- a/yaffs_yaffs2.c +++ b/yaffs_yaffs2.c @@ -1224,7 +1224,14 @@ static inline int yaffs2_scan_chunk(struct yaffs_dev *dev, is_shrink = oh->is_shrink; equiv_id = oh->equiv_id; } else { - in->variant_type = tags.extra_obj_type; + if ( in->variant_type != tags.extra_obj_type ) { + if ( in->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY ) + yaffs_trace(YAFFS_TRACE_ERROR, + "Cowardly refusing to convert directory for object %d", + tags.obj_id); + else + in->variant_type = tags.extra_obj_type; + } parent = yaffs_find_or_create_by_number(dev, tags.extra_parent_id, YAFFS_OBJECT_TYPE_DIRECTORY); An alternate that also works is to make the conversion and fixup the object's variant.file_variant structure at the same time. This was my preferred option until I started to think about what I should do if the directory had any children, orphan the children moving them to lost+found ? I think this points to a more general problem. Any changes to an object's variant_type should really require a check and potential fixup of the corresponding variant union. What does the team think ? -- Bob Dunlop