@@ -2621,6 +2621,42 @@ static int fix_key_order(struct btrfs_trans_handle *trans,
26212621	return  ret ;
26222622}
26232623
2624+ static  int  delete_bogus_item (struct  btrfs_trans_handle  * trans ,
2625+ 			     struct  btrfs_root  * root ,
2626+ 			     struct  btrfs_path  * path ,
2627+ 			     struct  extent_buffer  * buf , int  slot )
2628+ {
2629+ 	struct  btrfs_key  key ;
2630+ 	int  nritems  =  btrfs_header_nritems (buf );
2631+ 
2632+ 	btrfs_item_key_to_cpu (buf , & key , slot );
2633+ 
2634+ 	/* These are all the keys we can deal with missing. */ 
2635+ 	if  (key .type  !=  BTRFS_DIR_INDEX_KEY  && 
2636+ 	    key .type  !=  BTRFS_EXTENT_ITEM_KEY  && 
2637+ 	    key .type  !=  BTRFS_METADATA_ITEM_KEY  && 
2638+ 	    key .type  !=  BTRFS_TREE_BLOCK_REF_KEY  && 
2639+ 	    key .type  !=  BTRFS_EXTENT_DATA_REF_KEY )
2640+ 		return  -1 ;
2641+ 
2642+ 	printf ("Deleting bogus item [%llu,%u,%llu] at slot %d on block %llu\n" ,
2643+ 	       (unsigned long long )key .objectid , key .type ,
2644+ 	       (unsigned long long )key .offset , slot , buf -> start );
2645+ 	memmove_extent_buffer (buf , btrfs_item_nr_offset (slot ),
2646+ 			      btrfs_item_nr_offset (slot  +  1 ),
2647+ 			      sizeof (struct  btrfs_item ) * 
2648+ 			      (nritems  -  slot  -  1 ));
2649+ 	btrfs_set_header_nritems (buf , nritems  -  1 );
2650+ 	if  (slot  ==  0 ) {
2651+ 		struct  btrfs_disk_key  disk_key ;
2652+ 
2653+ 		btrfs_item_key (buf , & disk_key , 0 );
2654+ 		btrfs_fixup_low_keys (root , path , & disk_key , 1 );
2655+ 	}
2656+ 	btrfs_mark_buffer_dirty (buf );
2657+ 	return  0 ;
2658+ }
2659+ 
26242660static  int  fix_item_offset (struct  btrfs_trans_handle  * trans ,
26252661			   struct  btrfs_root  * root ,
26262662			   struct  extent_buffer  * buf )
@@ -2660,13 +2696,18 @@ static int fix_item_offset(struct btrfs_trans_handle *trans,
26602696	}
26612697
26622698	buf  =  path -> nodes [level ];
2699+ again :
26632700	for  (i  =  0 ; i  <  btrfs_header_nritems (buf ); i ++ ) {
26642701		unsigned int   shift  =  0 , offset ;
26652702
26662703		if  (i  ==  0  &&  btrfs_item_end_nr (buf , i ) != 
26672704		    BTRFS_LEAF_DATA_SIZE (root )) {
26682705			if  (btrfs_item_end_nr (buf , i ) > 
26692706			    BTRFS_LEAF_DATA_SIZE (root )) {
2707+ 				ret  =  delete_bogus_item (trans , root , path ,
2708+ 							buf , i );
2709+ 				if  (!ret )
2710+ 					goto again ;
26702711				fprintf (stderr , "item is off the end of the " 
26712712					"leaf, can't fix\n" );
26722713				ret  =  - EIO ;
@@ -2678,6 +2719,10 @@ static int fix_item_offset(struct btrfs_trans_handle *trans,
26782719			   btrfs_item_offset_nr (buf , i  -  1 )) {
26792720			if  (btrfs_item_end_nr (buf , i ) > 
26802721			    btrfs_item_offset_nr (buf , i  -  1 )) {
2722+ 				ret  =  delete_bogus_item (trans , root , path ,
2723+ 							buf , i );
2724+ 				if  (!ret )
2725+ 					goto again ;
26812726				fprintf (stderr , "items overlap, can't fix\n" );
26822727				ret  =  - EIO ;
26832728				break ;
0 commit comments