@@ -1619,14 +1619,14 @@ static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle,
16191619static int ext4_xattr_set_entry (struct ext4_xattr_info * i ,
16201620 struct ext4_xattr_search * s ,
16211621 handle_t * handle , struct inode * inode ,
1622+ struct inode * new_ea_inode ,
16221623 bool is_block )
16231624{
16241625 struct ext4_xattr_entry * last , * next ;
16251626 struct ext4_xattr_entry * here = s -> here ;
16261627 size_t min_offs = s -> end - s -> base , name_len = strlen (i -> name );
16271628 int in_inode = i -> in_inode ;
16281629 struct inode * old_ea_inode = NULL ;
1629- struct inode * new_ea_inode = NULL ;
16301630 size_t old_size , new_size ;
16311631 int ret ;
16321632
@@ -1711,38 +1711,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
17111711 old_ea_inode = NULL ;
17121712 goto out ;
17131713 }
1714- }
1715- if (i -> value && in_inode ) {
1716- WARN_ON_ONCE (!i -> value_len );
1717-
1718- new_ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
1719- i -> value , i -> value_len );
1720- if (IS_ERR (new_ea_inode )) {
1721- ret = PTR_ERR (new_ea_inode );
1722- new_ea_inode = NULL ;
1723- goto out ;
1724- }
1725- }
17261714
1727- if (old_ea_inode ) {
17281715 /* We are ready to release ref count on the old_ea_inode. */
17291716 ret = ext4_xattr_inode_dec_ref (handle , old_ea_inode );
1730- if (ret ) {
1731- /* Release newly required ref count on new_ea_inode. */
1732- if (new_ea_inode ) {
1733- int err ;
1734-
1735- err = ext4_xattr_inode_dec_ref (handle ,
1736- new_ea_inode );
1737- if (err )
1738- ext4_warning_inode (new_ea_inode ,
1739- "dec ref new_ea_inode err=%d" ,
1740- err );
1741- ext4_xattr_inode_free_quota (inode , new_ea_inode ,
1742- i -> value_len );
1743- }
1717+ if (ret )
17441718 goto out ;
1745- }
17461719
17471720 ext4_xattr_inode_free_quota (inode , old_ea_inode ,
17481721 le32_to_cpu (here -> e_value_size ));
@@ -1866,7 +1839,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
18661839 ret = 0 ;
18671840out :
18681841 iput (old_ea_inode );
1869- iput (new_ea_inode );
18701842 return ret ;
18711843}
18721844
@@ -1929,9 +1901,21 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19291901 size_t old_ea_inode_quota = 0 ;
19301902 unsigned int ea_ino ;
19311903
1932-
19331904#define header (x ) ((struct ext4_xattr_header *)(x))
19341905
1906+ /* If we need EA inode, prepare it before locking the buffer */
1907+ if (i -> value && i -> in_inode ) {
1908+ WARN_ON_ONCE (!i -> value_len );
1909+
1910+ ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
1911+ i -> value , i -> value_len );
1912+ if (IS_ERR (ea_inode )) {
1913+ error = PTR_ERR (ea_inode );
1914+ ea_inode = NULL ;
1915+ goto cleanup ;
1916+ }
1917+ }
1918+
19351919 if (s -> base ) {
19361920 int offset = (char * )s -> here - bs -> bh -> b_data ;
19371921
@@ -1940,6 +1924,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19401924 EXT4_JTR_NONE );
19411925 if (error )
19421926 goto cleanup ;
1927+
19431928 lock_buffer (bs -> bh );
19441929
19451930 if (header (s -> base )-> h_refcount == cpu_to_le32 (1 )) {
@@ -1966,7 +1951,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
19661951 }
19671952 ea_bdebug (bs -> bh , "modifying in-place" );
19681953 error = ext4_xattr_set_entry (i , s , handle , inode ,
1969- true /* is_block */ );
1954+ ea_inode , true /* is_block */ );
19701955 ext4_xattr_block_csum_set (inode , bs -> bh );
19711956 unlock_buffer (bs -> bh );
19721957 if (error == - EFSCORRUPTED )
@@ -2034,29 +2019,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
20342019 s -> end = s -> base + sb -> s_blocksize ;
20352020 }
20362021
2037- error = ext4_xattr_set_entry (i , s , handle , inode , true /* is_block */ );
2022+ error = ext4_xattr_set_entry (i , s , handle , inode , ea_inode ,
2023+ true /* is_block */ );
20382024 if (error == - EFSCORRUPTED )
20392025 goto bad_block ;
20402026 if (error )
20412027 goto cleanup ;
20422028
2043- if (i -> value && s -> here -> e_value_inum ) {
2044- /*
2045- * A ref count on ea_inode has been taken as part of the call to
2046- * ext4_xattr_set_entry() above. We would like to drop this
2047- * extra ref but we have to wait until the xattr block is
2048- * initialized and has its own ref count on the ea_inode.
2049- */
2050- ea_ino = le32_to_cpu (s -> here -> e_value_inum );
2051- error = ext4_xattr_inode_iget (inode , ea_ino ,
2052- le32_to_cpu (s -> here -> e_hash ),
2053- & ea_inode );
2054- if (error ) {
2055- ea_inode = NULL ;
2056- goto cleanup ;
2057- }
2058- }
2059-
20602029inserted :
20612030 if (!IS_LAST_ENTRY (s -> first )) {
20622031 new_bh = ext4_xattr_block_cache_find (inode , header (s -> base ),
@@ -2209,17 +2178,16 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
22092178
22102179cleanup :
22112180 if (ea_inode ) {
2212- int error2 ;
2213-
2214- error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2215- if (error2 )
2216- ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2217- error2 );
2181+ if (error ) {
2182+ int error2 ;
22182183
2219- /* If there was an error, revert the quota charge. */
2220- if (error )
2184+ error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2185+ if (error2 )
2186+ ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2187+ error2 );
22212188 ext4_xattr_inode_free_quota (inode , ea_inode ,
22222189 i_size_read (ea_inode ));
2190+ }
22232191 iput (ea_inode );
22242192 }
22252193 if (ce )
@@ -2277,14 +2245,38 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
22772245{
22782246 struct ext4_xattr_ibody_header * header ;
22792247 struct ext4_xattr_search * s = & is -> s ;
2248+ struct inode * ea_inode = NULL ;
22802249 int error ;
22812250
22822251 if (!EXT4_INODE_HAS_XATTR_SPACE (inode ))
22832252 return - ENOSPC ;
22842253
2285- error = ext4_xattr_set_entry (i , s , handle , inode , false /* is_block */ );
2286- if (error )
2254+ /* If we need EA inode, prepare it before locking the buffer */
2255+ if (i -> value && i -> in_inode ) {
2256+ WARN_ON_ONCE (!i -> value_len );
2257+
2258+ ea_inode = ext4_xattr_inode_lookup_create (handle , inode ,
2259+ i -> value , i -> value_len );
2260+ if (IS_ERR (ea_inode ))
2261+ return PTR_ERR (ea_inode );
2262+ }
2263+ error = ext4_xattr_set_entry (i , s , handle , inode , ea_inode ,
2264+ false /* is_block */ );
2265+ if (error ) {
2266+ if (ea_inode ) {
2267+ int error2 ;
2268+
2269+ error2 = ext4_xattr_inode_dec_ref (handle , ea_inode );
2270+ if (error2 )
2271+ ext4_warning_inode (ea_inode , "dec ref error=%d" ,
2272+ error2 );
2273+
2274+ ext4_xattr_inode_free_quota (inode , ea_inode ,
2275+ i_size_read (ea_inode ));
2276+ iput (ea_inode );
2277+ }
22872278 return error ;
2279+ }
22882280 header = IHDR (inode , ext4_raw_inode (& is -> iloc ));
22892281 if (!IS_LAST_ENTRY (s -> first )) {
22902282 header -> h_magic = cpu_to_le32 (EXT4_XATTR_MAGIC );
@@ -2293,6 +2285,7 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
22932285 header -> h_magic = cpu_to_le32 (0 );
22942286 ext4_clear_inode_state (inode , EXT4_STATE_XATTR );
22952287 }
2288+ iput (ea_inode );
22962289 return 0 ;
22972290}
22982291
0 commit comments