ext4: move test whether extent to map can be extended to one place
authorJan Kara <jack@suse.cz>
Sat, 17 Aug 2013 13:57:56 +0000 (09:57 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 17 Aug 2013 13:57:56 +0000 (09:57 -0400)
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: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
fs/ext4/inode.c

index 0569c74..787497d 100644 (file)
@@ -1904,34 +1904,48 @@ static int ext4_writepage(struct page *page,
  *
  * @mpd - extent of blocks
  * @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,
-                                 unsigned long b_state)
+static bool mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk,
+                                  struct buffer_head *bh)
 {
        struct ext4_map_blocks *map = &mpd->map;
 
-       /* Don't go larger than mballoc is willing to allocate */
-       if (map->m_len >= MAX_WRITEPAGES_EXTENT_LEN)
-               return 0;
+       /* Buffer that doesn't need mapping for writeback? */
+       if (!buffer_dirty(bh) || !buffer_mapped(bh) ||
+           (!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? */
        if (map->m_len == 0) {
                map->m_lblk = lblk;
                map->m_len = 1;
-               map->m_flags = b_state & BH_FLAGS;
-               return 1;
+               map->m_flags = bh->b_state & BH_FLAGS;
+               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? */
        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++;
-               return 1;
+               return true;
        }
-       return 0;
+       return false;
 }
 
 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 {
                BUG_ON(buffer_locked(bh));
 
-               if (!buffer_dirty(bh) || !buffer_mapped(bh) ||
-                   (!buffer_delay(bh) && !buffer_unwritten(bh)) ||
-                   lblk >= blocks) {
+               if (lblk >= blocks || !mpage_add_bh_to_extent(mpd, lblk, bh)) {
                        /* Found extent to map? */
                        if (mpd->map.m_len)
                                return false;
-                       if (lblk >= blocks)
-                               return true;
-                       continue;
+                       /* Everything mapped so far and we hit EOF */
+                       return true;
                }
-               if (!mpage_add_bh_to_extent(mpd, lblk, bh->b_state))
-                       return false;
        } while (lblk++, (bh = bh->b_this_page) != head);
        return true;
 }