xfs: use contiguous bdev reservation for file preallocation

The block device reservation that occurs as part of transaction
reservation uses a worst case algorithm to determine the amount of
reservation required to satisfy the transaction. This means that one
bdev (i.e., device-mapper) block is reserved per required filesystem
block, even though the former block size is likely much larger than the
latter.

Worst case reservation is required in most cases because, from the
perspective of the transaction, block allocation can occur throughout
the block address space. This is unnecessary for some operations where
more context is available, however. xfs_alloc_file_space() is one such
case. It calls xfs_bmapi_write() in a loop and once per transaction.
Since it also passes nmap == 1, each call maps a single extent and thus
allocates contiguous blocks. Based on that, the bdev reservation can be
reduced from the worst case 1-1 mapping to a more optimal 1-N mapping of
dm blocks to fs blocks (e.g., one dm block can cover many fs blocks).

Update xfs_alloc_file_space() to bypass transaction based bdev
reservation. Instead, open-code the bdev reservation using the more
optimal contiguous reservation value. This allows fallocate requests to
consume just about all of the available space in a thin volume without
premature ENOSPC errors.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 file changed