• Qu Wenruo's avatar
    btrfs: refactor main loop in memmove_extent_buffer() · 096d2301
    Qu Wenruo authored
    [BACKGROUND]
    Currently memove_extent_buffer() does a loop where it strop at any page
    boundary inside [dst_offset, dst_offset + len) or [src_offset,
    src_offset + len).
    
    This is mostly allowing us to do copy_pages(), but if we're going to use
    folios we will need to handle multi-page (the old behavior) or single
    folio (the new optimization).
    
    The current code would be a burden for future changes.
    
    [ENHANCEMENT]
    Instead of sticking with copy_pages(), here we utilize the new
    __write_extent_buffer() helper to handle the writes.
    
    Unlike the refactoring in memcpy_extent_buffer(), we can not just rely
    on the write_extent_buffer() and only handle page boundaries inside src
    range.
    
    The function write_extent_buffer() itself is still doing forward
    writing, thus it cannot handle the following case: (already in the
    extent buffer memory operation tests, cross page overlapping run 2)
    
    	Src	Page boundary
    	|///////|
    	    |///|////|
    	    Dst
    
    In the above case, if we just follow page boundary in the src range, we
    have no need to do any split, just one __write_extent_buffer() with
    use_memmove = true.
    
    But __write_extent_buffer() would split the dst range into two,
    so it first copies the beginning part of the src range into the first half
    of the dst range.
    After this operation, the beginning of the dst range is already updated,
    causing corruption.
    
    So we have to follow the old behavior of handling both page boundaries.
    
    And since we're the last caller of copy_pages(), we can remove it
    completely.
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    096d2301
extent_io.c 128 KB