@@ -277,9 +277,9 @@ static struct dx_frame *dx_probe(struct ext4_filename *fname,
277
277
struct dx_hash_info * hinfo ,
278
278
struct dx_frame * frame );
279
279
static 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 );
283
283
static void dx_sort_map (struct dx_map_entry * map , unsigned count );
284
284
static struct ext4_dir_entry_2 * dx_move_dirents (struct inode * dir , char * from ,
285
285
char * to , struct dx_map_entry * offsets ,
@@ -1249,15 +1249,23 @@ static inline int search_dirblock(struct buffer_head *bh,
1249
1249
* Create map of hash values, offsets, and sizes, stored at end of block.
1250
1250
* Returns number of entries mapped.
1251
1251
*/
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 ,
1254
1254
struct dx_map_entry * map_tail )
1255
1255
{
1256
1256
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 ;
1258
1260
struct dx_hash_info h = * hinfo ;
1259
1261
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 ;
1261
1269
if (de -> name_len && de -> inode ) {
1262
1270
if (ext4_hash_in_dirent (dir ))
1263
1271
h .hash = EXT4_DIRENT_HASH (de );
@@ -1270,8 +1278,7 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de,
1270
1278
count ++ ;
1271
1279
cond_resched ();
1272
1280
}
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 );
1275
1282
}
1276
1283
return count ;
1277
1284
}
@@ -1943,8 +1950,11 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1943
1950
1944
1951
/* create map in the end of data2 block */
1945
1952
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
+ }
1948
1958
map -= count ;
1949
1959
dx_sort_map (map , count );
1950
1960
/* Ensure that neither split block is over half full */
0 commit comments