• Chris Mason's avatar
    Btrfs: keep pages dirty when using btrfs_writepage_fixup_worker · 25f3c502
    Chris Mason authored
    For COW, btrfs expects pages dirty pages to have been through a few setup
    steps.  This includes reserving space for the new block allocations and marking
    the range in the state tree for delayed allocation.
    
    A few places outside btrfs will dirty pages directly, especially when unmapping
    mmap'd pages.  In order for these to properly go through COW, we run them
    through a fixup worker to wait for stable pages, and do the delalloc prep.
    
    87826df0 added a window where the dirty pages were cleaned, but pending
    more action from the fixup worker.  We clear_page_dirty_for_io() before
    we call into writepage, so the page is no longer dirty.  The commit
    changed it so now we leave the page clean between unlocking it here and
    the fixup worker starting at some point in the future.
    
    During this window, page migration can jump in and relocate the page.  Once our
    fixup work actually starts, it finds page->mapping is NULL and we end up
    freeing the page without ever writing it.
    
    This leads to crc errors and other exciting problems, since it screws up the
    whole statemachine for waiting for ordered extents.  The fix here is to keep
    the page dirty while we're waiting for the fixup worker to get to work.
    This is accomplished by returning -EAGAIN from btrfs_writepage_cow_fixup
    if we queued the page up for fixup, which will cause the writepage
    function to redirty the page.
    
    Because we now expect the page to be dirty once it gets to the fixup
    worker we must adjust the error cases to call clear_page_dirty_for_io()
    on the page.  That is the bulk of the patch, but it is not the fix, the
    fix is the -EAGAIN from btrfs_writepage_cow_fixup.  We cannot separate
    these two changes out because the error conditions change with the new
    expectations.
    Signed-off-by: default avatarChris Mason <clm@fb.com>
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    25f3c502
inode.c 285 KB