• Qu Wenruo's avatar
    btrfs: make Private2 lifespan more consistent · 87b4d86b
    Qu Wenruo authored
    Currently we use page Private2 bit to indicate that we have ordered
    extent for the page range.
    
    But the lifespan of it is not consistent, during regular writeback path,
    there are two locations to clear the same PagePrivate2:
    
        T ----- Page marked Dirty
        |
        + ----- Page marked Private2, through btrfs_run_dealloc_range()
        |
        + ----- Page cleared Private2, through btrfs_writepage_cow_fixup()
        |       in __extent_writepage_io()
        |       ^^^ Private2 cleared for the first time
        |
        + ----- Page marked Writeback, through btrfs_set_range_writeback()
        |       in __extent_writepage_io().
        |
        + ----- Page cleared Private2, through
        |       btrfs_writepage_endio_finish_ordered()
        |       ^^^ Private2 cleared for the second time.
        |
        + ----- Page cleared Writeback, through
                btrfs_writepage_endio_finish_ordered()
    
    Currently PagePrivate2 is mostly to prevent ordered extent accounting
    being executed for both endio and invalidatepage.
    Thus only the one who cleared page Private2 is responsible for ordered
    extent accounting.
    
    But the fact is, in btrfs_writepage_endio_finish_ordered(), page
    Private2 is cleared and ordered extent accounting is executed
    unconditionally.
    
    The race prevention only happens through btrfs_invalidatepage(), where
    we wait for the page writeback first, before checking the Private2 bit.
    
    This means, Private2 is also protected by Writeback bit, and there is no
    need for btrfs_writepage_cow_fixup() to clear Priavte2.
    
    This patch will change btrfs_writepage_cow_fixup() to just check
    PagePrivate2, not to clear it.
    The clearing will happen in either btrfs_invalidatepage() or
    btrfs_writepage_endio_finish_ordered().
    
    This makes the Private2 bit easier to understand, just meaning the page
    has unfinished ordered extent attached to it.
    
    And this patch is a hard requirement for the incoming refactoring for
    how we finished ordered IO for endio context, as the coming patch will
    check Private2 to determine if we need to do the ordered extent
    accounting.  Thus this patch is definitely needed or we will hang due to
    unfinished ordered extent.
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    87b4d86b
inode.c 298 KB