• Brian Foster's avatar
    xfs: clean up unwritten buffers on write failure · 60630fe6
    Brian Foster authored
    The xfs_vm_write_failed() handler is currently responsible for cleaning
    up any delalloc blocks over the range of a failed write beyond EOF.
    Failure to do so results in warning messages and other inconsistencies
    between buffer and extent state. The ->releasepage() handler currently
    warns in the event of a page being released with either unwritten or
    delalloc buffers, as neither is ever expected by the time a page is
    released.
    
    As has been reproduced by generic/083 on a -bsize=1k fs, it is currently
    possible to trigger the ->releasepage() warning for a page with
    unwritten buffers when a filesystem is near ENOSPC. This is reproduced
    by the following sequence:
    
      $ mkfs.xfs -f -b size=1k -d size=100m <dev>
      $ mount <dev> /mnt/
      $
      $ xfs_io -fc "falloc -k 0 1k" /mnt/file
      $ dd if=/dev/zero of=/mnt/enospc conv=notrunc oflag=append
      $
      $ xfs_io -c "pwrite 512 1k" /mnt/file
      $ xfs_io -d -c "pwrite 16k 1k" /mnt/file
    
    The first pwrite command attempts a block unaligned write across an
    unwritten block and a hole. The delalloc for the hole fails with ENOSPC
    and the subsequent error handling does not clean up the unwritten buffer
    that was instantiated during the first ->get_block() call.
    
    The second pwrite triggers a warning as part of the inode mapping
    invalidation that occurs prior to direct I/O. The releasepage() handler
    detects the unwritten buffer at this time, warns and prevents the
    release of the page.
    
    To deal with this problem, update xfs_vm_write_failed() to clean up
    unwritten as well as delalloc buffers that are beyond EOF and within the
    range of the failed write.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    
    60630fe6
xfs_aops.c 54.6 KB