Commit 09930042 authored by Jan Kara's avatar Jan Kara Committed by Theodore Ts'o

ext4: move test whether extent to map can be extended to one place

Currently the logic whether the current buffer can be added to an extent
of buffers to map is split between mpage_add_bh_to_extent() and
add_page_bufs_to_extent(). Move the whole logic to
mpage_add_bh_to_extent() which makes things a bit more straightforward
and make following i_size fixes easier.
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
parent 7d734532
...@@ -1904,34 +1904,48 @@ static int ext4_writepage(struct page *page, ...@@ -1904,34 +1904,48 @@ static int ext4_writepage(struct page *page,
* *
* @mpd - extent of blocks * @mpd - extent of blocks
* @lblk - logical number of the block in the file * @lblk - logical number of the block in the file
* @b_state - b_state of the buffer head added * @bh - buffer head we want to add to the extent
* *
* the function is used to collect contig. blocks in same state * The function is used to collect contig. blocks in the same state. If the
* buffer doesn't require mapping for writeback and we haven't started the
* extent of buffers to map yet, the function returns 'true' immediately - the
* caller can write the buffer right away. Otherwise the function returns true
* if the block has been added to the extent, false if the block couldn't be
* added.
*/ */
static int mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk, static bool mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk,
unsigned long b_state) struct buffer_head *bh)
{ {
struct ext4_map_blocks *map = &mpd->map; struct ext4_map_blocks *map = &mpd->map;
/* Don't go larger than mballoc is willing to allocate */ /* Buffer that doesn't need mapping for writeback? */
if (map->m_len >= MAX_WRITEPAGES_EXTENT_LEN) if (!buffer_dirty(bh) || !buffer_mapped(bh) ||
return 0; (!buffer_delay(bh) && !buffer_unwritten(bh))) {
/* So far no extent to map => we write the buffer right away */
if (map->m_len == 0)
return true;
return false;
}
/* First block in the extent? */ /* First block in the extent? */
if (map->m_len == 0) { if (map->m_len == 0) {
map->m_lblk = lblk; map->m_lblk = lblk;
map->m_len = 1; map->m_len = 1;
map->m_flags = b_state & BH_FLAGS; map->m_flags = bh->b_state & BH_FLAGS;
return 1; return true;
} }
/* Don't go larger than mballoc is willing to allocate */
if (map->m_len >= MAX_WRITEPAGES_EXTENT_LEN)
return false;
/* Can we merge the block to our big extent? */ /* Can we merge the block to our big extent? */
if (lblk == map->m_lblk + map->m_len && if (lblk == map->m_lblk + map->m_len &&
(b_state & BH_FLAGS) == map->m_flags) { (bh->b_state & BH_FLAGS) == map->m_flags) {
map->m_len++; map->m_len++;
return 1; return true;
} }
return 0; return false;
} }
static bool add_page_bufs_to_extent(struct mpage_da_data *mpd, 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,18 +1960,13 @@ static bool add_page_bufs_to_extent(struct mpage_da_data *mpd,
do { do {
BUG_ON(buffer_locked(bh)); BUG_ON(buffer_locked(bh));
if (!buffer_dirty(bh) || !buffer_mapped(bh) || if (lblk >= blocks || !mpage_add_bh_to_extent(mpd, lblk, bh)) {
(!buffer_delay(bh) && !buffer_unwritten(bh)) ||
lblk >= blocks) {
/* Found extent to map? */ /* Found extent to map? */
if (mpd->map.m_len) if (mpd->map.m_len)
return false; return false;
if (lblk >= blocks) /* Everything mapped so far and we hit EOF */
return true; return true;
continue;
} }
if (!mpage_add_bh_to_extent(mpd, lblk, bh->b_state))
return false;
} while (lblk++, (bh = bh->b_this_page) != head); } while (lblk++, (bh = bh->b_this_page) != head);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment