• D
    xfs: don't screw up direct writes when freesp is fragmented · 6d8a45ce
    Darrick J. Wong 提交于
    xfs_bmap_btalloc is given a range of file offset blocks that must be
    allocated to some data/attr/cow fork.  If the fork has an extent size
    hint associated with it, the request will be enlarged on both ends to
    try to satisfy the alignment hint.  If free space is fragmentated,
    sometimes we can allocate some blocks but not enough to fulfill any of
    the requested range.  Since bmapi_allocate always trims the new extent
    mapping to match the originally requested range, this results in
    bmapi_write returning zero and no mapping.
    
    The consequences of this vary -- buffered writes will simply re-call
    bmapi_write until it can satisfy at least one block from the original
    request.  Direct IO overwrites notice nmaps == 0 and return -ENOSPC
    through the dio mechanism out to userspace with the weird result that
    writes fail even when we have enough space because the ENOSPC return
    overrides any partial write status.  For direct CoW writes the situation
    was disastrous because nobody notices us returning an invalid zero-length
    wrong-offset mapping to iomap and the write goes off into space.
    
    Therefore, if free space is so fragmented that we managed to allocate
    some space but not enough to map into even a single block of the
    original allocation request range, we should break the alignment hint in
    order to guarantee at least some forward progress for the direct write.
    If we return a short allocation to iomap_apply it'll call back about the
    remaining blocks.
    Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: NChristoph Hellwig <hch@lst.de>
    6d8a45ce
xfs_bmap.c 169.2 KB