Patch "btrfs: fix double accounting of ordered extent for subpage case in btrfs_invalidapge" has been added to the 5.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    btrfs: fix double accounting of ordered extent for subpage case in btrfs_invalidapge

to the 5.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     btrfs-fix-double-accounting-of-ordered-extent-for-su.patch
and it can be found in the queue-5.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit b826338e19565f0a9cb18cf2c615f36cf61db316
Author: Qu Wenruo <wqu@xxxxxxxx>
Date:   Wed Jan 27 14:38:48 2021 +0800

    btrfs: fix double accounting of ordered extent for subpage case in btrfs_invalidapge
    
    [ Upstream commit 951c80f83d61bd4b21794c8aba829c3c1a45c2d0 ]
    
    Commit dbfdb6d1b369 ("Btrfs: Search for all ordered extents that could
    span across a page") make btrfs_invalidapage() to search all ordered
    extents.
    
    The offending code looks like this:
    
      again:
              start = page_start;
              ordered = btrfs_lookup_ordered_range(inode, start, page_end - start + 1);
              if (ordred) {
                      end = min(page_end,
                                ordered->file_offset + ordered->num_bytes - 1);
    
                      /* Do the cleanup */
    
                      start = end + 1;
                      if (start < page_end)
                              goto again;
              }
    
    The behavior is indeed necessary for the incoming subpage support, but
    when it iterates through all the ordered extents, it also resets the
    search range @start.
    
    This means, for the following cases, we can double account the ordered
    extents, causing its bytes_left underflow:
    
            Page offset
            0               16K             32K
            |<--- OE 1  --->|<--- OE 2 ---->|
    
    As the first iteration will find ordered extent (OE) 1, which doesn't
    cover the full page, thus after cleanup code, we need to retry again.
    But again label will reset start to page_start, and we got OE 1 again,
    which causes double accounting on OE 1, and cause OE 1's byte_left to
    underflow.
    
    This problem can only happen for subpage case, as for regular sectorsize
    == PAGE_SIZE case, we will always find a OE ends at or after page end,
    thus no way to trigger the problem.
    
    Move the again label after start = page_start.  There will be more
    comprehensive rework to convert the open coded loop to a proper while
    loop for subpage support.
    
    Fixes: dbfdb6d1b369 ("Btrfs: Search for all ordered extents that could span across a page")
    Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx>
    Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
    Signed-off-by: David Sterba <dsterba@xxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a8e0a6b038d3e..ad34c5a09befc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8186,8 +8186,9 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 
 	if (!inode_evicting)
 		lock_extent_bits(tree, page_start, page_end, &cached_state);
-again:
+
 	start = page_start;
+again:
 	ordered = btrfs_lookup_ordered_range(inode, start, page_end - start + 1);
 	if (ordered) {
 		found_ordered = true;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux