Index: nodemgmt.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/nodemgmt.c,v retrieving revision 1.6 diff -w -u -r1.6 nodemgmt.c --- nodemgmt.c 11 Dec 2003 23:33:54 -0000 1.6 +++ nodemgmt.c 13 Jul 2004 13:35:44 -0000 @@ -549,6 +549,60 @@ printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); return; } + + // Merge obsolete nodes into its previous node, i.e. always leave + // one node behind so as not to screw up ref_totlen() + if (ref->next_in_ino!=NULL) + { + bool moreToDo; + do { + moreToDo=false; + struct jffs2_inode_cache *ic; + ic = jffs2_raw_ref_to_ic(ref); + + // unlink the node and + struct jffs2_raw_node_ref *raw; + struct jffs2_raw_node_ref *prev=NULL; + raw = ic->nodes; + for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) { + // if this node *and* the previous *physical node* are obsolete, combine them. + if ((prev!=NULL)&&ref_obsolete(raw)) { + // now take take it off the physcial list, unless it is the + // first node. + struct jffs2_raw_node_ref *t; + struct jffs2_raw_node_ref *phys_prev=NULL; + t=jeb->first_node; + while (t!=NULL) { + if ((phys_prev!=NULL)&&(t==raw)&&ref_obsolete(prev)) { + // take it off the inode list. + prev->next_in_ino=t->next_in_ino; + + // take it off the physical list + phys_prev->next_phys=t->next_phys; + // update last physical entry pointer... + if (jeb->last_node==t) { + jeb->last_node=t->next_phys; + } + + // update physical __totlen field. + phys_prev->__totlen+=t->__totlen; + + + jffs2_free_raw_node_ref(raw); + moreToDo=true; + + break; + } + phys_prev=t; + t=t->next_phys; + } + break; + } + prev=raw; + } + } while (moreToDo); + } + } #if CONFIG_JFFS2_FS_DEBUG > 0