• Qu Wenruo's avatar
    btrfs: only unlock the to-be-submitted ranges inside a folio · bd610c09
    Qu Wenruo authored
    [SUBPAGE COMPRESSION LIMITS]
    Currently inside writepage_delalloc(), if a delalloc range is going to
    be submitted asynchronously (inline or compression, the page
    dirty/writeback/unlock are all handled in at different time, not at the
    submission time), then we return 1 and extent_writepage() will skip the
    submission.
    
    This is fine if every sector matches page size, but if a sector is
    smaller than page size (aka, subpage case), then it can be very
    problematic, for example for the following 64K page:
    
         0     16K     32K    48K     64K
         |/|   |///////|      |/|
           |                    |
           4K                   52K
    
    Where |/| is the dirty range we need to submit.
    
    In the above case, we need the following different handling for the 3
    ranges:
    
    - [0, 4K) needs to be submitted for regular write
      A single sector cannot be compressed.
    
    - [16K, 32K) needs to be submitted for compressed write
    
    - [48K, 52K) needs to be submitted for regular write.
    
    Above, if we try to submit [16K, 32K) for compressed write, we will
    return 1 and immediately, and without submitting the remaining
    [48K, 52K) range.
    
    Furthermore, since extent_writepage() will exit without unlocking any
    sectors, the submitted range [0, 4K) will not have sector unlocked.
    
    That's the reason why for now subpage is only allowed for full page
    range.
    
    [ENHANCEMENT]
    - Introduce a submission bitmap at btrfs_bio_ctrl::submit_bitmap
      This records which sectors will be submitted by extent_writepage_io().
      This allows us to track which sectors needs to be submitted thus later
      to be properly unlocked.
    
      For asynchronously submitted range (inline/compression), the
      corresponding bits will be cleared from that bitmap.
    
    - Only return 1 if no sector needs to be submitted in
      writepage_delalloc()
    
    - Only submit sectors marked by submission bitmap inside
      extent_writepage_io()
      So we won't touch the asynchronously submitted part.
    
    - Introduce btrfs_folio_end_writer_lock_bitmap() helper
      This will only unlock the involved sectors specified by @bitmap
      parameter, to avoid touching the range asynchronously submitted.
    
    Please note that, since subpage compression is still limited to page
    aligned range, this change is only a preparation for future sector
    perfect compression support for subpage.
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    bd610c09
subpage.c 29.6 KB