• Filipe Manana's avatar
    btrfs: fix failure of RWF_NOWAIT write into prealloc extent beyond eof · 4b194628
    Filipe Manana authored
    If we attempt to write to prealloc extent located after eof using a
    RWF_NOWAIT write, we always fail with -EAGAIN.
    
    We do actually check if we have an allocated extent for the write at
    the start of btrfs_file_write_iter() through a call to check_can_nocow(),
    but later when we go into the actual direct IO write path we simply
    return -EAGAIN if the write starts at or beyond EOF.
    
    Trivial to reproduce:
    
      $ mkfs.btrfs -f /dev/sdb
      $ mount /dev/sdb /mnt
    
      $ touch /mnt/foo
      $ chattr +C /mnt/foo
    
      $ xfs_io -d -c "pwrite -S 0xab 0 64K" /mnt/foo
      wrote 65536/65536 bytes at offset 0
      64 KiB, 16 ops; 0.0004 sec (135.575 MiB/sec and 34707.1584 ops/sec)
    
      $ xfs_io -c "falloc -k 64K 1M" /mnt/foo
    
      $ xfs_io -d -c "pwrite -N -V 1 -S 0xfe -b 64K 64K 64K" /mnt/foo
      pwrite: Resource temporarily unavailable
    
    On xfs and ext4 the write succeeds, as expected.
    
    Fix this by removing the wrong check at btrfs_direct_IO().
    
    Fixes: edf064e7 ("btrfs: nowait aio support")
    CC: stable@vger.kernel.org # 4.14+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    4b194628
inode.c 285 KB