lkml.org 
[lkml]   [2020]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 226/265] btrfs: fix failure of RWF_NOWAIT write into prealloc extent beyond eof
    Date
    From: Filipe Manana <fdmanana@suse.com>

    commit 4b1946284dd6641afdb9457101056d9e6ee6204c upstream.

    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: edf064e7c6fec3 ("btrfs: nowait aio support")
    CC: stable@vger.kernel.org # 4.14+
    Signed-off-by: Filipe Manana <fdmanana@suse.com>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/btrfs/inode.c | 3 ---
    1 file changed, 3 deletions(-)

    diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
    index 18111b0263d71..6aa200e373c8f 100644
    --- a/fs/btrfs/inode.c
    +++ b/fs/btrfs/inode.c
    @@ -8262,9 +8262,6 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
    dio_data.overwrite = 1;
    inode_unlock(inode);
    relock = true;
    - } else if (iocb->ki_flags & IOCB_NOWAIT) {
    - ret = -EAGAIN;
    - goto out;
    }
    ret = btrfs_delalloc_reserve_space(inode, &data_reserved,
    offset, count);
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-06-29 23:53    [W:2.131 / U:0.752 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site