• Qu Wenruo's avatar
    btrfs: make relocate_one_page() handle subpage case · c2832898
    Qu Wenruo authored
    For subpage case, one page of data reloc inode can contain several file
    extents, like this:
    
    |<--- File extent A --->| FE B | FE C |<--- File extent D -->|
    		|<--------- Page --------->|
    
    We can no longer use PAGE_SIZE directly for various operations.
    
    This patch will relocate_one_page() to handle subpage case by:
    - Iterating through all extents of a cluster when marking pages
      When marking pages dirty and delalloc, we need to check the cluster
      extent boundary.
      Now we introduce a loop to go extent by extent of a page, until we
      either finished the last extent, or reach the page end.
    
      By this, regular sectorsize == PAGE_SIZE can still work as usual, since
      we will do that loop only once.
    
    - Iteration start from max(page_start, extent_start)
      Since we can have the following case:
    			| FE B | FE C |<--- File extent D -->|
    		|<--------- Page --------->|
      Thus we can't always start from page_start, but do a
      max(page_start, extent_start)
    
    - Iteration end when the cluster is exhausted
      Similar to previous case, the last file extent can end before the page
      end:
    |<--- File extent A --->| FE B | FE C |
    		|<--------- Page --------->|
      In this case, we need to manually exit the loop after we have finished
      the last extent of the cluster.
    
    - Reserve metadata space for each extent range
      Since now we can hit multiple ranges in one page, we should reserve
      metadata for each range, not simply PAGE_SIZE.
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    c2832898
relocation.c 111 KB