@@ -2915,11 +2915,17 @@ static int ext4_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
29152915 return err ;
29162916}
29172917
2918- struct ext4_dir_entry_2 * ext4_init_dot_dotdot (struct inode * inode ,
2919- struct ext4_dir_entry_2 * de ,
2920- int blocksize , int csum_size ,
2921- unsigned int parent_ino , int dotdot_real_len )
2918+ int ext4_init_dirblock (handle_t * handle , struct inode * inode ,
2919+ struct buffer_head * bh , unsigned int parent_ino ,
2920+ void * inline_buf , int inline_size )
29222921{
2922+ struct ext4_dir_entry_2 * de = (struct ext4_dir_entry_2 * ) bh -> b_data ;
2923+ size_t blocksize = bh -> b_size ;
2924+ int csum_size = 0 , header_size ;
2925+
2926+ if (ext4_has_feature_metadata_csum (inode -> i_sb ))
2927+ csum_size = sizeof (struct ext4_dir_entry_tail );
2928+
29232929 de -> inode = cpu_to_le32 (inode -> i_ino );
29242930 de -> name_len = 1 ;
29252931 de -> rec_len = ext4_rec_len_to_disk (ext4_dir_rec_len (de -> name_len , NULL ),
@@ -2930,18 +2936,29 @@ struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
29302936 de = ext4_next_entry (de , blocksize );
29312937 de -> inode = cpu_to_le32 (parent_ino );
29322938 de -> name_len = 2 ;
2933- if (!dotdot_real_len )
2934- de -> rec_len = ext4_rec_len_to_disk (blocksize -
2935- (csum_size + ext4_dir_rec_len (1 , NULL )),
2936- blocksize );
2937- else
2939+ memcpy (de -> name , ".." , 3 );
2940+ ext4_set_de_type (inode -> i_sb , de , S_IFDIR );
2941+ if (inline_buf ) {
29382942 de -> rec_len = ext4_rec_len_to_disk (
29392943 ext4_dir_rec_len (de -> name_len , NULL ),
29402944 blocksize );
2941- memcpy (de -> name , ".." , 3 );
2942- ext4_set_de_type (inode -> i_sb , de , S_IFDIR );
2945+ de = ext4_next_entry (de , blocksize );
2946+ header_size = (char * )de - bh -> b_data ;
2947+ memcpy ((void * )de , inline_buf , inline_size );
2948+ ext4_update_final_de (bh -> b_data , inline_size + header_size ,
2949+ blocksize - csum_size );
2950+ } else {
2951+ de -> rec_len = ext4_rec_len_to_disk (blocksize -
2952+ (csum_size + ext4_dir_rec_len (1 , NULL )),
2953+ blocksize );
2954+ }
29432955
2944- return ext4_next_entry (de , blocksize );
2956+ if (csum_size )
2957+ ext4_initialize_dirent_tail (bh , blocksize );
2958+ BUFFER_TRACE (dir_block , "call ext4_handle_dirty_metadata" );
2959+ set_buffer_uptodate (bh );
2960+ set_buffer_verified (bh );
2961+ return ext4_handle_dirty_dirblock (handle , inode , bh );
29452962}
29462963
29472964int ext4_init_new_dir (handle_t * handle , struct inode * dir ,
@@ -2950,13 +2967,8 @@ int ext4_init_new_dir(handle_t *handle, struct inode *dir,
29502967 struct buffer_head * dir_block = NULL ;
29512968 struct ext4_dir_entry_2 * de ;
29522969 ext4_lblk_t block = 0 ;
2953- unsigned int blocksize = dir -> i_sb -> s_blocksize ;
2954- int csum_size = 0 ;
29552970 int err ;
29562971
2957- if (ext4_has_feature_metadata_csum (dir -> i_sb ))
2958- csum_size = sizeof (struct ext4_dir_entry_tail );
2959-
29602972 if (ext4_test_inode_state (inode , EXT4_STATE_MAY_INLINE_DATA )) {
29612973 err = ext4_try_create_inline_dir (handle , dir , inode );
29622974 if (err < 0 && err != - ENOSPC )
@@ -2965,21 +2977,15 @@ int ext4_init_new_dir(handle_t *handle, struct inode *dir,
29652977 goto out ;
29662978 }
29672979
2980+ set_nlink (inode , 2 );
29682981 inode -> i_size = 0 ;
29692982 dir_block = ext4_append (handle , inode , & block );
29702983 if (IS_ERR (dir_block ))
29712984 return PTR_ERR (dir_block );
29722985 de = (struct ext4_dir_entry_2 * )dir_block -> b_data ;
2973- ext4_init_dot_dotdot (inode , de , blocksize , csum_size , dir -> i_ino , 0 );
2974- set_nlink (inode , 2 );
2975- if (csum_size )
2976- ext4_initialize_dirent_tail (dir_block , blocksize );
2977-
2978- BUFFER_TRACE (dir_block , "call ext4_handle_dirty_metadata" );
2979- err = ext4_handle_dirty_dirblock (handle , inode , dir_block );
2986+ err = ext4_init_dirblock (handle , inode , dir_block , dir -> i_ino , NULL , 0 );
29802987 if (err )
29812988 goto out ;
2982- set_buffer_verified (dir_block );
29832989out :
29842990 brelse (dir_block );
29852991 return err ;
0 commit comments