@@ -1620,14 +1620,14 @@ static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle,
16201620static int ext4_xattr_set_entry (struct ext4_xattr_info * i ,
16211621 struct ext4_xattr_search * s ,
16221622 handle_t * handle , struct inode * inode ,
1623+ struct inode * new_ea_inode ,
16231624 bool is_block )
16241625{
16251626 struct ext4_xattr_entry * last , * next ;
16261627 struct ext4_xattr_entry * here = s -> here ;
16271628 size_t min_offs = s -> end - s -> base , name_len = strlen (i -> name );
16281629 int in_inode = i -> in_inode ;
16291630 struct inode * old_ea_inode = NULL ;
1630- struct inode * new_ea_inode = NULL ;
16311631 size_t old_size , new_size ;
16321632 int ret ;
16331633
@@ -1712,38 +1712,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
17121712 old_ea_inode = NULL ;
17131713 goto out ;
17141714 }
1715- }
1716- if (i -> value && in_inode ) {
1717- WARN_ON_ONCE (!i -> value_len );
1718-
1719- new_ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
1720- i -> value , i -> value_len );
1721- if (IS_ERR (new_ea_inode )) {
1722- ret = PTR_ERR (new_ea_inode );
1723- new_ea_inode = NULL ;
1724- goto out ;
1725- }
1726- }
17271715
1728- if (old_ea_inode ) {
17291716 /* We are ready to release ref count on the old_ea_inode. */
17301717 ret = ext4_xattr_inode_dec_ref (handle , old_ea_inode );
1731- if (ret ) {
1732- /* Release newly required ref count on new_ea_inode. */
1733- if (new_ea_inode ) {
1734- int err ;
1735-
1736- err = ext4_xattr_inode_dec_ref (handle ,
1737- new_ea_inode );
1738- if (err )
1739- ext4_warning_inode (new_ea_inode ,
1740- "dec ref new_ea_inode err=%d" ,
1741- err );
1742- ext4_xattr_inode_free_quota (inode , new_ea_inode ,
1743- i -> value_len );
1744- }
1718+ if (ret )
17451719 goto out ;
1746- }
17471720
17481721 ext4_xattr_inode_free_quota (inode , old_ea_inode ,
17491722 le32_to_cpu (here -> e_value_size ));
@@ -1853,7 +1826,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
18531826 ret = 0 ;
18541827out :
18551828 iput (old_ea_inode );
1856- iput (new_ea_inode );
18571829 return ret ;
18581830}
18591831
@@ -1916,9 +1888,21 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19161888 size_t old_ea_inode_quota = 0 ;
19171889 unsigned int ea_ino ;
19181890
1919-
19201891#define header (x ) ((struct ext4_xattr_header *)(x))
19211892
1893+ /* If we need EA inode, prepare it before locking the buffer */
1894+ if (i -> value && i -> in_inode ) {
1895+ WARN_ON_ONCE (!i -> value_len );
1896+
1897+ ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
1898+ i -> value , i -> value_len );
1899+ if (IS_ERR (ea_inode )) {
1900+ error = PTR_ERR (ea_inode );
1901+ ea_inode = NULL ;
1902+ goto cleanup ;
1903+ }
1904+ }
1905+
19221906 if (s -> base ) {
19231907 int offset = (char * )s -> here - bs -> bh -> b_data ;
19241908
@@ -1927,6 +1911,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19271911 EXT4_JTR_NONE );
19281912 if (error )
19291913 goto cleanup ;
1914+
19301915 lock_buffer (bs -> bh );
19311916
19321917 if (header (s -> base )-> h_refcount == cpu_to_le32 (1 )) {
@@ -1953,7 +1938,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19531938 }
19541939 ea_bdebug (bs -> bh , "modifying in-place" );
19551940 error = ext4_xattr_set_entry (i , s , handle , inode ,
1956- true /* is_block */ );
1941+ ea_inode , true /* is_block */ );
19571942 ext4_xattr_block_csum_set (inode , bs -> bh );
19581943 unlock_buffer (bs -> bh );
19591944 if (error == - EFSCORRUPTED )
@@ -2021,29 +2006,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
20212006 s -> end = s -> base + sb -> s_blocksize ;
20222007 }
20232008
2024- error = ext4_xattr_set_entry (i , s , handle , inode , true /* is_block */ );
2009+ error = ext4_xattr_set_entry (i , s , handle , inode , ea_inode ,
2010+ true /* is_block */ );
20252011 if (error == - EFSCORRUPTED )
20262012 goto bad_block ;
20272013 if (error )
20282014 goto cleanup ;
20292015
2030- if (i -> value && s -> here -> e_value_inum ) {
2031- /*
2032- * A ref count on ea_inode has been taken as part of the call to
2033- * ext4_xattr_set_entry() above. We would like to drop this
2034- * extra ref but we have to wait until the xattr block is
2035- * initialized and has its own ref count on the ea_inode.
2036- */
2037- ea_ino = le32_to_cpu (s -> here -> e_value_inum );
2038- error = ext4_xattr_inode_iget (inode , ea_ino ,
2039- le32_to_cpu (s -> here -> e_hash ),
2040- & ea_inode );
2041- if (error ) {
2042- ea_inode = NULL ;
2043- goto cleanup ;
2044- }
2045- }
2046-
20472016inserted :
20482017 if (!IS_LAST_ENTRY (s -> first )) {
20492018 new_bh = ext4_xattr_block_cache_find (inode , header (s -> base ),
@@ -2196,17 +2165,16 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
21962165
21972166cleanup :
21982167 if (ea_inode ) {
2199- int error2 ;
2200-
2201- error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2202- if (error2 )
2203- ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2204- error2 );
2168+ if (error ) {
2169+ int error2 ;
22052170
2206- /* If there was an error, revert the quota charge. */
2207- if (error )
2171+ error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2172+ if (error2 )
2173+ ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2174+ error2 );
22082175 ext4_xattr_inode_free_quota (inode , ea_inode ,
22092176 i_size_read (ea_inode ));
2177+ }
22102178 iput (ea_inode );
22112179 }
22122180 if (ce )
@@ -2264,14 +2232,38 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
22642232{
22652233 struct ext4_xattr_ibody_header * header ;
22662234 struct ext4_xattr_search * s = & is -> s ;
2235+ struct inode * ea_inode = NULL ;
22672236 int error ;
22682237
22692238 if (!EXT4_INODE_HAS_XATTR_SPACE (inode ))
22702239 return - ENOSPC ;
22712240
2272- error = ext4_xattr_set_entry (i , s , handle , inode , false /* is_block */ );
2273- if (error )
2241+ /* If we need EA inode, prepare it before locking the buffer */
2242+ if (i -> value && i -> in_inode ) {
2243+ WARN_ON_ONCE (!i -> value_len );
2244+
2245+ ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
2246+ i -> value , i -> value_len );
2247+ if (IS_ERR (ea_inode ))
2248+ return PTR_ERR (ea_inode );
2249+ }
2250+ error = ext4_xattr_set_entry (i , s , handle , inode , ea_inode ,
2251+ false /* is_block */ );
2252+ if (error ) {
2253+ if (ea_inode ) {
2254+ int error2 ;
2255+
2256+ error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2257+ if (error2 )
2258+ ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2259+ error2 );
2260+
2261+ ext4_xattr_inode_free_quota (inode , ea_inode ,
2262+ i_size_read (ea_inode ));
2263+ iput (ea_inode );
2264+ }
22742265 return error ;
2266+ }
22752267 header = IHDR (inode , ext4_raw_inode (& is -> iloc ));
22762268 if (!IS_LAST_ENTRY (s -> first )) {
22772269 header -> h_magic = cpu_to_le32 (EXT4_XATTR_MAGIC );
@@ -2280,6 +2272,7 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
22802272 header -> h_magic = cpu_to_le32 (0 );
22812273 ext4_clear_inode_state (inode , EXT4_STATE_XATTR );
22822274 }
2275+ iput (ea_inode );
22832276 return 0 ;
22842277}
22852278
0 commit comments