• Josef Bacik's avatar
    btrfs: adjust overcommit logic when very close to full · cb6cbab7
    Josef Bacik authored
    A user reported some unpleasant behavior with very small file systems.
    The reproducer is this
    
      $ mkfs.btrfs -f -m single -b 8g /dev/vdb
      $ mount /dev/vdb /mnt/test
      $ dd if=/dev/zero of=/mnt/test/testfile bs=512M count=20
    
    This will result in usage that looks like this
    
      Overall:
          Device size:                   8.00GiB
          Device allocated:              8.00GiB
          Device unallocated:            1.00MiB
          Device missing:                  0.00B
          Device slack:                  2.00GiB
          Used:                          5.47GiB
          Free (estimated):              2.52GiB      (min: 2.52GiB)
          Free (statfs, df):               0.00B
          Data ratio:                       1.00
          Metadata ratio:                   1.00
          Global reserve:                5.50MiB      (used: 0.00B)
          Multiple profiles:                  no
    
      Data,single: Size:7.99GiB, Used:5.46GiB (68.41%)
         /dev/vdb        7.99GiB
    
      Metadata,single: Size:8.00MiB, Used:5.77MiB (72.07%)
         /dev/vdb        8.00MiB
    
      System,single: Size:4.00MiB, Used:16.00KiB (0.39%)
         /dev/vdb        4.00MiB
    
      Unallocated:
         /dev/vdb        1.00MiB
    
    As you can see we've gotten ourselves quite full with metadata, with all
    of the disk being allocated for data.
    
    On smaller file systems there's not a lot of time before we get full, so
    our overcommit behavior bites us here.  Generally speaking data
    reservations result in chunk allocations as we assume reservation ==
    actual use for data.  This means at any point we could end up with a
    chunk allocation for data, and if we're very close to full we could do
    this before we have a chance to figure out that we need another metadata
    chunk.
    
    Address this by adjusting the overcommit logic.  Simply put we need to
    take away 1 chunk from the available chunk space in case of a data
    reservation.  This will allow us to stop overcommitting before we
    potentially lose this space to a data allocation.  With this fix in
    place we properly allocate a metadata chunk before we're completely
    full, allowing for enough slack space in metadata.
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    cb6cbab7
space-info.c 59.1 KB