diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0569c745475c..787497d536b6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1904,34 +1904,48 @@ static int ext4_writepage(struct page *page, | |||
1904 | * | 1904 | * |
1905 | * @mpd - extent of blocks | 1905 | * @mpd - extent of blocks |
1906 | * @lblk - logical number of the block in the file | 1906 | * @lblk - logical number of the block in the file |
1907 | * @b_state - b_state of the buffer head added | 1907 | * @bh - buffer head we want to add to the extent |
1908 | * | 1908 | * |
1909 | * the function is used to collect contig. blocks in same state | 1909 | * The function is used to collect contig. blocks in the same state. If the |
1910 | * buffer doesn't require mapping for writeback and we haven't started the | ||
1911 | * extent of buffers to map yet, the function returns 'true' immediately - the | ||
1912 | * caller can write the buffer right away. Otherwise the function returns true | ||
1913 | * if the block has been added to the extent, false if the block couldn't be | ||
1914 | * added. | ||
1910 | */ | 1915 | */ |
1911 | static int mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk, | 1916 | static bool mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk, |
1912 | unsigned long b_state) | 1917 | struct buffer_head *bh) |
1913 | { | 1918 | { |
1914 | struct ext4_map_blocks *map = &mpd->map; | 1919 | struct ext4_map_blocks *map = &mpd->map; |
1915 | 1920 | ||
1916 | /* Don't go larger than mballoc is willing to allocate */ | 1921 | /* Buffer that doesn't need mapping for writeback? */ |
1917 | if (map->m_len >= MAX_WRITEPAGES_EXTENT_LEN) | 1922 | if (!buffer_dirty(bh) || !buffer_mapped(bh) || |
1918 | return 0; | 1923 | (!buffer_delay(bh) && !buffer_unwritten(bh))) { |
1924 | /* So far no extent to map => we write the buffer right away */ | ||
1925 | if (map->m_len == 0) | ||
1926 | return true; | ||
1927 | return false; | ||
1928 | } | ||
1919 | 1929 | ||
1920 | /* First block in the extent? */ | 1930 | /* First block in the extent? */ |
1921 | if (map->m_len == 0) { | 1931 | if (map->m_len == 0) { |
1922 | map->m_lblk = lblk; | 1932 | map->m_lblk = lblk; |
1923 | map->m_len = 1; | 1933 | map->m_len = 1; |
1924 | map->m_flags = b_state & BH_FLAGS; | 1934 | map->m_flags = bh->b_state & BH_FLAGS; |
1925 | return 1; | 1935 | return true; |
1926 | } | 1936 | } |
1927 | 1937 | ||
1938 | /* Don't go larger than mballoc is willing to allocate */ | ||
1939 | if (map->m_len >= MAX_WRITEPAGES_EXTENT_LEN) | ||
1940 | return false; | ||
1941 | |||
1928 | /* Can we merge the block to our big extent? */ | 1942 | /* Can we merge the block to our big extent? */ |
1929 | if (lblk == map->m_lblk + map->m_len && | 1943 | if (lblk == map->m_lblk + map->m_len && |
1930 | (b_state & BH_FLAGS) == map->m_flags) { | 1944 | (bh->b_state & BH_FLAGS) == map->m_flags) { |
1931 | map->m_len++; | 1945 | map->m_len++; |
1932 | return 1; | 1946 | return true; |
1933 | } | 1947 | } |
1934 | return 0; | 1948 | return false; |
1935 | } | 1949 | } |
1936 | 1950 | ||
1937 | static bool add_page_bufs_to_extent(struct mpage_da_data *mpd, | 1951 | static bool add_page_bufs_to_extent(struct mpage_da_data *mpd, |
@@ -1946,18 +1960,13 @@ static bool add_page_bufs_to_extent(struct mpage_da_data *mpd, | |||
1946 | do { | 1960 | do { |
1947 | BUG_ON(buffer_locked(bh)); | 1961 | BUG_ON(buffer_locked(bh)); |
1948 | 1962 | ||
1949 | if (!buffer_dirty(bh) || !buffer_mapped(bh) || | 1963 | if (lblk >= blocks || !mpage_add_bh_to_extent(mpd, lblk, bh)) { |
1950 | (!buffer_delay(bh) && !buffer_unwritten(bh)) || | ||
1951 | lblk >= blocks) { | ||
1952 | /* Found extent to map? */ | 1964 | /* Found extent to map? */ |
1953 | if (mpd->map.m_len) | 1965 | if (mpd->map.m_len) |
1954 | return false; | 1966 | return false; |
1955 | if (lblk >= blocks) | 1967 | /* Everything mapped so far and we hit EOF */ |
1956 | return true; | 1968 | return true; |
1957 | continue; | ||
1958 | } | 1969 | } |
1959 | if (!mpage_add_bh_to_extent(mpd, lblk, bh->b_state)) | ||
1960 | return false; | ||
1961 | } while (lblk++, (bh = bh->b_this_page) != head); | 1970 | } while (lblk++, (bh = bh->b_this_page) != head); |
1962 | return true; | 1971 | return true; |
1963 | } | 1972 | } |