2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Copyright  2000  by  Hans  Reiser ,  licensing  governed  by  reiserfs / README 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Written  by  Anatoly  P .  Pinchuk  pap @ namesys . botik . ru 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Programm  System  Institute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Pereslavl - Zalessky  Russia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   This  file  contains  functions  dealing  with  S + tree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  B_IS_IN_TREE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  copy_item_head 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  comp_short_keys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  comp_keys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  comp_short_le_keys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  le_key2cpu_key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  comp_le_keys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bin_search 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  get_lkey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  get_rkey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  key_in_buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  decrement_bcount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_check_path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  pathrelse_and_restore 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  pathrelse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  search_by_key_reada 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  search_by_key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  search_for_position_by_key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  comp_items 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  prepare_for_direct_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  prepare_for_direntry_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  prepare_for_delete_or_cut 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  calc_deleted_bytes_number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  init_tb_struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  padd_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_delete_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_delete_solid_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_delete_object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  maybe_indirect_to_direct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  indirect_to_direct_roll_back 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_cut_from_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  truncate_directory 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_do_truncate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_paste_into_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  reiserfs_insert_item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/time.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/string.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/pagemap.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/reiserfs_fs.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/buffer_head.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/quotaops.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Does the buffer contain a disk block which is in the tree. */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  int  B_IS_IN_TREE ( const  struct  buffer_head  * bh )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( B_LEVEL ( bh )  >  MAX_HEIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       " PAP-1010: block (%b) has too big level (%z) " ,  bh ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( B_LEVEL ( bh )  ! =  FREE_LEVEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to gets item head in le form
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  void  copy_item_head ( struct  item_head  * to ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   const  struct  item_head  * from ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memcpy ( to ,  from ,  IH_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* k1 is pointer to on-disk structure which is stored in little-endian
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   form .  k2  is  pointer  to  cpu  variable .  For  key  of  items  of  the  same 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   object  this  returns  0. 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:44 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   Returns :  - 1  if  key1  <  key2 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								   0  if  key1  = =  key2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   1  if  key1  >  key2  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  int  comp_short_keys ( const  struct  reiserfs_key  * le_key ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   const  struct  cpu_key  * cpu_key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__u32  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  =  le32_to_cpu ( le_key - > k_dir_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( n  <  cpu_key - > on_disk_key . k_dir_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( n  >  cpu_key - > on_disk_key . k_dir_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  =  le32_to_cpu ( le_key - > k_objectid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( n  <  cpu_key - > on_disk_key . k_objectid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( n  >  cpu_key - > on_disk_key . k_objectid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* k1 is pointer to on-disk structure which is stored in little-endian
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   form .  k2  is  pointer  to  cpu  variable . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Compare  keys  using  all  4  key  fields . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Returns :  - 1  if  key1  <  key2  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   if  key1  =  key2  1  if  key1  >  key2  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  comp_keys ( const  struct  reiserfs_key  * le_key ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    const  struct  cpu_key  * cpu_key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									retval  =  comp_short_keys ( le_key ,  cpu_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( le_key_k_offset ( le_key_version ( le_key ) ,  le_key )  < 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    cpu_key_k_offset ( cpu_key ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( le_key_k_offset ( le_key_version ( le_key ) ,  le_key )  > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    cpu_key_k_offset ( cpu_key ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cpu_key - > key_length  = =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* this part is needed only when tail conversion is in progress */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( le_key_k_type ( le_key_version ( le_key ) ,  le_key )  < 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    cpu_key_k_type ( cpu_key ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( le_key_k_type ( le_key_version ( le_key ) ,  le_key )  > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    cpu_key_k_type ( cpu_key ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  int  comp_short_le_keys ( const  struct  reiserfs_key  * key1 ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      const  struct  reiserfs_key  * key2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__u32  * k1_u32 ,  * k2_u32 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  key_length  =  REISERFS_SHORT_KEY_LEN ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									k1_u32  =  ( __u32  * )  key1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									k2_u32  =  ( __u32  * )  key2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( ;  key_length - - ;  + + k1_u32 ,  + + k2_u32 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( le32_to_cpu ( * k1_u32 )  <  le32_to_cpu ( * k2_u32 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( le32_to_cpu ( * k1_u32 )  >  le32_to_cpu ( * k2_u32 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  void  le_key2cpu_key ( struct  cpu_key  * to ,  const  struct  reiserfs_key  * from )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to - > on_disk_key . k_dir_id  =  le32_to_cpu ( from - > k_dir_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to - > on_disk_key . k_objectid  =  le32_to_cpu ( from - > k_objectid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// find out version of the key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									version  =  le_key_version ( from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to - > version  =  version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to - > on_disk_key . k_offset  =  le_key_k_offset ( version ,  from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to - > on_disk_key . k_type  =  le_key_k_type ( version ,  from ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// this does not say which one is bigger, it only returns 1 if keys
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// are not equal, 0 otherwise
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  int  comp_le_keys ( const  struct  reiserfs_key  * k1 ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  struct  reiserfs_key  * k2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  memcmp ( k1 ,  k2 ,  sizeof ( struct  reiserfs_key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Binary  search  toolkit  function                                         * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Search  for  an  item  in  the  array  by  the  item  key                        * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Returns :     1  if  found ,   0  if  not  found ;                               * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *         * pos  =  number  of  the  searched  element  if  found ,  else  the         * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *         number  of  the  first  element  that  is  larger  than  key .             * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* For those not familiar with binary search: lbound is the leftmost item that it
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 could  be ,  rbound  the  rightmost  item  that  it  could  be .   We  examine  the  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 halfway  between  lbound  and  rbound ,  and  that  tells  us  either  that  we  can  increase 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 lbound ,  or  decrease  rbound ,  or  that  we  have  found  it ,  or  if  lbound  < =  rbound  that 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 there  are  no  possible  items ,  and  we  have  not  found  it .  With  each  examination  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 cut  the  number  of  possible  items  it  could  be  by  one  more  than  half  rounded  down , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 or  we  find  it .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  bin_search ( const  void  * key , 	/* Key to search for. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     const  void  * base , 	/* First item in the array. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     int  num , 	/* Number of items in the array. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     int  width , 	/* Item size in the array.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   searched .  Lest  the  reader  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   confused ,  note  that  this  is  crafted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   as  a  general  function ,  and  when  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   is  applied  specifically  to  the  array 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   of  item  headers  in  a  node ,  width 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   is  actually  the  item  header  size  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   the  item  size .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     int  * pos  /* Number of the searched for element. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  rbound ,  lbound ,  j ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( j  =  ( ( rbound  =  num  -  1 )  +  ( lbound  =  0 ) )  /  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     lbound  < =  rbound ;  j  =  ( rbound  +  lbound )  /  2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  ( comp_keys 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( ( struct  reiserfs_key  * ) ( ( char  * ) base  +  j  *  width ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 ( struct  cpu_key  * ) key ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  - 1 : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											lbound  =  j  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rbound  =  j  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* pos  =  j ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  ITEM_FOUND ; 	/* Key found in the array.  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* bin_search did not find given key, it returns position of key,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   that  is  minimal  and  greater  than  the  given  one .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									* pos  =  lbound ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ITEM_NOT_FOUND ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Minimal possible key. It is never in the tree. */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  reiserfs_key  MIN_KEY  =  {  0 ,  0 ,  { { 0 ,  0 } , }  } ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Maximal possible key. It is never in the tree. */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  reiserfs_key  MAX_KEY  =  {  
						 
					
						
							
								
									
										
										
										
											2005-05-01 08:59:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__constant_cpu_to_le32 ( 0xffffffff ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__constant_cpu_to_le32 ( 0xffffffff ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ { __constant_cpu_to_le32 ( 0xffffffff ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									  __constant_cpu_to_le32 ( 0xffffffff ) } , } 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-01 08:59:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   of  the  path ,  and  going  upwards .   We  must  check  the  path ' s  validity  at  each  step .   If  the  key  is  not  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the  path ,  there  is  no  delimiting  key  in  the  tree  ( buffer  is  first  or  last  buffer  in  tree ) ,  and  in  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   case  we  return  a  special  key ,  either  MIN_KEY  or  MAX_KEY .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  const  struct  reiserfs_key  * get_lkey ( const  struct  treepath  * chk_path ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														  const  struct  super_block  * sb ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  position ,  path_offset  =  chk_path - > path_length ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  buffer_head  * parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( path_offset  <  FIRST_PATH_ELEMENT_OFFSET , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5010: invalid offset in the path " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* While not higher in path than first element. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( path_offset - -  >  FIRST_PATH_ELEMENT_OFFSET )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RFALSE ( ! buffer_uptodate 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       ( PATH_OFFSET_PBUFFER ( chk_path ,  path_offset ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5020: parent is not uptodate " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Parent at the path is not in the tree now. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! B_IS_IN_TREE 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( parent  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     PATH_OFFSET_PBUFFER ( chk_path ,  path_offset ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MAX_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Check whether position in the parent is correct. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( position  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     PATH_OFFSET_POSITION ( chk_path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													  path_offset ) )  > 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    B_NR_ITEMS ( parent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MAX_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Check whether parent at the path really points to the child. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( B_N_CHILD_NUM ( parent ,  position )  ! = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    PATH_OFFSET_PBUFFER ( chk_path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													path_offset  +  1 ) - > b_blocknr ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MAX_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Return delimiting key if position in the parent is not equal to zero. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  B_N_PDELIM_KEY ( parent ,  position  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Return MIN_KEY if we are in the root of the buffer tree. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( PATH_OFFSET_PBUFFER ( chk_path ,  FIRST_PATH_ELEMENT_OFFSET ) - > 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    b_blocknr  = =  SB_ROOT_BLOCK ( sb ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & MIN_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & MAX_KEY ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Get delimiting key of the buffer at the path and its right neighbor. */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  const  struct  reiserfs_key  * get_rkey ( const  struct  treepath  * chk_path ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   const  struct  super_block  * sb ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  position ,  path_offset  =  chk_path - > path_length ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  buffer_head  * parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( path_offset  <  FIRST_PATH_ELEMENT_OFFSET , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5030: invalid offset in the path " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( path_offset - -  >  FIRST_PATH_ELEMENT_OFFSET )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RFALSE ( ! buffer_uptodate 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       ( PATH_OFFSET_PBUFFER ( chk_path ,  path_offset ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5040: parent is not uptodate " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Parent at the path is not in the tree now. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! B_IS_IN_TREE 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( parent  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     PATH_OFFSET_PBUFFER ( chk_path ,  path_offset ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MIN_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Check whether position in the parent is correct. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( position  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     PATH_OFFSET_POSITION ( chk_path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													  path_offset ) )  > 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    B_NR_ITEMS ( parent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MIN_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Check whether parent at the path really points to the child. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( B_N_CHILD_NUM ( parent ,  position )  ! = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    PATH_OFFSET_PBUFFER ( chk_path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													path_offset  +  1 ) - > b_blocknr ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & MIN_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Return delimiting key if position in the parent is not the last one. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( position  ! =  B_NR_ITEMS ( parent ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  B_N_PDELIM_KEY ( parent ,  position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Return MAX_KEY if we are in the root of the buffer tree. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( PATH_OFFSET_PBUFFER ( chk_path ,  FIRST_PATH_ELEMENT_OFFSET ) - > 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    b_blocknr  = =  SB_ROOT_BLOCK ( sb ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & MAX_KEY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & MIN_KEY ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Check whether a key is contained in the tree rooted from a buffer at a path. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* This works by looking at the left and right delimiting keys for the buffer in the last path_element in
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the  path .   These  delimiting  keys  are  stored  at  least  one  level  above  that  buffer  in  the  tree .  If  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   buffer  is  the  first  or  last  node  in  the  tree  order  then  one  of  the  delimiting  keys  may  be  absent ,  and  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   this  case  get_lkey  and  get_rkey  return  a  special  key  which  is  MIN_KEY  or  MAX_KEY .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  key_in_buffer ( struct  treepath  * chk_path , 	/* Path which should be checked.  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  struct  cpu_key  * key , 	/* Key which should be checked.   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  super_block  * sb 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( ! key  | |  chk_path - > path_length  <  FIRST_PATH_ELEMENT_OFFSET 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       | |  chk_path - > path_length  >  MAX_HEIGHT , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5050: pointer to the key(%p) is NULL or invalid path length(%d) " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       key ,  chk_path - > path_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RFALSE ( ! PATH_PLAST_BUFFER ( chk_path ) - > b_bdev , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5060: device must not be NODEV " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( comp_keys ( get_lkey ( chk_path ,  sb ) ,  key )  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* left delimiting key is bigger, that the key we look for */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*  if ( comp_keys(key, get_rkey(chk_path, sb)) != -1 ) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( comp_keys ( get_rkey ( chk_path ,  sb ) ,  key )  ! =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* key must be less than right delimitiing key */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-12-08 02:36:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  reiserfs_check_path ( struct  treepath  * p )  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RFALSE ( p - > path_length  ! =  ILLEGAL_PATH_ELEMENT_OFFSET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       " path not properly relsed " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Drop the reference to each buffer in a path and restore
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  dirty  bits  clean  when  preparing  the  buffer  for  the  log . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  version  should  only  be  called  from  fix_nodes ( )  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pathrelse_and_restore ( struct  super_block  * sb ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  treepath  * search_path ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  path_offset  =  search_path - > path_length ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( path_offset  <  ILLEGAL_PATH_ELEMENT_OFFSET , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " clm-4000: invalid path offset " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( path_offset  >  ILLEGAL_PATH_ELEMENT_OFFSET )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  buffer_head  * bh ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bh  =  PATH_OFFSET_PBUFFER ( search_path ,  path_offset - - ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_restore_prepared_buffer ( sb ,  bh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										brelse ( bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									search_path - > path_length  =  ILLEGAL_PATH_ELEMENT_OFFSET ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Drop the reference to each buffer in a path */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  pathrelse ( struct  treepath  * search_path )  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  path_offset  =  search_path - > path_length ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( path_offset  <  ILLEGAL_PATH_ELEMENT_OFFSET , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5090: invalid path offset " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( path_offset  >  ILLEGAL_PATH_ELEMENT_OFFSET ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										brelse ( PATH_OFFSET_PBUFFER ( search_path ,  path_offset - - ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									search_path - > path_length  =  ILLEGAL_PATH_ELEMENT_OFFSET ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  is_leaf ( char  * buf ,  int  blocksize ,  struct  buffer_head  * bh )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  block_head  * blkh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  * ih ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  used_space ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  prev_location ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  nr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blkh  =  ( struct  block_head  * ) buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( blkh_level ( blkh )  ! =  DISK_LEAF_NODE_LEVEL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5080 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " this should be caught earlier " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nr  =  blkh_nr_item ( blkh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nr  <  1  | |  nr  >  ( ( blocksize  -  BLKH_SIZE )  /  ( IH_SIZE  +  MIN_ITEM_LEN ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* item number is too big or too small */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5081 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " nr_item seems wrong: %z " ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ih  =  ( struct  item_head  * ) ( buf  +  BLKH_SIZE )  +  nr  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									used_space  =  BLKH_SIZE  +  IH_SIZE  *  nr  +  ( blocksize  -  ih_location ( ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( used_space  ! =  blocksize  -  blkh_free_space ( blkh ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* free space does not match to calculated amount of use space */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5082 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " free space seems wrong: %z " ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FIXME: it is_leaf will hit performance too much - we may have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// return 1 here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* check tables of item heads */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ih  =  ( struct  item_head  * ) ( buf  +  BLKH_SIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									prev_location  =  blocksize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  nr ;  i + + ,  ih + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( le_ih_k_type ( ih )  = =  TYPE_ANY )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( NULL ,  " reiserfs-5083 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " wrong item type for item %h " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ih_location ( ih )  > =  blocksize 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  ih_location ( ih )  <  IH_SIZE  *  nr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( NULL ,  " reiserfs-5084 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " item location seems wrong: %h " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ih_item_len ( ih )  <  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  ih_item_len ( ih )  >  MAX_ITEM_LEN ( blocksize ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( NULL ,  " reiserfs-5085 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " item length seems wrong: %h " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( prev_location  -  ih_location ( ih )  ! =  ih_item_len ( ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( NULL ,  " reiserfs-5086 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " item location seems wrong  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " (second one): %h " ,  ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev_location  =  ih_location ( ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// one may imagine much more checks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* returns 1 if buf looks like an internal node, 0 otherwise */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  is_internal ( char  * buf ,  int  blocksize ,  struct  buffer_head  * bh )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  block_head  * blkh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  nr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  used_space ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blkh  =  ( struct  block_head  * ) buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nr  =  blkh_level ( blkh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nr  < =  DISK_LEAF_NODE_LEVEL  | |  nr  >  MAX_HEIGHT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* this level is not possible for internal nodes */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5087 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " this should be caught earlier " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nr  =  blkh_nr_item ( blkh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nr  >  ( blocksize  -  BLKH_SIZE  -  DC_SIZE )  /  ( KEY_SIZE  +  DC_SIZE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* for internal which is not root we might check min number of keys */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5088 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " number of key seems wrong: %z " ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									used_space  =  BLKH_SIZE  +  KEY_SIZE  *  nr  +  DC_SIZE  *  ( nr  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( used_space  ! =  blocksize  -  blkh_free_space ( blkh ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5089 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " free space seems wrong: %z " ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// one may imagine much more checks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// make sure that bh contains formatted node of reiserfs tree of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 'level'-th level
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  is_tree_node ( struct  buffer_head  * bh ,  int  level )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( B_LEVEL ( bh )  ! =  level )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( NULL ,  " reiserfs-5090 " ,  " node level %d does  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 " not match to the expected one %d " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 B_LEVEL ( bh ) ,  level ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( level  = =  DISK_LEAF_NODE_LEVEL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  is_leaf ( bh - > b_data ,  bh - > b_size ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  is_internal ( bh - > b_data ,  bh - > b_size ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define SEARCH_BY_KEY_READA 16 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  function  is  NOT  SCHEDULE - SAFE ! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  It  might  unlock  the  write  lock  if  we  needed  to  wait  for  a  block 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  be  read .  Note  that  in  this  case  it  won ' t  recover  the  lock  to  avoid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  high  contention  resulting  from  too  much  lock  requests ,  especially 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  caller  ( search_by_key )  will  perform  other  schedule - unsafe 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  operations  just  after  calling  this  function . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ return  true  if  we  have  unlocked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  search_by_key_reada ( struct  super_block  * s ,  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												struct  buffer_head  * * bh , 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-18 23:39:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												b_blocknr_t  * b ,  int  num ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  j ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  unlocked  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  num ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bh [ i ]  =  sb_getblk ( s ,  b [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-08 14:21:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  We  are  going  to  read  some  blocks  on  which  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  have  a  reference .  It ' s  safe ,  though  we  might  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  reading  blocks  concurrently  changed  if  we  release 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  lock .  But  it ' s  still  fine  because  we  check  later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  if  the  tree  changed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( j  =  0 ;  j  <  i ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  note ,  this  needs  attention  if  we  are  getting  rid  of  the  BKL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  you  have  to  make  sure  the  prepared  bit  isn ' t  set  on  this  buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! buffer_uptodate ( bh [ j ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! unlocked )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reiserfs_write_unlock ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unlocked  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ll_rw_block ( READA ,  1 ,  bh  +  j ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										brelse ( bh [ j ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  unlocked ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Algorithm    SearchByKey                                                 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *              look  for  item  in  the  Disk  S + Tree  by  its  key                 * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Input :   sb    -   super  block                                             * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *          key   -  pointer  to  the  key  to  search                             * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  Output :  ITEM_FOUND ,  ITEM_NOT_FOUND  or  IO_ERROR                          * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *          search_path  -  path  from  the  root  to  the  needed  leaf             * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* This function fills up the path from the root to the leaf as it
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   descends  the  tree  looking  for  the  key .   It  uses  reiserfs_bread  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   try  to  find  buffers  in  the  cache  given  their  block  number .   If  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   does  not  find  them  in  the  cache  it  reads  them  from  disk .   For  each 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   node  search_by_key  finds  using  reiserfs_bread  it  then  uses 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   bin_search  to  look  through  that  node .   bin_search  will  find  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   position  of  the  block_number  of  the  next  node  if  it  is  looking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   through  an  internal  node .   If  it  is  looking  through  a  leaf  node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   bin_search  will  find  the  position  of  the  item  which  has  key  either 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   equal  to  given  key ,  or  which  is  the  maximal  key  less  than  the  given 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   key .   search_by_key  returns  a  path  that  must  be  checked  for  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   correctness  of  the  top  of  the  path  but  need  not  be  checked  for  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   correctness  of  the  bottom  of  the  path  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The function is NOT SCHEDULE-SAFE! */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  search_by_key ( struct  super_block  * sb ,  const  struct  cpu_key  * key , 	/* Key to search. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										  struct  treepath  * search_path , /* This structure was
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														   allocated  and  initialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   by  the  calling 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   function .  It  is  filled  up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   by  this  function .   */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										  int  stop_level 	/* How far down the tree to search. To
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   stop  at  leaf  level  -  set  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   DISK_LEAF_NODE_LEVEL  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									b_blocknr_t  block_number ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  expected_level ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  buffer_head  * bh ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  path_element  * last_element ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  node_level ,  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  right_neighbor_of_leaf_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  fs_gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  buffer_head  * reada_bh [ SEARCH_BY_KEY_READA ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-18 23:39:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									b_blocknr_t  reada_blocks [ SEARCH_BY_KEY_READA ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  reada_count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  repeat_counter  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									PROC_INFO_INC ( sb ,  search_by_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* As we add each node to a path we increase its count.  This means that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   we  must  be  careful  to  release  all  nodes  in  a  path  before  we  either 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   discard  the  path  struct  or  re - use  the  path  struct ,  as  we  do  here .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pathrelse ( search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									right_neighbor_of_leaf_node  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* With each iteration of this loop we search through the items in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   current  node ,  and  calculate  the  next  current  node ( next  path  element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   for  the  next  iteration  of  this  loop . .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									block_number  =  SB_ROOT_BLOCK ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									expected_level  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( + + repeat_counter  %  50000 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( sb ,  " PAP-5100 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 " %s: there were %d iterations of  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " while loop looking for key %K " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 current - > comm ,  repeat_counter , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* prep path to have another element added to it. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										last_element  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    PATH_OFFSET_PELEMENT ( search_path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 + + search_path - > path_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fs_gen  =  get_generation ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Read the next tree node, and set the last element in the path to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   have  a  pointer  to  it .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( bh  =  last_element - > pe_buffer  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     sb_getblk ( sb ,  block_number ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bool  unlocked  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! buffer_uptodate ( bh )  & &  reada_count  >  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* may unlock the write lock */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unlocked  =  search_by_key_reada ( sb ,  reada_bh , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														    reada_blocks ,  reada_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  If  we  haven ' t  already  unlocked  the  write  lock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  then  we  need  to  do  that  here  before  reading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  the  current  block 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! buffer_uptodate ( bh )  & &  ! unlocked )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-08 14:21:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												reiserfs_write_unlock ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												unlocked  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ll_rw_block ( READ ,  1 ,  & bh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											wait_on_buffer ( bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-14 02:56:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( unlocked ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reiserfs_write_lock ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! buffer_uptodate ( bh ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  io_error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      io_error : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											search_path - > path_length - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pathrelse ( search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reada_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( expected_level  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expected_level  =  SB_TREE_HEIGHT ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										expected_level - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* It is possible that schedule occurred. We must check whether the key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   to  search  is  still  in  the  tree  rooted  from  the  current  buffer .  If 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   not  then  repeat  search  from  the  root .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( fs_changed ( fs_gen ,  sb )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( ! B_IS_IN_TREE ( bh )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     B_LEVEL ( bh )  ! =  expected_level  | | 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     ! key_in_buffer ( search_path ,  key ,  sb ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											PROC_INFO_INC ( sb ,  search_by_key_fs_changed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PROC_INFO_INC ( sb ,  search_by_key_restarted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PROC_INFO_INC ( sb , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												      sbk_restarted [ expected_level  -  1 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pathrelse ( search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Get the root block number so that we can repeat the search
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   starting  from  the  root .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											block_number  =  SB_ROOT_BLOCK ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expected_level  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											right_neighbor_of_leaf_node  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* repeat search from the root */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* only check that the key is in the buffer if key is not
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										   equal  to  the  MAX_KEY .  Latter  case  is  only  possible  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   " finish_unfinished() "  processing  during  mount .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( comp_keys ( & MAX_KEY ,  key )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ! key_in_buffer ( search_path ,  key ,  sb ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5130: key is not in the buffer " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
											 
										
											
												kill-the-bkl/reiserfs: move the concurrent tree accesses checks per superblock
When do_balance() balances the tree, a trick is performed to
provide the ability for other tree writers/readers to check whether
do_balance() is executing concurrently (requires CONFIG_REISERFS_CHECK).
This is done to protect concurrent accesses to the tree. The trick
is the following:
When do_balance is called, a unique global variable called cur_tb
takes a pointer to the current tree to be rebalanced.
Once do_balance finishes its work, cur_tb takes the NULL value.
Then, concurrent tree readers/writers just have to check the value
of cur_tb to ensure do_balance isn't executing concurrently.
If it is, then it proves that schedule() occured on do_balance(),
which then relaxed the bkl that protected the tree.
Now that the bkl has be turned into a mutex, this check is still
fine even though do_balance() becomes preemptible: the write lock
will not be automatically released on schedule(), so the tree is
still protected.
But this is only fine if we have a single reiserfs mountpoint.
Indeed, because the bkl is a global lock, it didn't allowed
concurrent executions between a tree reader/writer in a mount point
and a do_balance() on another tree from another mountpoint.
So assuming all these readers/writers weren't supposed to be
reentrant, the current check now sometimes detect false positives with
the current per-superblock mutex which allows this reentrancy.
This patch keeps the concurrent tree accesses check but moves it
per superblock, so that only trees from a same mount point are
checked to be not accessed concurrently.
[ Impact: fix spurious panic while running several reiserfs mount-points ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
											 
										 
										
											2009-05-16 19:10:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( REISERFS_SB ( sb ) - > cur_tb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											print_cur_tb ( " 5140 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( sb ,  " PAP-5140 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " schedule occurred in do_balance! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// make sure, that the node contents look like a node of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// certain level
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! is_tree_node ( bh ,  expected_level ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_error ( sb ,  " vs-5150 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " invalid format found in block %ld.  " 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " Fsck? " ,  bh - > b_blocknr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pathrelse ( search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* ok, we have acquired next formatted node in the tree */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										node_level  =  B_LEVEL ( bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PROC_INFO_BH_STAT ( sb ,  bh ,  node_level  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( node_level  <  stop_level , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " vs-5152: tree level (%d) is less than stop level (%d) " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       node_level ,  stop_level ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										retval  =  bin_search ( key ,  B_N_PITEM_HEAD ( bh ,  0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												      B_NR_ITEMS ( bh ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												      ( node_level  = = 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       DISK_LEAF_NODE_LEVEL )  ?  IH_SIZE  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      KEY_SIZE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												      & ( last_element - > pe_position ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( node_level  = =  stop_level )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* we are not in the stop level */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( retval  = =  ITEM_FOUND ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* item has been found, so we choose the pointer which is to the right of the found one */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											last_element - > pe_position + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* if item was not found we choose the position which is to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   the  left  of  the  found  item .  This  requires  no  code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   bin_search  did  it  already .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* So we have chosen a position in the current node which is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   an  internal  node .   Now  we  calculate  child  block  number  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   position  in  the  node .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										block_number  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    B_N_CHILD_NUM ( bh ,  last_element - > pe_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* if we are going to read leaf nodes, try for read ahead as well */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( search_path - > reada  &  PATH_READA )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    node_level  = =  DISK_LEAF_NODE_LEVEL  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  pos  =  last_element - > pe_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  limit  =  B_NR_ITEMS ( bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  reiserfs_key  * le_key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( search_path - > reada  &  PATH_READA_BACK ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												limit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( reada_count  <  SEARCH_BY_KEY_READA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( pos  = =  limit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reada_blocks [ reada_count + + ]  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    B_N_CHILD_NUM ( bh ,  pos ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( search_path - > reada  &  PATH_READA_BACK ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													pos - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pos + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  check  to  make  sure  we ' re  in  the  same  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												le_key  =  B_N_PDELIM_KEY ( bh ,  pos ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( le32_to_cpu ( le_key - > k_objectid )  ! = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    key - > on_disk_key . k_objectid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Form the path to an item and position in this item which contains
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   file  byte  defined  by  key .  If  there  is  no  such  item 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								   corresponding  to  the  key ,  we  point  the  path  to  the  item  with 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   maximal  key  less  than  key ,  and  * pos_in_item  is  set  to  one 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								   past  the  last  entry / byte  in  the  item .   If  searching  for  entry  in  a 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   directory  item ,  and  it  is  not  found ,  * pos_in_item  is  set  to  one 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								   entry  more  than  the  entry  with  maximal  key  which  is  less  than  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   sought  key . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Note  that  if  there  is  no  entry  in  this  same  node  which  is  one  more , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   then  we  point  to  an  imaginary  entry .   for  direct  items ,  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   position  is  in  units  of  bytes ,  for  indirect  items  the  position  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   in  units  of  blocknr  entries ,  for  directory  items  the  position  is  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   units  of  directory  entries .   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The function is NOT SCHEDULE-SAFE! */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  search_for_position_by_key ( struct  super_block  * sb , 	/* Pointer to the super block.          */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       const  struct  cpu_key  * p_cpu_key , 	/* Key to search (cpu variable)         */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       struct  treepath  * search_path 	/* Filled up by this function.          */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  * p_le_ih ; 	/* pointer to on-disk structure */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  blk_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									loff_t  item_offset ,  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  reiserfs_dir_entry  de ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If searching for directory entry. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direntry_cpu_key ( p_cpu_key ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  search_by_entry_key ( sb ,  p_cpu_key ,  search_path , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   & de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If not searching for directory entry. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If item is found. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retval  =  search_item ( sb ,  p_cpu_key ,  search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( retval  = =  IO_ERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval  = =  ITEM_FOUND )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( ! ih_item_len 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ( B_N_PITEM_HEAD 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( PATH_PLAST_BUFFER ( search_path ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 PATH_LAST_POSITION ( search_path ) ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5165: item length equals zero " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pos_in_item ( search_path )  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  POSITION_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( ! PATH_LAST_POSITION ( search_path ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5170: position equals zero " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Item is not found. Set path to the previous item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_le_ih  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    B_N_PITEM_HEAD ( PATH_PLAST_BUFFER ( search_path ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   - - PATH_LAST_POSITION ( search_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									blk_size  =  sb - > s_blocksize ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( comp_short_keys ( & ( p_le_ih - > ih_key ) ,  p_cpu_key ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FILE_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// FIXME: quite ugly this far
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									item_offset  =  le_ih_k_offset ( p_le_ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									offset  =  cpu_key_k_offset ( p_cpu_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Needed byte is contained in the item pointed to by the path. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( item_offset  < =  offset  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    item_offset  +  op_bytes_number ( p_le_ih ,  blk_size )  >  offset )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pos_in_item ( search_path )  =  offset  -  item_offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( is_indirect_le_ih ( p_le_ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos_in_item ( search_path )  / =  blk_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  POSITION_FOUND ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Needed byte is not contained in the item pointed to by the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   path .  Set  pos_in_item  out  of  the  item .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_indirect_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pos_in_item ( search_path )  = 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ih_item_len ( p_le_ih )  /  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pos_in_item ( search_path )  =  ih_item_len ( p_le_ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  POSITION_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Compare given item and item pointed to by the path. */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  comp_items ( const  struct  item_head  * stored_ih ,  const  struct  treepath  * path )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  buffer_head  * bh  =  PATH_PLAST_BUFFER ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  item_head  * ih ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Last buffer at the path is not in the tree. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! B_IS_IN_TREE ( bh ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Last path position is invalid. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( PATH_LAST_POSITION ( path )  > =  B_NR_ITEMS ( bh ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* we need only to know, whether it is the same item */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ih  =  get_ih ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  memcmp ( stored_ih ,  ih ,  IH_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* unformatted nodes are not logged anymore, ever.  This is safe
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  now  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define held_by_others(bh) (atomic_read(&(bh)->b_count) > 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// block can not be forgotten as it is in I/O or held by someone
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define block_in_use(bh) (buffer_locked(bh) || (held_by_others(bh))) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// prepare for delete or cut of direct item
  
						 
					
						
							
								
									
										
										
										
											2006-12-08 02:36:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  prepare_for_direct_item ( struct  treepath  * path ,  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													  struct  item_head  * le_ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  struct  inode  * inode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  loff_t  new_file_length ,  int  * cut_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									loff_t  round_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( new_file_length  = =  max_reiserfs_offset ( inode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* item has to be deleted */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cut_size  =  - ( IH_SIZE  +  ih_item_len ( le_ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  M_DELETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// new file gets truncated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( get_inode_item_key_version ( inode )  = =  KEY_FORMAT_3_6 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:44 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										round_len  =  ROUND_UP ( new_file_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* this was new_file_length < le_ih ... */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( round_len  <  le_ih_k_offset ( le_ih ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* cut_size  =  - ( IH_SIZE  +  ih_item_len ( le_ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  M_DELETE ; 	/* Delete this item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Calculate first position and size for cutting from item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pos_in_item ( path )  =  round_len  -  ( le_ih_k_offset ( le_ih )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cut_size  =  - ( ih_item_len ( le_ih )  -  pos_in_item ( path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  M_CUT ; 	/* Cut from this item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// old file: items may have any length
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( new_file_length  <  le_ih_k_offset ( le_ih ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cut_size  =  - ( IH_SIZE  +  ih_item_len ( le_ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  M_DELETE ; 	/* Delete this item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Calculate first position and size for cutting from item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									* cut_size  =  - ( ih_item_len ( le_ih )  - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      ( pos_in_item ( path )  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       new_file_length  +  1  -  le_ih_k_offset ( le_ih ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  M_CUT ; 		/* Cut from this item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-12-08 02:36:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  prepare_for_direntry_item ( struct  treepath  * path ,  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													    struct  item_head  * le_ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    struct  inode  * inode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    loff_t  new_file_length , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    int  * cut_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( le_ih_k_offset ( le_ih )  = =  DOT_OFFSET  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    new_file_length  = =  max_reiserfs_offset ( inode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RFALSE ( ih_entry_count ( le_ih )  ! =  2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " PAP-5220: incorrect empty directory item (%h) " ,  le_ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cut_size  =  - ( IH_SIZE  +  ih_item_len ( le_ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  M_DELETE ; 	/* Delete the directory item containing "." and ".." entry. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ih_entry_count ( le_ih )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Delete the directory item such as there is one record only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   in  this  item  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cut_size  =  - ( IH_SIZE  +  ih_item_len ( le_ih ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  M_DELETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Cut one record from the directory item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* cut_size  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    - ( DEH_SIZE  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      entry_length ( get_last_bh ( path ) ,  le_ih ,  pos_in_item ( path ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  M_CUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD (2 * JOURNAL_PER_BALANCE_CNT + 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*  If the path points to a directory or direct item, calculate mode and the size cut, for balance.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    If  the  path  points  to  an  indirect  item ,  remove  some  number  of  its  unformatted  nodes . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    In  case  of  file  truncate  calculate  whether  this  item  must  be  deleted / truncated  or  last 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unformatted  node  of  this  item  will  be  converted  to  a  direct  item . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    This  function  returns  a  determination  of  what  balance  mode  the  calling  function  should  employ .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  prepare_for_delete_or_cut ( struct  reiserfs_transaction_handle  * th ,  struct  inode  * inode ,  struct  treepath  * path ,  const  struct  cpu_key  * item_key ,  int  * removed , 	/* Number of unformatted nodes which were removed
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																														   from  end  of  the  file .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												      int  * cut_size ,  unsigned  long  long  new_file_length 	/* MAX_KEY_OFFSET in case of delete. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  super_block  * sb  =  inode - > i_sb ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  item_head  * p_le_ih  =  PATH_PITEM_HEAD ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  buffer_head  * bh  =  PATH_PLAST_BUFFER ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Stat_data item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_statdata_le_ih ( p_le_ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( new_file_length  ! =  max_reiserfs_offset ( inode ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5210: mode must be M_DELETE " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										* cut_size  =  - ( IH_SIZE  +  ih_item_len ( p_le_ih ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  M_DELETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Directory item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direntry_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  prepare_for_direntry_item ( path ,  p_le_ih ,  inode , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 new_file_length , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 cut_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Direct item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direct_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  prepare_for_direct_item ( path ,  p_le_ih ,  inode , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													       new_file_length ,  cut_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Case of an indirect item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    int  blk_size  =  sb - > s_blocksize ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    struct  item_head  s_ih ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    int  need_re_search ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    int  delete  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    int  result  =  M_CUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    int  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    if  (  new_file_length  = =  max_reiserfs_offset  ( inode )  )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* prepare_for_delete_or_cut() is called by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  reiserfs_delete_item ( )  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										new_file_length  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delete  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										need_re_search  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										* cut_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bh  =  PATH_PLAST_BUFFER ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copy_item_head ( & s_ih ,  PATH_PITEM_HEAD ( path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pos  =  I_UNFM_NUM ( & s_ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										while  ( le_ih_k_offset  ( & s_ih )  +  ( pos  -  1 )  *  blk_size  >  new_file_length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 17:47:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    __le32  * unfm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    __u32  block ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    /* Each unformatted block deletion may involve one additional
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     *  bitmap  block  into  the  transaction ,  thereby  the  initial 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     *  journal  space  reservation  might  not  be  enough .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    if  ( ! delete  & &  ( * cut_size )  ! =  0  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reiserfs_transaction_free_space ( th )  <  JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    unfm  =  ( __le32  * ) B_I_PITEM ( bh ,  & s_ih )  +  pos  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    block  =  get_block_num ( unfm ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    if  ( block  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_prepare_for_journal ( sb ,  bh ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											put_block_num ( unfm ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											journal_mark_dirty ( th ,  sb ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_free_block ( th ,  inode ,  block ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    } 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-30 23:36:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    reiserfs_write_unlock ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    cond_resched ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-30 23:36:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    reiserfs_write_lock ( sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    if  ( item_moved  ( & s_ih ,  path ) )   { 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											need_re_search  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    pos  - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( * removed ) + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( * cut_size )  - =  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    if  ( pos  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( * cut_size )  - =  IH_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											result  =  M_DELETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* a trick.  If the buffer has been logged, this will do nothing.  If
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* *  we ' ve  broken  the  loop  without  logging  it ,  it  will  restore  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* *  buffer  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_restore_prepared_buffer ( sb ,  bh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    }  while  ( need_re_search  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     search_for_position_by_key ( sb ,  item_key ,  path )  = =  POSITION_FOUND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    pos_in_item ( path )  =  pos  *  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    if  ( * cut_size  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Nothing were cut. maybe convert last unformatted node to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  direct  item ?  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										result  =  M_CONVERT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Calculate number of bytes which will be deleted or cut during balance */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  calc_deleted_bytes_number ( struct  tree_balance  * tb ,  char  mode )  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  del_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  item_head  * p_le_ih  =  PATH_PITEM_HEAD ( tb - > tb_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_statdata_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									del_size  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( mode  = = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									     M_DELETE )  ?  ih_item_len ( p_le_ih )  :  - tb - > insert_size [ 0 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_direntry_le_ih ( p_le_ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* return EMPTY_DIR_SIZE; We delete emty directoris only.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  we  can ' t  use  EMPTY_DIR_SIZE ,  as  old  format  dirs  have  a  different 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  empty  size .   ick .  FIXME ,  is  this  right ?  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  del_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_indirect_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										del_size  =  ( del_size  /  UNFM_P_SIZE )  * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												( PATH_PLAST_BUFFER ( tb - > tb_path ) - > b_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  del_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  init_tb_struct ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  tree_balance  * tb , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  super_block  * sb , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  treepath  * path ,  int  size ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memset ( tb ,  ' \0 ' ,  sizeof ( struct  tree_balance ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tb - > transaction_handle  =  th ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tb - > tb_sb  =  sb ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tb - > tb_path  =  path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PATH_OFFSET_PBUFFER ( path ,  ILLEGAL_PATH_ELEMENT_OFFSET )  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PATH_OFFSET_POSITION ( path ,  ILLEGAL_PATH_ELEMENT_OFFSET )  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tb - > insert_size [ 0 ]  =  size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  padd_item ( char  * item ,  int  total_length ,  int  length )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( i  =  total_length ;  i  >  length ; ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										item [ - - i ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								char  key2type ( struct  reiserfs_key  * ih )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_direntry_le_key ( 2 ,  ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' d ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direct_le_key ( 2 ,  ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' D ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_indirect_le_key ( 2 ,  ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' i ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_statdata_le_key ( 2 ,  ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' s ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ' u ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								char  head2type ( struct  item_head  * ih )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_direntry_le_ih ( ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' d ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direct_le_ih ( ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' D ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_indirect_le_ih ( ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' i ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_statdata_le_ih ( ih ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ' s ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ' u ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Delete object item.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  th        -  active  transaction  handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  path      -  path  to  the  deleted  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  item_key  -  key  to  search  for  the  deleted  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  indode    -  used  for  updating  i_blocks  and  quotas 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  un_bh     -  NULL  or  unformatted  node  pointer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  reiserfs_delete_item ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 struct  treepath  * path ,  const  struct  cpu_key  * item_key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 struct  inode  * inode ,  struct  buffer_head  * un_bh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  super_block  * sb  =  inode - > i_sb ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  tree_balance  s_del_balance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  s_ih ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  * q_ih ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  quota_cut_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ret_value ,  del_size ,  removed ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  iter  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									init_tb_struct ( th ,  & s_del_balance ,  sb ,  path , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       0  /*size is unknown */  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										removed  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										iter + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mode  = 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    prepare_for_delete_or_cut ( th ,  inode ,  path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													      item_key ,  & removed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      & del_size , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													      max_reiserfs_offset ( inode ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( mode  ! =  M_DELETE ,  " PAP-5320: mode must be M_DELETE " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										copy_item_head ( & s_ih ,  PATH_PITEM_HEAD ( path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s_del_balance . insert_size [ 0 ]  =  del_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  =  fix_nodes ( M_DELETE ,  & s_del_balance ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ret_value  ! =  REPEAT_SEARCH ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PROC_INFO_INC ( sb ,  delete_item_restarted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// file system changed, repeat search
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    search_for_position_by_key ( sb ,  item_key ,  path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ret_value  = =  IO_ERROR ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ret_value  = =  FILE_NOT_FOUND )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( sb ,  " vs-5340 " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 " no items of the file %K found " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 			/* while (1) */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ret_value  ! =  CARRY_ON )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										unfix_nodes ( & s_del_balance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// reiserfs_delete_item returns item length when success
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ret_value  =  calc_deleted_bytes_number ( & s_del_balance ,  M_DELETE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									q_ih  =  get_ih ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									quota_cut_bytes  =  ih_item_len ( q_ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* hack so the quota code doesn't have to guess if the file
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  has  a  tail .   On  tail  insert ,  we  allocate  quota  for  1  unformatted  node . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  We  test  the  offset  because  the  tail  might  have  been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  split  into  multiple  items ,  and  we  only  want  to  decrement  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  the  unfm  node  once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! S_ISLNK ( inode - > i_mode )  & &  is_direct_le_ih ( q_ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( le_ih_k_offset ( q_ih )  &  ( sb - > s_blocksize  -  1 ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quota_cut_bytes  =  sb - > s_blocksize  +  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quota_cut_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( un_bh )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  off ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We are in direct2indirect conversion, so move tail contents
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   to  the  unformatted  node  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* note, we do the copy before preparing the buffer because we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  don ' t  care  about  the  contents  of  the  unformatted  node  yet . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  the  only  thing  we  really  care  about  is  the  direct  item ' s  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  is  in  the  unformatted  node . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  Otherwise ,  we  would  have  to  call  reiserfs_prepare_for_journal  on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  the  unformatted  node ,  which  might  schedule ,  meaning  we ' d  have  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  loop  all  the  way  back  up  to  the  start  of  the  while  loop . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  The  unformatted  node  must  be  dirtied  later  on .   We  can ' t  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  sure  here  if  the  entire  tail  has  been  deleted  yet . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * * 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  un_bh  is  from  the  page  cache  ( all  unformatted  nodes  are 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  from  the  page  cache )  and  might  be  a  highmem  page .   So ,  we 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  can ' t  use  un_bh - > b_data . 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  - clm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										data  =  kmap_atomic ( un_bh - > b_page ,  KM_USER0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										off  =  ( ( le_ih_k_offset ( & s_ih )  -  1 )  &  ( PAGE_CACHE_SIZE  -  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( data  +  off , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       B_I_PITEM ( PATH_PLAST_BUFFER ( path ) ,  & s_ih ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       ret_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										kunmap_atomic ( data ,  KM_USER0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Perform balancing after all resources have been collected at once. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do_balance ( & s_del_balance ,  NULL ,  NULL ,  M_DELETE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_debug ( sb ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " reiserquota delete_item(): freeing %u, id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       quota_cut_bytes ,  inode - > i_uid ,  head2type ( & s_ih ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dquot_free_space_nodirty ( inode ,  quota_cut_bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Return deleted body length */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Summary Of Mechanisms For Handling Collisions Between Processes:
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 deletion  of  the  body  of  the  object  is  performed  by  iput ( ) ,  with  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 result  that  if  multiple  processes  are  operating  on  a  file ,  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 deletion  of  the  body  of  the  file  is  deferred  until  the  last  process 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 that  has  an  open  inode  performs  its  iput ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 writes  and  truncates  are  protected  from  collisions  by  use  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 semaphores . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 creates ,  linking ,  and  mknod  are  protected  from  collisions  with  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 processes  by  making  the  reiserfs_add_entry ( )  the  last  step  in  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 creation ,  and  then  rolling  back  all  changes  if  there  was  a  collision . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 -  Hans 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* this deletes item which never gets split */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  reiserfs_delete_solid_item ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  inode  * inode ,  struct  reiserfs_key  * key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  tree_balance  tb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INITIALIZE_PATH ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  item_len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  tb_init  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  cpu_key  cpu_key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  quota_cut_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									le_key2cpu_key ( & cpu_key ,  key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										retval  =  search_item ( th - > t_super ,  & cpu_key ,  & path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval  = =  IO_ERROR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_error ( th - > t_super ,  " vs-5350 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " i/o failure occurred trying  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " to delete %K " ,  & cpu_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval  ! =  ITEM_FOUND )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pathrelse ( & path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ( ( unsigned  long  long ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     GET_HASH_VALUE ( le_key_k_offset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    ( le_key_version ( key ) ,  key ) )  = =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     & &  ( unsigned  long  long ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     GET_GENERATION_NUMBER ( le_key_k_offset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   ( le_key_version ( key ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    key ) )  = =  1 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												reiserfs_warning ( th - > t_super ,  " vs-5355 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 " %k not found " ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! tb_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tb_init  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											item_len  =  ih_item_len ( PATH_PITEM_HEAD ( & path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											init_tb_struct ( th ,  & tb ,  th - > t_super ,  & path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       - ( IH_SIZE  +  item_len ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										quota_cut_bytes  =  ih_item_len ( PATH_PITEM_HEAD ( & path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										retval  =  fix_nodes ( M_DELETE ,  & tb ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval  = =  REPEAT_SEARCH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PROC_INFO_INC ( th - > t_super ,  delete_solid_item_restarted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( retval  = =  CARRY_ON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											do_balance ( & tb ,  NULL ,  NULL ,  M_DELETE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( inode )  { 	/* Should we count quota for item? (we don't count quotas for save-links) */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												reiserfs_debug ( th - > t_super ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       " reiserquota delete_solid_item(): freeing %u id=%u type=%c " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       quota_cut_bytes ,  inode - > i_uid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       key2type ( key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dquot_free_space_nodirty ( inode , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 quota_cut_bytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// IO_ERROR, NO_DISK_SPACE, etc
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( th - > t_super ,  " vs-5360 " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 " could not delete %K due to fix_nodes failure " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 & cpu_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unfix_nodes ( & tb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_check_path ( & path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  reiserfs_delete_object ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   struct  inode  * inode ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inode - > i_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* for directory this deletes item containing "." and ".." */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    reiserfs_do_truncate ( th ,  inode ,  NULL ,  0  /*no timestamp updates */  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# if defined( USE_INODE_GENERATION_COUNTER ) 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! old_format_only ( th - > t_super ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										__le32  * inode_generation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inode_generation  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    & REISERFS_SB ( th - > t_super ) - > s_rs - > s_inode_generation ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-28 02:16:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										le32_add_cpu ( inode_generation ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/* USE_INODE_GENERATION_COUNTER */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_delete_solid_item ( th ,  inode ,  INODE_PKEY ( inode ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  unmap_buffers ( struct  page  * page ,  loff_t  pos )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  buffer_head  * bh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  buffer_head  * head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  buffer_head  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  tail_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  cur_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( page )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( page_has_buffers ( page ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tail_index  =  pos  &  ( PAGE_CACHE_SIZE  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cur_index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											head  =  page_buffers ( page ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bh  =  head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												next  =  bh - > b_this_page ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* we want to unmap the buffers that contain the tail, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 * *  all  the  buffers  after  it  ( since  the  tail  must  be  at  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 * *  end  of  the  file ) .   We  don ' t  want  to  unmap  file  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 * *  before  the  tail ,  since  it  might  be  dirty  and  waiting  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 * *  reach  disk 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cur_index  + =  bh - > b_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( cur_index  >  tail_index )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reiserfs_unmap_buffer ( bh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bh  =  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  while  ( bh  ! =  head ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  maybe_indirect_to_direct ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    struct  inode  * inode , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    struct  page  * page , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    struct  treepath  * path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    const  struct  cpu_key  * item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    loff_t  new_file_size ,  char  * mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  super_block  * sb  =  inode - > i_sb ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  block_size  =  sb - > s_blocksize ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  cut_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( new_file_size  ! =  inode - > i_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* the page being sent in could be NULL if there was an i/o error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  reading  in  the  last  block .   The  user  will  hit  problems  trying  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  read  the  file ,  but  for  now  we  just  skip  the  indirect2direct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( atomic_read ( & inode - > i_count )  >  1  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ! tail_has_to_be_packed ( inode )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ! page  | |  ( REISERFS_I ( inode ) - > i_flags  &  i_nopack_mask ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:44 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* leave tail in an unformatted node */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										* mode  =  M_SKIP_BALANCING ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cut_bytes  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    block_size  -  ( new_file_size  &  ( block_size  -  1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pathrelse ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  cut_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Perform the conversion to a direct_item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* return indirect_to_direct(inode, path, item_key,
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												  new_file_size ,  mode ) ;  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  indirect2direct ( th ,  inode ,  page ,  path ,  item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       new_file_size ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* we did indirect_to_direct conversion. And we have inserted direct
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   item  successesfully ,  but  there  were  no  disk  space  to  cut  unfm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   pointer  being  converted .  Therefore  we  have  to  delete  inserted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   direct  item ( s )  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  indirect_to_direct_roll_back ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
									
										
										
										
											2006-12-08 02:36:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 struct  inode  * inode ,  struct  treepath  * path ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  cpu_key  tail_key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  tail_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  removed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									make_cpu_key ( & tail_key ,  inode ,  inode - > i_size  +  1 ,  TYPE_DIRECT ,  4 ) ; 	// !!!!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tail_key . key_length  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tail_len  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( cpu_key_k_offset ( & tail_key )  &  ( inode - > i_sb - > s_blocksize  -  1 ) )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( tail_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* look for the last byte of the tail */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( search_for_position_by_key ( inode - > i_sb ,  & tail_key ,  path )  = = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    POSITION_NOT_FOUND ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( inode - > i_sb ,  " vs-5615 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " found invalid item " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( path - > pos_in_item  ! = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ih_item_len ( PATH_PITEM_HEAD ( path ) )  -  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " vs-5616: appended bytes found " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PATH_LAST_POSITION ( path ) - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removed  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    reiserfs_delete_item ( th ,  path ,  & tail_key ,  inode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 NULL  /*unbh not needed */  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RFALSE ( removed  < =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       | |  removed  >  tail_len , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " vs-5617: there was tail %d bytes, removed item length %d bytes " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       tail_len ,  removed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tail_len  - =  removed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										set_cpu_key_k_offset ( & tail_key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     cpu_key_k_offset ( & tail_key )  -  removed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_warning ( inode - > i_sb ,  " reiserfs-5091 " ,  " indirect_to_direct  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 " conversion has been rolled back due to  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 " lack of disk space " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//mark_file_without_tail (inode);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mark_inode_dirty ( inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* (Truncate or cut entry) or delete object item. Returns < 0 on failure */  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  reiserfs_cut_from_item ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  treepath  * path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   struct  cpu_key  * item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  inode  * inode , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   struct  page  * page ,  loff_t  new_file_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  super_block  * sb  =  inode - > i_sb ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Every function which is going to call do_balance must first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   create  a  tree_balance  structure .   Then  it  must  fill  up  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   structure  by  using  the  init_tb_struct  and  fix_nodes  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   After  that  we  can  make  tree  balancing .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  tree_balance  s_cut_balance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  * p_le_ih ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  cut_size  =  0 , 	/* Amount to be cut. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ret_value  =  CARRY_ON ,  removed  =  0 , 	/* Number of the removed unformatted nodes. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    is_inode_locked  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  mode ; 		/* Mode of the balance. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  retval2  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  quota_cut_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									loff_t  tail_pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									init_tb_struct ( th ,  & s_cut_balance ,  inode - > i_sb ,  path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       cut_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Repeat this loop until we either cut the item without needing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   to  balance ,  or  we  fix_nodes  without  schedule  occurring  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Determine the balance mode, position of the first byte to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   be  cut ,  and  size  to  be  cut .   In  case  of  the  indirect  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   free  unformatted  nodes  which  are  pointed  to  by  the  cut 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   pointers .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mode  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    prepare_for_delete_or_cut ( th ,  inode ,  path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													      item_key ,  & removed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      & cut_size ,  new_file_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mode  = =  M_CONVERT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* convert last unformatted node to direct item or leave
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   tail  in  the  unformatted  node  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											RFALSE ( ret_value  ! =  CARRY_ON , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       " PAP-5570: can not convert twice " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ret_value  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    maybe_indirect_to_direct ( th ,  inode ,  page , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														     path ,  item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														     new_file_size ,  & mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( mode  = =  M_SKIP_BALANCING ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* tail has been left in the unformatted node */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  ret_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											is_inode_locked  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* removing of last unformatted node will change value we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   have  to  return  to  truncate .  Save  it  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											retval2  =  ret_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*retval2 = sb->s_blocksize - (new_file_size & (sb->s_blocksize - 1)); */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* So, we have performed the first part of the conversion:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   inserting  the  new  direct  item .   Now  we  are  removing  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   last  unformatted  node  pointer .  Set  key  to  search  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   it .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											set_cpu_key_k_type ( item_key ,  TYPE_INDIRECT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											item_key - > key_length  =  4 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											new_file_size  - = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ( new_file_size  &  ( sb - > s_blocksize  -  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tail_pos  =  new_file_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											set_cpu_key_k_offset ( item_key ,  new_file_size  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( search_for_position_by_key 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    ( sb ,  item_key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     path )  = =  POSITION_NOT_FOUND )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												print_block ( PATH_PLAST_BUFFER ( path ) ,  3 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    PATH_LAST_POSITION ( path )  -  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    PATH_LAST_POSITION ( path )  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												reiserfs_panic ( sb ,  " PAP-5580 " ,  " item to  " 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													       " convert does not exist (%K) " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													       item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( cut_size  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pathrelse ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s_cut_balance . insert_size [ 0 ]  =  cut_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  =  fix_nodes ( mode ,  & s_cut_balance ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ret_value  ! =  REPEAT_SEARCH ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PROC_INFO_INC ( sb ,  cut_from_item_restarted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    search_for_position_by_key ( sb ,  item_key ,  path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ret_value  = =  POSITION_FOUND ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_warning ( sb ,  " PAP-5610 " ,  " item %K not found " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										unfix_nodes ( & s_cut_balance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  ( ret_value  = =  IO_ERROR )  ?  - EIO  :  - ENOENT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 			/* while */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check fix_nodes results (IO_ERROR or NO_DISK_SPACE)
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ret_value  ! =  CARRY_ON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_inode_locked )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// FIXME: this seems to be not needed: we are always able
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// to cut item
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											indirect_to_direct_roll_back ( th ,  inode ,  path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ret_value  = =  NO_DISK_SPACE ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( sb ,  " reiserfs-5092 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 " NO_DISK_SPACE " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										unfix_nodes ( & s_cut_balance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EIO ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* go ahead and perform balancing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( mode  = =  M_PASTE  | |  mode  = =  M_INSERT ,  " invalid mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Calculate number of bytes that need to be cut from the item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									quota_cut_bytes  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( mode  = = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									     M_DELETE )  ?  ih_item_len ( get_ih ( path ) )  :  - s_cut_balance . 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    insert_size [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval2  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  =  calc_deleted_bytes_number ( & s_cut_balance ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret_value  =  retval2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* For direct items, we only change the quota when deleting the last
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * *  item . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_le_ih  =  PATH_PITEM_HEAD ( s_cut_balance . tb_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! S_ISLNK ( inode - > i_mode )  & &  is_direct_le_ih ( p_le_ih ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( mode  = =  M_DELETE  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( le_ih_k_offset ( p_le_ih )  &  ( sb - > s_blocksize  -  1 ) )  = = 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// FIXME: this is to keep 3.5 happy
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											REISERFS_I ( inode ) - > i_first_direct_byte  =  U32_MAX ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											quota_cut_bytes  =  sb - > s_blocksize  +  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quota_cut_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_inode_locked )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  item_head  * le_ih  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    PATH_PITEM_HEAD ( s_cut_balance . tb_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* we are going to complete indirect2direct conversion. Make
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   sure ,  that  we  exactly  remove  last  unformatted  node  pointer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   of  the  item  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! is_indirect_le_ih ( le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( sb ,  " vs-5652 " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " item must be indirect %h " ,  le_ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( mode  = =  M_DELETE  & &  ih_item_len ( le_ih )  ! =  UNFM_P_SIZE ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( sb ,  " vs-5653 " ,  " completing  " 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " indirect2direct conversion indirect  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " item %h being deleted must be of  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " 4 byte long " ,  le_ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( mode  = =  M_CUT 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    & &  s_cut_balance . insert_size [ 0 ]  ! =  - UNFM_P_SIZE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( sb ,  " vs-5654 " ,  " can not complete  " 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       " indirect2direct conversion of %h  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " (CUT, insert_size==%d) " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       le_ih ,  s_cut_balance . insert_size [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* it would be useful to make sure, that right neighboring
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   item  is  direct  item  of  this  file  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									do_balance ( & s_cut_balance ,  NULL ,  NULL ,  mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_inode_locked )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* we've done an indirect->direct conversion.  when the data block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  was  freed ,  it  was  removed  from  the  list  of  blocks  that  must 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  be  flushed  before  the  transaction  commits ,  make  sure  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  unmap  and  invalidate  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unmap_buffers ( page ,  tail_pos ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										REISERFS_I ( inode ) - > i_flags  & =  ~ i_pack_on_close_mask ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_debug ( inode - > i_sb ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " reiserquota cut_from_item(): freeing %u id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       quota_cut_bytes ,  inode - > i_uid ,  ' ? ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dquot_free_space_nodirty ( inode ,  quota_cut_bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  truncate_directory ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       struct  inode  * inode ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( inode - > i_nlink ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_error ( inode - > i_sb ,  " vs-5655 " ,  " link count != 0 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_le_key_k_offset ( KEY_FORMAT_3_5 ,  INODE_PKEY ( inode ) ,  DOT_OFFSET ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_le_key_k_type ( KEY_FORMAT_3_5 ,  INODE_PKEY ( inode ) ,  TYPE_DIRENTRY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reiserfs_delete_solid_item ( th ,  inode ,  INODE_PKEY ( inode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reiserfs_update_sd ( th ,  inode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_le_key_k_offset ( KEY_FORMAT_3_5 ,  INODE_PKEY ( inode ) ,  SD_OFFSET ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_le_key_k_type ( KEY_FORMAT_3_5 ,  INODE_PKEY ( inode ) ,  TYPE_STAT_DATA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Truncate file to the new size. Note, this must be called with a transaction
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   already  started  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  reiserfs_do_truncate ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  struct  inode  * inode , 	/* ->i_size contains new size */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 struct  page  * page , 	/* up to date for last block */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 int  update_timestamps 	/* when it is called by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   file_release  to  convert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   the  tail  -  no  timestamps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   should  be  updated  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INITIALIZE_PATH ( s_search_path ) ; 	/* Path to the current object item. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  item_head  * p_le_ih ; 	/* Pointer to an item header. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  cpu_key  s_item_key ; 	/* Key to search for a previous file item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									loff_t  file_size , 	/* Old file size. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 new_file_size ; 	/* New file size. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  deleted ; 		/* Number of deleted or truncated bytes. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( S_ISREG ( inode - > i_mode )  | |  S_ISDIR ( inode - > i_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     | |  S_ISLNK ( inode - > i_mode ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( S_ISDIR ( inode - > i_mode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// deletion of directory - no need to update timestamps
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										truncate_directory ( th ,  inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Get new file size. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									new_file_size  =  inode - > i_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FIXME: note, that key type is unimportant here
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									make_cpu_key ( & s_item_key ,  inode ,  max_reiserfs_offset ( inode ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										     TYPE_DIRECT ,  3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retval  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    search_for_position_by_key ( inode - > i_sb ,  & s_item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       & s_search_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval  = =  IO_ERROR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_error ( inode - > i_sb ,  " vs-5657 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       " i/o failure occurred trying to truncate %K " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       & s_item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval  = =  POSITION_FOUND  | |  retval  = =  FILE_NOT_FOUND )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_error ( inode - > i_sb ,  " PAP-5660 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       " wrong result %d of search for %K " ,  retval , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       & s_item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s_search_path . pos_in_item - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Get real file size (total length of all file items) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_le_ih  =  PATH_PITEM_HEAD ( & s_search_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_statdata_le_ih ( p_le_ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										file_size  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										loff_t  offset  =  le_ih_k_offset ( p_le_ih ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  bytes  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    op_bytes_number ( p_le_ih ,  inode - > i_sb - > s_blocksize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* this may mismatch with real file size: if last direct item
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   had  no  padding  zeros  and  last  unformatted  node  had  no  free 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   space ,  this  file  would  have  this  file  size  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										file_size  =  offset  +  bytes  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  are  we  doing  a  full  truncate  or  delete ,  if  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  kick  in  the  reada  code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( new_file_size  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s_search_path . reada  =  PATH_READA  |  PATH_READA_BACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( file_size  = =  0  | |  file_size  <  new_file_size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  update_and_out ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Update key to search for the last file item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									set_cpu_key_k_offset ( & s_item_key ,  file_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Cut or delete file item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										deleted  = 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    reiserfs_cut_from_item ( th ,  & s_search_path ,  & s_item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   inode ,  page ,  new_file_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( deleted  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( inode - > i_sb ,  " vs-5665 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 " reiserfs_cut_from_item failed " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_check_path ( & s_search_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RFALSE ( deleted  >  file_size , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       " PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       deleted ,  file_size ,  & s_item_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Change key to search the last file item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										file_size  - =  deleted ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										set_cpu_key_k_offset ( & s_item_key ,  file_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* While there are bytes to truncate and previous file item is presented in the tree. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:44 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  This  loop  could  take  a  really  long  time ,  and  could  log 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 * *  many  more  blocks  than  a  transaction  can  hold .   So ,  we  do  a  polite 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  journal  end  here ,  and  if  the  transaction  needs  ending ,  we  make 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  sure  the  file  is  consistent  before  ending  the  current  trans 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  and  starting  a  new  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( journal_transaction_should_end ( th ,  0 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    reiserfs_transaction_free_space ( th )  < =  JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  orig_len_alloc  =  th - > t_blocks_allocated ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pathrelse ( & s_search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( update_timestamps )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												inode - > i_mtime  =  CURRENT_TIME_SEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												inode - > i_ctime  =  CURRENT_TIME_SEC ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_update_sd ( th ,  inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  journal_end ( th ,  inode - > i_sb ,  orig_len_alloc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  journal_begin ( th ,  inode - > i_sb , 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-25 03:06:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													    JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD  +  JOURNAL_PER_BALANCE_CNT  *  4 )  ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_update_inode_transaction ( inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  while  ( file_size  >  ROUND_UP ( new_file_size )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 search_for_position_by_key ( inode - > i_sb ,  & s_item_key , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													    & s_search_path )  = =  POSITION_FOUND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RFALSE ( file_size  >  ROUND_UP ( new_file_size ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       " PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       new_file_size ,  file_size ,  s_item_key . on_disk_key . k_objectid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      update_and_out : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( update_timestamps )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this is truncate, not file closing
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										inode - > i_mtime  =  CURRENT_TIME_SEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inode - > i_ctime  =  CURRENT_TIME_SEC ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_update_sd ( th ,  inode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      out : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pathrelse ( & s_search_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// this makes sure, that we __append__, not overwrite or add holes
  
						 
					
						
							
								
									
										
										
										
											2006-12-08 02:36:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  check_research_for_paste ( struct  treepath  * path ,  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												     const  struct  cpu_key  * key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  item_head  * found_ih  =  get_ih ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_direct_le_ih ( found_ih ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( le_ih_k_offset ( found_ih )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    op_bytes_number ( found_ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    get_last_bh ( path ) - > b_size )  ! = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    cpu_key_k_offset ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    | |  op_bytes_number ( found_ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       get_last_bh ( path ) - > b_size )  ! = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    pos_in_item ( path ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( NULL ,  " PAP-5720 " ,  " found direct item  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " %h or position (%d) does not match  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " to key %K " ,  found_ih , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       pos_in_item ( path ) ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_indirect_le_ih ( found_ih ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( le_ih_k_offset ( found_ih )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    op_bytes_number ( found_ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    get_last_bh ( path ) - > b_size )  ! = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    cpu_key_k_offset ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    | |  I_UNFM_NUM ( found_ih )  ! =  pos_in_item ( path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  get_ih_free_space ( found_ih )  ! =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_panic ( NULL ,  " PAP-5730 " ,  " found indirect  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " item (%h) or position (%d) does not  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       " match to key (%K) " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       found_ih ,  pos_in_item ( path ) ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif				 /* config reiserfs check */ 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Paste bytes to the existing item. Returns bytes number pasted into the item. */  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  reiserfs_paste_into_item ( struct  reiserfs_transaction_handle  * th ,  struct  treepath  * search_path , 	/* Path to the pasted item.	  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     const  struct  cpu_key  * key , 	/* Key to search for the needed item. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											     struct  inode  * inode , 	/* Inode item belongs to */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											     const  char  * body , 	/* Pointer to the bytes to paste.    */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											     int  pasted_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 				/* Size of pasted bytes.             */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  tree_balance  s_paste_balance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  fs_gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fs_gen  =  get_generation ( inode - > i_sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_debug ( inode - > i_sb ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " reiserquota paste_into_item(): allocating %u id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       pasted_size ,  inode - > i_uid , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       key2type ( & ( key - > on_disk_key ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retval  =  dquot_alloc_space_nodirty ( inode ,  pasted_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pathrelse ( search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									init_tb_struct ( th ,  & s_paste_balance ,  th - > t_super ,  search_path , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       pasted_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef DISPLACE_NEW_PACKING_LOCALITIES 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s_paste_balance . key  =  key - > on_disk_key ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* DQUOT_* can schedule, must check before the fix_nodes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( fs_changed ( fs_gen ,  inode - > i_sb ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  search_again ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( retval  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fix_nodes ( M_PASTE ,  & s_paste_balance ,  NULL , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											  body ) )  = =  REPEAT_SEARCH )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									      search_again : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* file system changed while we were in the fix_nodes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PROC_INFO_INC ( th - > t_super ,  paste_into_item_restarted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										retval  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    search_for_position_by_key ( th - > t_super ,  key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       search_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( retval  = =  IO_ERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retval  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  error_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval  = =  POSITION_FOUND )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( inode - > i_sb ,  " PAP-5710 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " entry or pasted byte (%K) exists " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											retval  =  - EEXIST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  error_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_REISERFS_CHECK 
  
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										check_research_for_paste ( search_path ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Perform balancing after all resources are collected by fix_nodes, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   accessing  them  will  not  risk  triggering  schedule .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval  = =  CARRY_ON )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										do_balance ( & s_paste_balance ,  NULL  /*ih */  ,  body ,  M_PASTE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									retval  =  ( retval  = =  NO_DISK_SPACE )  ?  - ENOSPC  :  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      error_out : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* this also releases the path */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unfix_nodes ( & s_paste_balance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_debug ( inode - > i_sb ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " reiserquota paste_into_item(): freeing %u id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       pasted_size ,  inode - > i_uid , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       key2type ( & ( key - > on_disk_key ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dquot_free_space_nodirty ( inode ,  pasted_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Insert new item into the buffer at the path.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  th    -  active  transaction  handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  path  -  path  to  the  inserted  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ih    -  pointer  to  the  item  header  to  insert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  body  -  pointer  to  the  bytes  to  insert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  reiserfs_insert_item ( struct  reiserfs_transaction_handle  * th ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 struct  treepath  * path ,  const  struct  cpu_key  * key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 struct  item_head  * ih ,  struct  inode  * inode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const  char  * body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  tree_balance  s_ins_balance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  fs_gen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  quota_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( ! th - > t_trans_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( inode )  { 		/* Do we count quotas for item? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fs_gen  =  get_generation ( inode - > i_sb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										quota_bytes  =  ih_item_len ( ih ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* hack so the quota code doesn't have to guess if the file has
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * *  a  tail ,  links  are  always  tails ,  so  there ' s  no  guessing  needed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! S_ISLNK ( inode - > i_mode )  & &  is_direct_le_ih ( ih ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											quota_bytes  =  inode - > i_sb - > s_blocksize  +  UNFM_P_SIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reiserfs_debug ( inode - > i_sb ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       " reiserquota insert_item(): allocating %u id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       quota_bytes ,  inode - > i_uid ,  head2type ( ih ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* We can't dirty inode here. It would be immediately written but
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  appropriate  stat  item  isn ' t  inserted  yet . . .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										retval  =  dquot_alloc_space_nodirty ( inode ,  quota_bytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pathrelse ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									init_tb_struct ( th ,  & s_ins_balance ,  th - > t_super ,  path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       IH_SIZE  +  ih_item_len ( ih ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef DISPLACE_NEW_PACKING_LOCALITIES 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s_ins_balance . key  =  key - > on_disk_key ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* DQUOT_* can schedule, must check to be sure calling fix_nodes is safe */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( inode  & &  fs_changed ( fs_gen ,  inode - > i_sb ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  search_again ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( retval  = 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fix_nodes ( M_INSERT ,  & s_ins_balance ,  ih , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  body ) )  = =  REPEAT_SEARCH )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									      search_again : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* file system changed while we were in the fix_nodes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PROC_INFO_INC ( th - > t_super ,  insert_item_restarted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										retval  =  search_item ( th - > t_super ,  key ,  path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( retval  = =  IO_ERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retval  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  error_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( retval  = =  ITEM_FOUND )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reiserfs_warning ( th - > t_super ,  " PAP-5760 " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 " key %K already exists in the tree " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retval  =  - EEXIST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  error_out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* make balancing after all resources will be collected at a time */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( retval  = =  CARRY_ON )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										do_balance ( & s_ins_balance ,  ih ,  body ,  M_INSERT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retval  =  ( retval  = =  NO_DISK_SPACE )  ?  - ENOSPC  :  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      error_out : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* also releases the path */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unfix_nodes ( & s_ins_balance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef REISERQUOTA_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reiserfs_debug ( th - > t_super ,  REISERFS_DEBUG_CODE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " reiserquota insert_item(): freeing %u id=%u type=%c " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-30 14:02:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       quota_bytes ,  inode - > i_uid ,  head2type ( ih ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( inode ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 09:05:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dquot_free_space_nodirty ( inode ,  quota_bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 20:21:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}