2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  JFFS2  - -  Journalling  Flash  File  System ,  Version  2. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  2001 - 2003  Red  Hat ,  Inc . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Created  by  David  Woodhouse  < dwmw2 @ infradead . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  For  licensing  information ,  see  the  file  ' LICENCE '  in  this  directory . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  $ Id :  nodelist . c , v  1.115  2005 / 11 / 07  11 : 14 : 40  gleixner  Exp  $ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/kernel.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/sched.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/fs.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/mtd/mtd.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/rbtree.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/crc32.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/slab.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/pagemap.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "nodelist.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_add_fd_to_list ( struct  jffs2_sb_info  * c ,  struct  jffs2_full_dirent  * new ,  struct  jffs2_full_dirent  * * list )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_full_dirent  * * prev  =  list ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_dentlist ( " add dirent  \" %s \" , ino #%u \n " ,  new - > name ,  new - > ino ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( * prev )  & &  ( * prev ) - > nhash  < =  new - > nhash )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( * prev ) - > nhash  = =  new - > nhash  & &  ! strcmp ( ( * prev ) - > name ,  new - > name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Duplicate. Free one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( new - > version  <  ( * prev ) - > version )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_dentlist ( " Eep! Marking new dirent node is obsolete, old is  \" %s \" , ino #%u \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													( * prev ) - > name ,  ( * prev ) - > ino ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												jffs2_mark_node_obsolete ( c ,  new - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_free_full_dirent ( new ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_dentlist ( " marking old dirent  \" %s \" , ino #%u bsolete \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													( * prev ) - > name ,  ( * prev ) - > ino ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												new - > next  =  ( * prev ) - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_mark_node_obsolete ( c ,  ( ( * prev ) - > raw ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_free_full_dirent ( * prev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												* prev  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev  =  & ( ( * prev ) - > next ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new - > next  =  * prev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* prev  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-31 09:20:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  jffs2_truncate_fragtree ( struct  jffs2_sb_info  * c ,  struct  rb_root  * list ,  uint32_t  size )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * frag  =  jffs2_lookup_node_frag ( list ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree ( " truncating fragtree to 0x%08x bytes \n " ,  size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-31 09:20:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* We know frag->ofs <= size. That's what lookup does for us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frag  & &  frag - > ofs  ! =  size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( frag - > ofs + frag - > size  >  size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-31 09:20:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											frag - > size  =  size  -  frag - > ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frag  =  frag_next ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( frag  & &  frag - > ofs  > =  size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  jffs2_node_frag  * next  =  frag_next ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frag_erase ( frag ,  list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_obsolete_node_frag ( c ,  frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frag  =  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( size  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  If  the  last  fragment  starts  at  the  RAM  page  boundary ,  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  REF_PRISTINE  irrespective  of  its  size . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									frag  =  frag_last ( list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-22 10:07:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( frag - > node  & &  ( frag - > ofs  &  ( PAGE_CACHE_SIZE  -  1 ) )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " marking the last fragment 0x%08x-0x%08x REF_PRISTINE. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											frag - > ofs ,  frag - > ofs  +  frag - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										frag - > node - > raw - > flash_offset  =  ref_offset ( frag - > node - > raw )  |  REF_PRISTINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-31 09:20:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  jffs2_obsolete_node_frag ( struct  jffs2_sb_info  * c ,  struct  jffs2_node_frag  * this )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( this - > node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										this - > node - > frags - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! this - > node - > frags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* The node has no valid frags left. It's totally obsoleted */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " marking old node @0x%08x (0x%04x-0x%04x) obsolete \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ref_offset ( this - > node - > raw ) ,  this - > node - > ofs ,  this - > node - > ofs + this - > node - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											jffs2_mark_node_obsolete ( c ,  this - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_full_dnode ( this - > node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ref_offset ( this - > node - > raw ) ,  this - > node - > ofs ,  this - > node - > ofs + this - > node - > size ,  this - > node - > frags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mark_ref_normal ( this - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									jffs2_free_node_frag ( this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  jffs2_fragtree_insert ( struct  jffs2_node_frag  * newfrag ,  struct  jffs2_node_frag  * base )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  rb_node  * parent  =  & base - > rb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rb_node  * * link  =  & parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 22:03:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree2 ( " insert frag (0x%04x-0x%04x) \n " ,  newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 22:03:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( * link )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parent  =  * link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										base  =  rb_entry ( parent ,  struct  jffs2_node_frag ,  rb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( newfrag - > ofs  >  base - > ofs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											link  =  & base - > rb . rb_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( newfrag - > ofs  <  base - > ofs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											link  =  & base - > rb . rb_left ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 22:03:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											JFFS2_ERROR ( " duplicate frag at %08x (%p,%p) \n " ,  newfrag - > ofs ,  newfrag ,  base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BUG ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 22:03:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rb_link_node ( & newfrag - > rb ,  & base - > rb ,  link ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Allocate  and  initializes  a  new  fragment . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-14 13:20:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  jffs2_node_frag  *  new_fragment ( struct  jffs2_full_dnode  * fn ,  uint32_t  ofs ,  uint32_t  size )  
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * newfrag ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newfrag  =  jffs2_alloc_node_frag ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( likely ( newfrag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newfrag - > ofs  =  ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newfrag - > size  =  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newfrag - > node  =  fn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										JFFS2_ERROR ( " cannot allocate a jffs2_node_frag object \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newfrag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  when  there  is  no  overlapping  fragment  exist .  Inserts  a  hole  before  the  new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  fragment  and  inserts  the  new  fragment  to  the  fragtree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  no_overlapping_node ( struct  jffs2_sb_info  * c ,  struct  rb_root  * root ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 	       struct  jffs2_node_frag  * newfrag , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       struct  jffs2_node_frag  * this ,  uint32_t  lastend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( lastend  <  newfrag - > node - > ofs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* put a hole in before the new fragment */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  jffs2_node_frag  * holefrag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										holefrag =  new_fragment ( NULL ,  lastend ,  newfrag - > node - > ofs  -  lastend ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( unlikely ( ! holefrag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_node_frag ( newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* By definition, the 'this' node has no right-hand child,
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   because  there  are  no  frags  with  offset  greater  than  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   So  that ' s  where  we  want  to  put  the  hole  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " add hole frag %#04x-%#04x on the right of the new frag. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												holefrag - > ofs ,  holefrag - > ofs  +  holefrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_link_node ( & holefrag - > rb ,  & this - > rb ,  & this - > rb . rb_right ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " Add hole frag %#04x-%#04x to the root of the tree. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												holefrag - > ofs ,  holefrag - > ofs  +  holefrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_link_node ( & holefrag - > rb ,  NULL ,  & root - > rb_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rb_insert_color ( & holefrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										this  =  holefrag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* By definition, the 'this' node has no right-hand child,
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										   because  there  are  no  frags  with  offset  greater  than  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   So  that ' s  where  we  want  to  put  new  fragment  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " add the new node at the right \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rb_link_node ( & newfrag - > rb ,  & this - > rb ,  & this - > rb . rb_right ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " insert the new node at the root of the tree \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rb_link_node ( & newfrag - > rb ,  NULL ,  & root - > rb_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Doesn't set inode->i_size */  
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  jffs2_add_frag_to_fragtree ( struct  jffs2_sb_info  * c ,  struct  rb_root  * root ,  struct  jffs2_node_frag  * newfrag )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  lastend ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Skip all the nodes which are completed before this one starts */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									this  =  jffs2_lookup_node_frag ( root ,  newfrag - > node - > ofs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											  this - > ofs ,  this - > ofs + this - > size ,  this - > node ? ( ref_offset ( this - > node - > raw ) ) : 0xffffffff ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										lastend  =  this - > ofs  +  this - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " lookup gave no frag \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										lastend  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* See if we ran off the end of the fragtree */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( lastend  < =  newfrag - > ofs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We did */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Check if 'this' node was on the same page as the new node.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   If  so ,  both  ' this '  and  the  new  node  get  marked  REF_NORMAL  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   the  GC  can  take  a  look . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( lastend  & &  ( lastend - 1 )  > >  PAGE_CACHE_SHIFT  = =  newfrag - > ofs  > >  PAGE_CACHE_SHIFT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( this - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mark_ref_normal ( this - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mark_ref_normal ( newfrag - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  no_overlapping_node ( c ,  root ,  newfrag ,  this ,  lastend ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( this - > node ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " dealing with frag %u-%u, phys %#08x(%d). \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										this - > ofs ,  this - > ofs  +  this - > size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ref_offset ( this - > node - > raw ) ,  ref_flags ( this - > node - > raw ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " dealing with hole frag %u-%u. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										this - > ofs ,  this - > ofs  +  this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  -  i . e .  newfrag - > ofs  <  this - > ofs + this - > size  & &  newfrag - > ofs  > =  this - > ofs 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( newfrag - > ofs  >  this - > ofs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* This node isn't completely obsoleted. The start of it remains valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Mark the new node and the partially covered node REF_NORMAL -- let
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   the  GC  take  a  look  at  them  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark_ref_normal ( newfrag - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( this - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mark_ref_normal ( this - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( this - > ofs  +  this - > size  >  newfrag - > ofs  +  newfrag - > size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* The new node splits 'this' frag into two */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  jffs2_node_frag  * newfrag2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( this - > node ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " split old frag 0x%04x-0x%04x, phys 0x%08x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													this - > ofs ,  this - > ofs + this - > size ,  ref_offset ( this - > node - > raw ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " split old hole frag 0x%04x-0x%04x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-17 15:13:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													this - > ofs ,  this - > ofs + this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* New second frag pointing to this's node */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											newfrag2  =  new_fragment ( this - > node ,  newfrag - > ofs  +  newfrag - > size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														this - > ofs  +  this - > size  -  newfrag - > ofs  -  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( unlikely ( ! newfrag2 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( this - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												this - > node - > frags + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Adjust size of original 'this' */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											this - > size  =  newfrag - > ofs  -  this - > ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Now, we know there's no node with offset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   greater  than  this - > ofs  but  smaller  than 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   newfrag2 - > ofs  or  newfrag - > ofs ,  for  obvious 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   reasons .  So  we  can  do  a  tree  insert  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   ' this '  to  insert  newfrag ,  and  a  tree  insert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   from  newfrag  to  insert  newfrag2 .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_fragtree_insert ( newfrag ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											jffs2_fragtree_insert ( newfrag2 ,  newfrag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rb_insert_color ( & newfrag2 - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* New node just reduces 'this' frag in size, doesn't split it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										this - > size  =  newfrag - > ofs  -  this - > ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Again, we know it lives down here in the tree */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_fragtree_insert ( newfrag ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* New frag starts at the same point as 'this' used to. Replace
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										   it  in  the  tree  without  doing  a  delete  and  insertion  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											  newfrag ,  newfrag - > ofs ,  newfrag - > ofs + newfrag - > size ,  this ,  this - > ofs ,  this - > ofs + this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rb_replace_node ( & this - > rb ,  & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( newfrag - > ofs  +  newfrag - > size  > =  this - > ofs + this - > size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " obsoleting node frag %p (%x-%x) \n " ,  this ,  this - > ofs ,  this - > ofs + this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											jffs2_obsolete_node_frag ( c ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											this - > ofs  + =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											this - > size  - =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_fragtree_insert ( this ,  newfrag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rb_insert_color ( & this - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* OK, now we have newfrag added in the correct place in the tree, but
 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									   frag_next ( newfrag )  may  be  a  fragment  which  is  overlapped  by  it 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( this  =  frag_next ( newfrag ) )  & &  newfrag - > ofs  +  newfrag - > size  > =  this - > ofs  +  this - > size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* 'this' frag is obsoleted completely. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " obsoleting node frag %p (%x-%x) and removing from tree \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											this ,  this - > ofs ,  this - > ofs + this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rb_erase ( & this - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										jffs2_obsolete_node_frag ( c ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Now we're pointing at the first frag which isn't totally obsoleted by
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									   the  new  frag  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! this  | |  newfrag - > ofs  +  newfrag - > size  = =  this - > ofs ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Still some overlap but we don't need to move it in the tree */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									this - > size  =  ( this - > ofs  +  this - > size )  -  ( newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									this - > ofs  =  newfrag - > ofs  +  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* And mark them REF_NORMAL so the GC takes a look at them */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( this - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark_ref_normal ( this - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mark_ref_normal ( newfrag - > node - > raw ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Given  an  inode ,  probably  with  existing  tree  of  fragments ,  add  the  new  node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  the  fragment  tree . 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  jffs2_add_full_dnode_to_inode ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_info  * f ,  struct  jffs2_full_dnode  * fn )  
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * newfrag ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( unlikely ( ! fn - > size ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 11:13:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newfrag  =  new_fragment ( fn ,  fn - > ofs ,  fn - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( unlikely ( ! newfrag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newfrag - > node - > frags  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree ( " adding node %#04x-%#04x @0x%08x on flash, newfrag *%p \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										  fn - > ofs ,  fn - > ofs + fn - > size ,  ref_offset ( fn - > raw ) ,  newfrag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ret  =  jffs2_add_frag_to_fragtree ( c ,  & f - > fragtree ,  newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( unlikely ( ret ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we now share a page with other nodes, mark either previous
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   or  next  node  REF_NORMAL ,  as  appropriate .   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( newfrag - > ofs  &  ( PAGE_CACHE_SIZE - 1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  jffs2_node_frag  * prev  =  frag_prev ( newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark_ref_normal ( fn - > raw ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* If we don't start at zero there's _always_ a previous */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( prev - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mark_ref_normal ( prev - > node - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( newfrag - > ofs + newfrag - > size )  &  ( PAGE_CACHE_SIZE - 1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  jffs2_node_frag  * next  =  frag_next ( newfrag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mark_ref_normal ( fn - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( next - > node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mark_ref_normal ( next - > node - > raw ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									jffs2_dbg_fragtree_paranoia_check_nolock ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Check  the  data  CRC  of  the  node . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns :  0  if  the  data  CRC  is  correct ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  	    1  -  if  incorrect ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	    error  code  if  an  error  occured . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  check_node_data ( struct  jffs2_sb_info  * c ,  struct  jffs2_tmp_dnode_info  * tn )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_raw_node_ref  * ref  =  tn - > fn - > raw ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  0 ,  pointed  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_eraseblock  * jeb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  * buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  crc ,  ofs ,  retlen ,  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( tn - > csize  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! jffs2_is_writebuffered ( c ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  adj_acc ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Calculate how many bytes were already checked */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ofs  =  ref_offset ( ref )  +  sizeof ( struct  jffs2_raw_inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									len  =  ofs  %  c - > wbuf_pagesize ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-17 15:57:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( likely ( len ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										len  =  c - > wbuf_pagesize  -  len ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( len  > =  tn - > csize )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_readinode ( " no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ref_offset ( ref ) ,  tn - > csize ,  ofs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  adj_acc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ofs  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  =  tn - > csize  -  len ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_readinode ( " check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ref_offset ( ref ) ,  tn - > csize ,  tn - > partial_crc ,  tn - > data_crc ,  ofs  -  len ,  ofs ,  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifndef __ECOS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  adding  and  jffs2_flash_read_end ( )  interface .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c - > mtd - > point )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  c - > mtd - > point ( c - > mtd ,  ofs ,  len ,  & retlen ,  & buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! err  & &  retlen  <  tn - > csize )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											JFFS2_WARNING ( " MTD point returned len too short: %u instead of %u. \n " ,  retlen ,  tn - > csize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c - > mtd - > unpoint ( c - > mtd ,  buffer ,  ofs ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											JFFS2_WARNING ( " MTD point failed: error code %d. \n " ,  err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pointed  =  1 ;  /* succefully pointed to device */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! pointed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buffer  =  kmalloc ( len ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( unlikely ( ! buffer ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* TODO: this is very frequent pattern, make it a separate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  routine  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  jffs2_flash_read ( c ,  ofs ,  len ,  & retlen ,  buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											JFFS2_ERROR ( " can not read %d bytes from 0x%08x, error code: %d. \n " ,  len ,  ofs ,  err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  free_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( retlen  ! =  len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											JFFS2_ERROR ( " short read at %#08x: %d instead of %d. \n " ,  ofs ,  retlen ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  free_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Continue calculating CRC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									crc  =  crc32 ( tn - > partial_crc ,  buffer ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if ( ! pointed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree ( buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef __ECOS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c - > mtd - > unpoint ( c - > mtd ,  buffer ,  ofs ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( crc  ! =  tn - > data_crc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 10:26:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										JFFS2_NOTICE ( " wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ofs ,  tn - > data_crc ,  crc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								adj_acc :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									jeb  =  & c - > blocks [ ref - > flash_offset  /  c - > sector_size ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  =  ref_totlen ( c ,  jeb ,  ref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  Mark  the  node  as  having  been  checked  and  fix  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  accounting  accordingly . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_lock ( & c - > erase_completion_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									jeb - > used_size  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									jeb - > unchecked_size  - =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c - > used_size  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c - > unchecked_size  - =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_unlock ( & c - > erase_completion_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								free_out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if ( ! pointed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree ( buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef __ECOS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c - > mtd - > unpoint ( c - > mtd ,  buffer ,  ofs ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Helper  function  for  jffs2_add_older_frag_to_fragtree ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Checks  the  node  if  we  are  in  the  checking  stage . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-14 13:20:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  check_node ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_info  * f ,  struct  jffs2_tmp_dnode_info  * tn )  
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( ref_obsolete ( tn - > fn - > raw ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* We only check the data CRC of unchecked nodes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ref_flags ( tn - > fn - > raw )  ! =  REF_UNCHECKED ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree2 ( " check node %#04x-%#04x, phys offs %#08x. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 10:26:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tn - > fn - > ofs ,  tn - > fn - > ofs  +  tn - > fn - > size ,  ref_offset ( tn - > fn - > raw ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret  =  check_node_data ( c ,  tn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( unlikely ( ret  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										JFFS2_ERROR ( " check_node_data() returned error: %d. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( unlikely ( ret  >  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " CRC error, mark it obsolete. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										jffs2_mark_node_obsolete ( c ,  tn - > fn - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Helper  function  for  jffs2_add_older_frag_to_fragtree ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  when  the  new  fragment  that  is  being  inserted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  splits  a  hole  fragment . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  split_hole ( struct  jffs2_sb_info  * c ,  struct  rb_root  * root ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      struct  jffs2_node_frag  * newfrag ,  struct  jffs2_node_frag  * hole ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree2 ( " fragment %#04x-%#04x splits the hole %#04x-%#04x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ,  hole - > ofs ,  hole - > ofs  +  hole - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hole - > ofs  = =  newfrag - > ofs )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  Well ,  the  new  fragment  actually  starts  at  the  same  offset  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  the  hole . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hole - > ofs  +  hole - > size  >  newfrag - > ofs  +  newfrag - > size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  We  replace  the  overlapped  left  part  of  the  hole  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  the  new  node . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " insert fragment %#04x-%#04x and cut the left part of the hole \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_replace_node ( & hole - > rb ,  & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hole - > ofs  + =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hole - > size  - =  newfrag - > size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  We  know  that  ' hole '  should  be  the  right  hand 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  fragment . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_fragtree_insert ( hole ,  newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_insert_color ( & hole - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  Ah ,  the  new  fragment  is  of  the  same  size  as  the  hole . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Relace  the  hole  by  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " insert fragment %#04x-%#04x and overwrite hole \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_replace_node ( & hole - > rb ,  & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_node_frag ( hole ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* The new fragment lefts some hole space at the left */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  jffs2_node_frag  *  newfrag2  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hole - > ofs  +  hole - > size  >  newfrag - > ofs  +  newfrag - > size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* The new frag also lefts some space at the right */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newfrag2  =  new_fragment ( NULL ,  newfrag - > ofs  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												newfrag - > size ,  hole - > ofs  +  hole - > size 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												-  newfrag - > ofs  -  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( unlikely ( ! newfrag2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_free_node_frag ( newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hole - > size  =  newfrag - > ofs  -  hole - > ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " left the hole %#04x-%#04x at the left and inserd fragment %#04x-%#04x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hole - > ofs ,  hole - > ofs  +  hole - > size ,  newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_fragtree_insert ( newfrag ,  hole ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( newfrag2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " left the hole %#04x-%#04x at the right \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												newfrag2 - > ofs ,  newfrag2 - > ofs  +  newfrag2 - > size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_fragtree_insert ( newfrag2 ,  newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rb_insert_color ( & newfrag2 - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  is  used  when  we  build  inode .  It  expects  the  nodes  are  passed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  in  the  decreasing  version  order .  The  whole  point  of  this  is  to  improve  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  inodes  checking  on  NAND :  we  check  the  nodes '  data  CRC  only  when  they  are  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  obsoleted .  Previously ,  add_frag_to_fragtree ( )  function  was  used  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  nodes  were  passed  to  it  in  the  increasing  version  ordes  and  CRCs  of  all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  nodes  were  checked . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Note :  tn - > fn - > size  shouldn ' t  be  zero . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  if  the  node  was  inserted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          1  if  it  wasn ' t  inserted  ( since  it  is  obsolete ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          <  0  an  if  error  occured 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  jffs2_add_older_frag_to_fragtree ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_info  * f ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     struct  jffs2_tmp_dnode_info  * tn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * this ,  * newfrag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  lastend ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_full_dnode  * fn  =  tn - > fn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rb_root  * root  =  & f - > fragtree ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  fn_size  =  fn - > size ,  fn_ofs  =  fn - > ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ,  checked  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ref_flag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree ( " insert fragment %#04x-%#04x, ver %u \n " ,  fn_ofs ,  fn_ofs  +  fn_size ,  tn - > version ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Skip all the nodes which are completed before this one starts */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									this  =  jffs2_lookup_node_frag ( root ,  fn_ofs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( this ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " 'this' found %#04x-%#04x (%s) \n " ,  this - > ofs ,  this - > ofs  +  this - > size ,  this - > node  ?  " data "  :  " hole " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastend  =  this - > ofs  +  this - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastend  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Detect the preliminary type of node */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( fn - > size  > =  PAGE_CACHE_SIZE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ref_flag  =  REF_PRISTINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ref_flag  =  REF_NORMAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* See if we ran off the end of the root */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( lastend  < =  fn_ofs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We did */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  We  are  going  to  insert  the  new  node  into  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  fragment  tree ,  so  check  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  check_node ( c ,  f ,  tn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fn - > frags  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newfrag  =  new_fragment ( fn ,  fn_ofs ,  fn_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( unlikely ( ! newfrag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  no_overlapping_node ( c ,  root ,  newfrag ,  this ,  lastend ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( unlikely ( err  ! =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_node_frag ( newfrag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out_ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fn - > frags  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  Here  we  have : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  fn_ofs  <  this - > ofs  +  this - > size  & &  fn_ofs  > =  this - > ofs . 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  Remember ,  ' this '  has  higher  version ,  any  non - hole  node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  which  is  already  in  the  fragtree  is  newer  then  the  newly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  inserted . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! this - > node )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  ' this '  is  the  hole  fragment ,  so  at  least  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  beginning  of  the  new  fragment  is  valid . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  We  are  going  to  insert  the  new  node  into  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  fragment  tree ,  so  check  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! checked )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  check_node ( c ,  f ,  tn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( unlikely ( err  ! =  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												checked  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( this - > ofs  +  this - > size  > =  fn_ofs  +  fn_size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* We split the hole on two parts */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fn - > frags  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												newfrag  =  new_fragment ( fn ,  fn_ofs ,  fn_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( unlikely ( ! newfrag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  split_hole ( c ,  root ,  newfrag ,  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( unlikely ( err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  out_ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 *  The  beginning  of  the  new  fragment  is  valid  since  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  overlaps  the  hole  node . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ref_flag  =  REF_NORMAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fn - > frags  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newfrag  =  new_fragment ( fn ,  fn_ofs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													this - > ofs  +  this - > size  -  fn_ofs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( unlikely ( ! newfrag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( fn_ofs  = =  this - > ofs )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 *  The  new  node  starts  at  the  same  offset  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  the  hole  and  supersieds  the  hole . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " add the new fragment instead of hole %#04x-%#04x, refcnt %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													fn_ofs ,  fn_ofs  +  this - > ofs  +  this - > size  -  fn_ofs ,  fn - > frags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rb_replace_node ( & this - > rb ,  & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_free_node_frag ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 *  The  hole  becomes  shorter  as  its  right  part 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  is  supersieded  by  the  new  fragment . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " reduce size of hole %#04x-%#04x to %#04x-%#04x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													this - > ofs ,  this - > ofs  +  this - > size ,  this - > ofs ,  this - > ofs  +  this - > size  -  newfrag - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " add new fragment %#04x-%#04x, refcnt %d \n " ,  fn_ofs , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													fn_ofs  +  this - > ofs  +  this - > size  -  fn_ofs ,  fn - > frags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												this - > size  - =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_fragtree_insert ( newfrag ,  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fn_ofs  + =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fn_size  - =  newfrag - > size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											this  =  rb_entry ( rb_next ( & newfrag - > rb ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  jffs2_node_frag ,  rb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " switch to the next 'this' fragment: %#04x-%#04x %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												this - > ofs ,  this - > ofs  +  this - > size ,  this - > node  ?  " (data) "  :  " (hole) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  ' This '  node  is  not  the  hole  so  it  obsoletes  the  new  fragment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  either  fully  or  partially . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( this - > ofs  +  this - > size  > =  fn_ofs  +  fn_size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* The new node is obsolete, drop it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( fn - > frags  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " %#04x-%#04x is obsolete, mark it obsolete \n " ,  fn_ofs ,  fn_ofs  +  fn_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ref_flag  =  REF_OBSOLETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out_ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  jffs2_node_frag  * new_this ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* 'This' node obsoletes the beginning of the new node */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " the beginning %#04x-%#04x is obsolete \n " ,  fn_ofs ,  this - > ofs  +  this - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ref_flag  =  REF_NORMAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fn_size  - =  this - > ofs  +  this - > size  -  fn_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fn_ofs  =  this - > ofs  +  this - > size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dbg_fragtree2 ( " now considering %#04x-%#04x \n " ,  fn_ofs ,  fn_ofs  +  fn_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											new_this  =  rb_entry ( rb_next ( & this - > rb ) ,  struct  jffs2_node_frag ,  rb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! new_this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 *  There  is  no  next  fragment .  Add  the  rest  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  the  new  node  as  the  right - hand  child . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! checked )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													err  =  check_node ( c ,  f ,  tn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( unlikely ( err  ! =  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													checked  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fn - > frags  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												newfrag  =  new_fragment ( fn ,  fn_ofs ,  fn_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( unlikely ( ! newfrag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " there are no more fragments, insert %#04x-%#04x \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													newfrag - > ofs ,  newfrag - > ofs  +  newfrag - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rb_link_node ( & newfrag - > rb ,  & this - > rb ,  & this - > rb . rb_right ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rb_insert_color ( & newfrag - > rb ,  root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  out_ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												this  =  new_this ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dbg_fragtree2 ( " switch to the next 'this' fragment: %#04x-%#04x %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													this - > ofs ,  this - > ofs  +  this - > size ,  this - > node  ?  " (data) "  :  " (hole) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out_ok :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( fn - > size  <  PAGE_CACHE_SIZE  & &  ref_flag  = =  REF_PRISTINE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ref_flag  = =  REF_OBSOLETE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " the node is obsolete now \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* jffs2_mark_node_obsolete() will adjust space accounting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_mark_node_obsolete ( c ,  fn - > raw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree2 ( " the node is  \" %s \"  now \n " ,  ref_flag  = =  REF_NORMAL  ?  " REF_NORMAL "  :  " REF_PRISTINE " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-01 13:05:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Space accounting was adjusted at check_node_data() */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_lock ( & c - > erase_completion_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fn - > raw - > flash_offset  =  ref_offset ( fn - > raw )  |  ref_flag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_unlock ( & c - > erase_completion_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-07-27 15:46:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  jffs2_set_inocache_state ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_cache  * ic ,  int  state )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_lock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ic - > state  =  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wake_up ( & c - > inocache_wq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_unlock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* During mount, this needs no locking. During normal operation, its
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   callers  want  to  do  other  stuff  while  still  holding  the  inocache_lock . 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   Rather  than  introducing  special  case  get_ino_cache  functions  or 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								   callbacks ,  we  just  let  the  caller  do  the  locking  itself .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								struct  jffs2_inode_cache  * jffs2_get_ino_cache ( struct  jffs2_sb_info  * c ,  uint32_t  ino )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_inode_cache  * ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret  =  c - > inocache_list [ ino  %  INOCACHE_HASHSIZE ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ret  & &  ret - > ino  <  ino )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  ret - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ret  & &  ret - > ino  ! =  ino ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_add_ino_cache  ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_cache  * new )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_inode_cache  * * prev ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-22 21:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									spin_lock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-22 21:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! new - > ino ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new - > ino  =  + + c - > highest_ino ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_inocache ( " add %p (ino #%u) \n " ,  new ,  new - > ino ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-22 21:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									prev  =  & c - > inocache_list [ new - > ino  %  INOCACHE_HASHSIZE ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( * prev )  & &  ( * prev ) - > ino  <  new - > ino )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev  =  & ( * prev ) - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new - > next  =  * prev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* prev  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_unlock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_del_ino_cache ( struct  jffs2_sb_info  * c ,  struct  jffs2_inode_cache  * old )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_inode_cache  * * prev ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_inocache ( " del %p (ino #%u) \n " ,  old ,  old - > ino ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									spin_lock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									prev  =  & c - > inocache_list [ old - > ino  %  INOCACHE_HASHSIZE ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									while  ( ( * prev )  & &  ( * prev ) - > ino  <  old - > ino )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev  =  & ( * prev ) - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( * prev )  = =  old )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* prev  =  old - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-02-27 23:01:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Free it now unless it's in READING or CLEARING state, which
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   are  the  transitions  upon  read_inode ( )  and  clear_inode ( ) .  The 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									   rest  of  the  time  we  know  nobody  else  is  looking  at  it ,  and 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-27 23:01:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									   if  it ' s  held  by  read_inode ( )  or  clear_inode ( )  they ' ll  free  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   for  themselves .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( old - > state  ! =  INO_STATE_READING  & &  old - > state  ! =  INO_STATE_CLEARING ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_free_inode_cache ( old ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									spin_unlock ( & c - > inocache_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_free_ino_caches ( struct  jffs2_sb_info  * c )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_inode_cache  * this ,  * next ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  ( i = 0 ;  i < INOCACHE_HASHSIZE ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										this  =  c - > inocache_list [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( this )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  this - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_inode_cache ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											this  =  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c - > inocache_list [ i ]  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_free_raw_node_refs ( struct  jffs2_sb_info  * c )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_raw_node_ref  * this ,  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i = 0 ;  i < c - > nr_blocks ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										this  =  c - > blocks [ i ] . first_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while ( this )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  this - > next_phys ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jffs2_free_raw_node_ref ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											this  =  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c - > blocks [ i ] . first_node  =  c - > blocks [ i ] . last_node  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								struct  jffs2_node_frag  * jffs2_lookup_node_frag ( struct  rb_root  * fragtree ,  uint32_t  offset )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* The common case in lookup is that there will be a node
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									   which  precisely  matches .  So  we  go  looking  for  that  first  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rb_node  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * prev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * frag  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree2 ( " root %p, offset %d \n " ,  fragtree ,  offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									next  =  fragtree - > rb_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while ( next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frag  =  rb_entry ( next ,  struct  jffs2_node_frag ,  rb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( frag - > ofs  +  frag - > size  < =  offset )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Remember the closest smaller match on the way down */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! prev  | |  frag - > ofs  >  prev - > ofs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												prev  =  frag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  frag - > rb . rb_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( frag - > ofs  >  offset )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  frag - > rb . rb_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  frag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Exact match not found. Go back up looking at each parent,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   and  return  the  closest  smaller  one  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( prev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " no match. Returning frag %#04x-%#04x, closest previous \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-28 15:46:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											  prev - > ofs ,  prev - > ofs + prev - > size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dbg_fragtree2 ( " returning NULL, empty fragtree \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  prev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Pass 'c' argument to indicate that nodes should be marked obsolete as
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   they ' re  killed .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  jffs2_kill_fragtree ( struct  rb_root  * root ,  struct  jffs2_sb_info  * c )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * frag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  jffs2_node_frag  * parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! root - > rb_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-22 12:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dbg_fragtree ( " killing \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									frag  =  ( rb_entry ( root - > rb_node ,  struct  jffs2_node_frag ,  rb ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while ( frag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( frag - > rb . rb_left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											frag  =  frag_left ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( frag - > rb . rb_right )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											frag  =  frag_right ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( frag - > node  & &  ! ( - - frag - > node - > frags ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Not a hole, and it's the final remaining frag
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											   of  this  node .  Free  the  node  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												jffs2_mark_node_obsolete ( c ,  frag - > node - > raw ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											jffs2_free_full_dnode ( frag - > node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parent  =  frag_parent ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( frag_left ( parent )  = =  frag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parent - > rb . rb_left  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-07 11:16:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												parent - > rb . rb_right  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										jffs2_free_node_frag ( frag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frag  =  parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cond_resched ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}