@@ -5702,6 +5702,42 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
57025702 return err ;
57035703}
57045704
5705+ static int __ext4_expand_extra_isize (struct inode * inode ,
5706+ unsigned int new_extra_isize ,
5707+ struct ext4_iloc * iloc ,
5708+ handle_t * handle , int * no_expand )
5709+ {
5710+ struct ext4_inode * raw_inode ;
5711+ struct ext4_xattr_ibody_header * header ;
5712+ int error ;
5713+
5714+ raw_inode = ext4_raw_inode (iloc );
5715+
5716+ header = IHDR (inode , raw_inode );
5717+
5718+ /* No extended attributes present */
5719+ if (!ext4_test_inode_state (inode , EXT4_STATE_XATTR ) ||
5720+ header -> h_magic != cpu_to_le32 (EXT4_XATTR_MAGIC )) {
5721+ memset ((void * )raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
5722+ EXT4_I (inode )-> i_extra_isize , 0 ,
5723+ new_extra_isize - EXT4_I (inode )-> i_extra_isize );
5724+ EXT4_I (inode )-> i_extra_isize = new_extra_isize ;
5725+ return 0 ;
5726+ }
5727+
5728+ /* try to expand with EAs present */
5729+ error = ext4_expand_extra_isize_ea (inode , new_extra_isize ,
5730+ raw_inode , handle );
5731+ if (error ) {
5732+ /*
5733+ * Inode size expansion failed; don't try again
5734+ */
5735+ * no_expand = 1 ;
5736+ }
5737+
5738+ return error ;
5739+ }
5740+
57055741/*
57065742 * Expand an inode by new_extra_isize bytes.
57075743 * Returns 0 on success or negative error number on failure.
@@ -5711,8 +5747,6 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode,
57115747 struct ext4_iloc iloc ,
57125748 handle_t * handle )
57135749{
5714- struct ext4_inode * raw_inode ;
5715- struct ext4_xattr_ibody_header * header ;
57165750 int no_expand ;
57175751 int error ;
57185752
@@ -5736,32 +5770,53 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode,
57365770 if (ext4_write_trylock_xattr (inode , & no_expand ) == 0 )
57375771 return - EBUSY ;
57385772
5739- raw_inode = ext4_raw_inode (& iloc );
5773+ error = __ext4_expand_extra_isize (inode , new_extra_isize , & iloc ,
5774+ handle , & no_expand );
5775+ ext4_write_unlock_xattr (inode , & no_expand );
57405776
5741- header = IHDR (inode , raw_inode );
5777+ return error ;
5778+ }
57425779
5743- /* No extended attributes present */
5744- if (!ext4_test_inode_state (inode , EXT4_STATE_XATTR ) ||
5745- header -> h_magic != cpu_to_le32 (EXT4_XATTR_MAGIC )) {
5746- memset ((void * )raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
5747- EXT4_I (inode )-> i_extra_isize , 0 ,
5748- new_extra_isize - EXT4_I (inode )-> i_extra_isize );
5749- EXT4_I (inode )-> i_extra_isize = new_extra_isize ;
5750- ext4_write_unlock_xattr (inode , & no_expand );
5751- return 0 ;
5780+ int ext4_expand_extra_isize (struct inode * inode ,
5781+ unsigned int new_extra_isize ,
5782+ struct ext4_iloc * iloc )
5783+ {
5784+ handle_t * handle ;
5785+ int no_expand ;
5786+ int error , rc ;
5787+
5788+ if (ext4_test_inode_state (inode , EXT4_STATE_NO_EXPAND )) {
5789+ brelse (iloc -> bh );
5790+ return - EOVERFLOW ;
57525791 }
57535792
5754- /* try to expand with EAs present */
5755- error = ext4_expand_extra_isize_ea (inode , new_extra_isize ,
5756- raw_inode , handle );
5793+ handle = ext4_journal_start (inode , EXT4_HT_INODE ,
5794+ EXT4_DATA_TRANS_BLOCKS (inode -> i_sb ));
5795+ if (IS_ERR (handle )) {
5796+ error = PTR_ERR (handle );
5797+ brelse (iloc -> bh );
5798+ return error ;
5799+ }
5800+
5801+ ext4_write_lock_xattr (inode , & no_expand );
5802+
5803+ BUFFER_TRACE (iloc .bh , "get_write_access" );
5804+ error = ext4_journal_get_write_access (handle , iloc -> bh );
57575805 if (error ) {
5758- /*
5759- * Inode size expansion failed; don't try again
5760- */
5761- no_expand = 1 ;
5806+ brelse (iloc -> bh );
5807+ goto out_stop ;
57625808 }
5763- ext4_write_unlock_xattr (inode , & no_expand );
57645809
5810+ error = __ext4_expand_extra_isize (inode , new_extra_isize , iloc ,
5811+ handle , & no_expand );
5812+
5813+ rc = ext4_mark_iloc_dirty (handle , inode , iloc );
5814+ if (!error )
5815+ error = rc ;
5816+
5817+ ext4_write_unlock_xattr (inode , & no_expand );
5818+ out_stop :
5819+ ext4_journal_stop (handle );
57655820 return error ;
57665821}
57675822
0 commit comments