• Josef Bacik's avatar
    Btrfs: proper -ENOSPC handling · 9ed74f2d
    Josef Bacik authored
    At the start of a transaction we do a btrfs_reserve_metadata_space() and
    specify how many items we plan on modifying.  Then once we've done our
    modifications and such, just call btrfs_unreserve_metadata_space() for
    the same number of items we reserved.
    
    For keeping track of metadata needed for data I've had to add an extent_io op
    for when we merge extents.  This lets us track space properly when we are doing
    sequential writes, so we don't end up reserving way more metadata space than
    what we need.
    
    The only place where the metadata space accounting is not done is in the
    relocation code.  This is because Yan is going to be reworking that code in the
    near future, so running btrfs-vol -b could still possibly result in a ENOSPC
    related panic.  This patch also turns off the metadata_ratio stuff in order to
    allow users to more efficiently use their disk space.
    
    This patch makes it so we track how much metadata we need for an inode's
    delayed allocation extents by tracking how many extents are currently
    waiting for allocation.  It introduces two new callbacks for the
    extent_io tree's, merge_extent_hook and split_extent_hook.  These help
    us keep track of when we merge delalloc extents together and split them
    up.  Reservations are handled prior to any actually dirty'ing occurs,
    and then we unreserve after we dirty.
    
    btrfs_unreserve_metadata_for_delalloc() will make the appropriate
    unreservations as needed based on the number of reservations we
    currently have and the number of extents we currently have.  Doing the
    reservation outside of doing any of the actual dirty'ing lets us do
    things like filemap_flush() the inode to try and force delalloc to
    happen, or as a last resort actually start allocation on all delalloc
    inodes in the fs.  This has survived dbench, fs_mark and an fsx torture
    test.
    Signed-off-by: default avatarJosef Bacik <jbacik@redhat.com>
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    9ed74f2d
inode.c 155 KB