@@ -1749,36 +1749,32 @@ static int ext4_insert_delayed_blocks(struct inode *inode, ext4_lblk_t lblk,
1749
1749
}
1750
1750
1751
1751
/*
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.
1756
1759
*/
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 )
1759
1761
{
1760
1762
struct extent_status es ;
1761
1763
int retval ;
1762
- sector_t invalid_block = ~((sector_t ) 0xffff );
1763
1764
#ifdef ES_AGGRESSIVE_TEST
1764
1765
struct ext4_map_blocks orig_map ;
1765
1766
1766
1767
memcpy (& orig_map , map , sizeof (* map ));
1767
1768
#endif
1768
1769
1769
- if (invalid_block < ext4_blocks_count (EXT4_SB (inode -> i_sb )-> s_es ))
1770
- invalid_block = ~0 ;
1771
-
1772
1770
map -> m_flags = 0 ;
1773
1771
ext_debug (inode , "max_blocks %u, logical block %lu\n" , map -> m_len ,
1774
1772
(unsigned long ) map -> m_lblk );
1775
1773
1776
1774
/* Lookup extent status tree firstly */
1777
1775
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 ));
1782
1778
1783
1779
if (ext4_es_is_hole (& es ))
1784
1780
goto add_delayed ;
@@ -1788,10 +1784,8 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
1788
1784
* Delayed extent could be allocated by fallocate.
1789
1785
* So we need to check it.
1790
1786
*/
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 ;
1795
1789
return 0 ;
1796
1790
}
1797
1791
@@ -1806,7 +1800,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
1806
1800
#ifdef ES_AGGRESSIVE_TEST
1807
1801
ext4_map_blocks_es_recheck (NULL , inode , map , & orig_map , 0 );
1808
1802
#endif
1809
- return retval ;
1803
+ return 0 ;
1810
1804
}
1811
1805
1812
1806
/*
@@ -1820,7 +1814,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
1820
1814
retval = ext4_map_query_blocks (NULL , inode , map );
1821
1815
up_read (& EXT4_I (inode )-> i_data_sem );
1822
1816
if (retval )
1823
- return retval ;
1817
+ return retval < 0 ? retval : 0 ;
1824
1818
1825
1819
add_delayed :
1826
1820
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,
1832
1826
* the extent status tree.
1833
1827
*/
1834
1828
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 ));
1839
1831
1840
1832
if (!ext4_es_is_hole (& es )) {
1841
1833
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,
1845
1837
retval = ext4_map_query_blocks (NULL , inode , map );
1846
1838
if (retval ) {
1847
1839
up_write (& EXT4_I (inode )-> i_data_sem );
1848
- return retval ;
1840
+ return retval < 0 ? retval : 0 ;
1849
1841
}
1850
1842
}
1851
1843
1844
+ map -> m_flags |= EXT4_MAP_DELAYED ;
1852
1845
retval = ext4_insert_delayed_blocks (inode , map -> m_lblk , map -> m_len );
1853
1846
up_write (& EXT4_I (inode )-> i_data_sem );
1854
- if (retval )
1855
- return retval ;
1856
1847
1857
- map_bh (bh , inode -> i_sb , invalid_block );
1858
- set_buffer_new (bh );
1859
- set_buffer_delay (bh );
1860
1848
return retval ;
1861
1849
}
1862
1850
@@ -1876,11 +1864,15 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
1876
1864
struct buffer_head * bh , int create )
1877
1865
{
1878
1866
struct ext4_map_blocks map ;
1867
+ sector_t invalid_block = ~((sector_t ) 0xffff );
1879
1868
int ret = 0 ;
1880
1869
1881
1870
BUG_ON (create == 0 );
1882
1871
BUG_ON (bh -> b_size != inode -> i_sb -> s_blocksize );
1883
1872
1873
+ if (invalid_block < ext4_blocks_count (EXT4_SB (inode -> i_sb )-> s_es ))
1874
+ invalid_block = ~0 ;
1875
+
1884
1876
map .m_lblk = iblock ;
1885
1877
map .m_len = 1 ;
1886
1878
@@ -1889,10 +1881,17 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
1889
1881
* preallocated blocks are unmapped but should treated
1890
1882
* the same as allocated blocks.
1891
1883
*/
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 )
1894
1886
return ret ;
1895
1887
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
+
1896
1895
map_bh (bh , inode -> i_sb , map .m_pblk );
1897
1896
ext4_update_bh_state (bh , map .m_flags );
1898
1897
0 commit comments