@@ -1749,36 +1749,32 @@ static int ext4_insert_delayed_blocks(struct inode *inode, ext4_lblk_t lblk,
17491749}
17501750
17511751/*
1752- * This function is grabs code from the very beginning of
1753- * ext4_map_blocks, but assumes that the caller is from delayed write
1754- * time. This function looks up the requested blocks and sets the
1755- * buffer delay bit under the protection of i_data_sem.
1752+ * Looks up the requested blocks and sets the delalloc extent map.
1753+ * First try to look up for the extent entry that contains the requested
1754+ * blocks in the extent status tree without i_data_sem, then try to look
1755+ * up for the ondisk extent mapping with i_data_sem in read mode,
1756+ * finally hold i_data_sem in write mode, looks up again and add a
1757+ * delalloc extent entry if it still couldn't find any extent. Pass out
1758+ * the mapped extent through @map and return 0 on success.
17561759 */
1757- static int ext4_da_map_blocks (struct inode * inode , struct ext4_map_blocks * map ,
1758- struct buffer_head * bh )
1760+ static int ext4_da_map_blocks (struct inode * inode , struct ext4_map_blocks * map )
17591761{
17601762 struct extent_status es ;
17611763 int retval ;
1762- sector_t invalid_block = ~((sector_t ) 0xffff );
17631764#ifdef ES_AGGRESSIVE_TEST
17641765 struct ext4_map_blocks orig_map ;
17651766
17661767 memcpy (& orig_map , map , sizeof (* map ));
17671768#endif
17681769
1769- if (invalid_block < ext4_blocks_count (EXT4_SB (inode -> i_sb )-> s_es ))
1770- invalid_block = ~0 ;
1771-
17721770 map -> m_flags = 0 ;
17731771 ext_debug (inode , "max_blocks %u, logical block %lu\n" , map -> m_len ,
17741772 (unsigned long ) map -> m_lblk );
17751773
17761774 /* Lookup extent status tree firstly */
17771775 if (ext4_es_lookup_extent (inode , map -> m_lblk , NULL , & es )) {
1778- retval = es .es_len - (map -> m_lblk - es .es_lblk );
1779- if (retval > map -> m_len )
1780- retval = map -> m_len ;
1781- map -> m_len = retval ;
1776+ map -> m_len = min_t (unsigned int , map -> m_len ,
1777+ es .es_len - (map -> m_lblk - es .es_lblk ));
17821778
17831779 if (ext4_es_is_hole (& es ))
17841780 goto add_delayed ;
@@ -1788,10 +1784,8 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
17881784 * Delayed extent could be allocated by fallocate.
17891785 * So we need to check it.
17901786 */
1791- if (ext4_es_is_delayed (& es ) && !ext4_es_is_unwritten (& es )) {
1792- map_bh (bh , inode -> i_sb , invalid_block );
1793- set_buffer_new (bh );
1794- set_buffer_delay (bh );
1787+ if (ext4_es_is_delonly (& es )) {
1788+ map -> m_flags |= EXT4_MAP_DELAYED ;
17951789 return 0 ;
17961790 }
17971791
@@ -1806,7 +1800,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
18061800#ifdef ES_AGGRESSIVE_TEST
18071801 ext4_map_blocks_es_recheck (NULL , inode , map , & orig_map , 0 );
18081802#endif
1809- return retval ;
1803+ return 0 ;
18101804 }
18111805
18121806 /*
@@ -1820,7 +1814,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
18201814 retval = ext4_map_query_blocks (NULL , inode , map );
18211815 up_read (& EXT4_I (inode )-> i_data_sem );
18221816 if (retval )
1823- return retval ;
1817+ return retval < 0 ? retval : 0 ;
18241818
18251819add_delayed :
18261820 down_write (& EXT4_I (inode )-> i_data_sem );
@@ -1832,10 +1826,8 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
18321826 * the extent status tree.
18331827 */
18341828 if (ext4_es_lookup_extent (inode , map -> m_lblk , NULL , & es )) {
1835- retval = es .es_len - (map -> m_lblk - es .es_lblk );
1836- if (retval > map -> m_len )
1837- retval = map -> m_len ;
1838- map -> m_len = retval ;
1829+ map -> m_len = min_t (unsigned int , map -> m_len ,
1830+ es .es_len - (map -> m_lblk - es .es_lblk ));
18391831
18401832 if (!ext4_es_is_hole (& es )) {
18411833 up_write (& EXT4_I (inode )-> i_data_sem );
@@ -1845,18 +1837,14 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
18451837 retval = ext4_map_query_blocks (NULL , inode , map );
18461838 if (retval ) {
18471839 up_write (& EXT4_I (inode )-> i_data_sem );
1848- return retval ;
1840+ return retval < 0 ? retval : 0 ;
18491841 }
18501842 }
18511843
1844+ map -> m_flags |= EXT4_MAP_DELAYED ;
18521845 retval = ext4_insert_delayed_blocks (inode , map -> m_lblk , map -> m_len );
18531846 up_write (& EXT4_I (inode )-> i_data_sem );
1854- if (retval )
1855- return retval ;
18561847
1857- map_bh (bh , inode -> i_sb , invalid_block );
1858- set_buffer_new (bh );
1859- set_buffer_delay (bh );
18601848 return retval ;
18611849}
18621850
@@ -1876,11 +1864,15 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
18761864 struct buffer_head * bh , int create )
18771865{
18781866 struct ext4_map_blocks map ;
1867+ sector_t invalid_block = ~((sector_t ) 0xffff );
18791868 int ret = 0 ;
18801869
18811870 BUG_ON (create == 0 );
18821871 BUG_ON (bh -> b_size != inode -> i_sb -> s_blocksize );
18831872
1873+ if (invalid_block < ext4_blocks_count (EXT4_SB (inode -> i_sb )-> s_es ))
1874+ invalid_block = ~0 ;
1875+
18841876 map .m_lblk = iblock ;
18851877 map .m_len = 1 ;
18861878
@@ -1889,10 +1881,17 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
18891881 * preallocated blocks are unmapped but should treated
18901882 * the same as allocated blocks.
18911883 */
1892- ret = ext4_da_map_blocks (inode , & map , bh );
1893- if (ret <= 0 )
1884+ ret = ext4_da_map_blocks (inode , & map );
1885+ if (ret < 0 )
18941886 return ret ;
18951887
1888+ if (map .m_flags & EXT4_MAP_DELAYED ) {
1889+ map_bh (bh , inode -> i_sb , invalid_block );
1890+ set_buffer_new (bh );
1891+ set_buffer_delay (bh );
1892+ return 0 ;
1893+ }
1894+
18961895 map_bh (bh , inode -> i_sb , map .m_pblk );
18971896 ext4_update_bh_state (bh , map .m_flags );
18981897
0 commit comments