@@ -277,9 +277,9 @@ static struct dx_frame *dx_probe(struct ext4_filename *fname,
277277 struct dx_hash_info * hinfo ,
278278 struct dx_frame * frame );
279279static void dx_release (struct dx_frame * frames );
280- static int dx_make_map (struct inode * dir , struct ext4_dir_entry_2 * de ,
281- unsigned blocksize , struct dx_hash_info * hinfo ,
282- struct dx_map_entry map [] );
280+ static int dx_make_map (struct inode * dir , struct buffer_head * bh ,
281+ struct dx_hash_info * hinfo ,
282+ struct dx_map_entry * map_tail );
283283static void dx_sort_map (struct dx_map_entry * map , unsigned count );
284284static struct ext4_dir_entry_2 * dx_move_dirents (struct inode * dir , char * from ,
285285 char * to , struct dx_map_entry * offsets ,
@@ -1249,15 +1249,23 @@ static inline int search_dirblock(struct buffer_head *bh,
12491249 * Create map of hash values, offsets, and sizes, stored at end of block.
12501250 * Returns number of entries mapped.
12511251 */
1252- static int dx_make_map (struct inode * dir , struct ext4_dir_entry_2 * de ,
1253- unsigned blocksize , struct dx_hash_info * hinfo ,
1252+ static int dx_make_map (struct inode * dir , struct buffer_head * bh ,
1253+ struct dx_hash_info * hinfo ,
12541254 struct dx_map_entry * map_tail )
12551255{
12561256 int count = 0 ;
1257- char * base = (char * ) de ;
1257+ struct ext4_dir_entry_2 * de = (struct ext4_dir_entry_2 * )bh -> b_data ;
1258+ unsigned int buflen = bh -> b_size ;
1259+ char * base = bh -> b_data ;
12581260 struct dx_hash_info h = * hinfo ;
12591261
1260- while ((char * ) de < base + blocksize ) {
1262+ if (ext4_has_metadata_csum (dir -> i_sb ))
1263+ buflen -= sizeof (struct ext4_dir_entry_tail );
1264+
1265+ while ((char * ) de < base + buflen ) {
1266+ if (ext4_check_dir_entry (dir , NULL , de , bh , base , buflen ,
1267+ ((char * )de ) - base ))
1268+ return - EFSCORRUPTED ;
12611269 if (de -> name_len && de -> inode ) {
12621270 if (ext4_hash_in_dirent (dir ))
12631271 h .hash = EXT4_DIRENT_HASH (de );
@@ -1270,8 +1278,7 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de,
12701278 count ++ ;
12711279 cond_resched ();
12721280 }
1273- /* XXX: do we need to check rec_len == 0 case? -Chris */
1274- de = ext4_next_entry (de , blocksize );
1281+ de = ext4_next_entry (de , dir -> i_sb -> s_blocksize );
12751282 }
12761283 return count ;
12771284}
@@ -1943,8 +1950,11 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
19431950
19441951 /* create map in the end of data2 block */
19451952 map = (struct dx_map_entry * ) (data2 + blocksize );
1946- count = dx_make_map (dir , (struct ext4_dir_entry_2 * ) data1 ,
1947- blocksize , hinfo , map );
1953+ count = dx_make_map (dir , * bh , hinfo , map );
1954+ if (count < 0 ) {
1955+ err = count ;
1956+ goto journal_error ;
1957+ }
19481958 map -= count ;
19491959 dx_sort_map (map , count );
19501960 /* Ensure that neither split block is over half full */
0 commit comments