On Thu, Oct 08, 2020 at 06:59:54PM +0800, Anand Jain wrote: > From: Qu Wenruo <wqu@xxxxxxxx> > > commit 6d4572a9d71d5fc2affee0258d8582d39859188c upstream. > > [BUG] > When the data space is exhausted, even if the inode has NOCOW attribute, > we will still refuse to truncate unaligned range due to ENOSPC. > > The following script can reproduce it pretty easily: > #!/bin/bash > > dev=/dev/test/test > mnt=/mnt/btrfs > > umount $dev &> /dev/null > umount $mnt &> /dev/null > > mkfs.btrfs -f $dev -b 1G > mount -o nospace_cache $dev $mnt > touch $mnt/foobar > chattr +C $mnt/foobar > > xfs_io -f -c "pwrite -b 4k 0 4k" $mnt/foobar > /dev/null > xfs_io -f -c "pwrite -b 4k 0 1G" $mnt/padding &> /dev/null > sync > > xfs_io -c "fpunch 0 2k" $mnt/foobar > umount $mnt > > Currently this will fail at the fpunch part. > > [CAUSE] > Because btrfs_truncate_block() always reserves space without checking > the NOCOW attribute. > > Since the writeback path follows NOCOW bit, we only need to bother the > space reservation code in btrfs_truncate_block(). > > [FIX] > Make btrfs_truncate_block() follow btrfs_buffered_write() to try to > reserve data space first, and fall back to NOCOW check only when we > don't have enough space. > > Such always-try-reserve is an optimization introduced in > btrfs_buffered_write(), to avoid expensive btrfs_check_can_nocow() call. > > This patch will export check_can_nocow() as btrfs_check_can_nocow(), and > use it in btrfs_truncate_block() to fix the problem. > > Reported-by: Martin Doucha <martin.doucha@xxxxxxxx> > Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx> > Reviewed-by: Anand Jain <anand.jain@xxxxxxxxxx> > Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> > Reviewed-by: David Sterba <dsterba@xxxxxxxx> > Signed-off-by: David Sterba <dsterba@xxxxxxxx> > Signed-off-by: Anand Jain <anand.jain@xxxxxxxxxx> > Conflicts: > fs/btrfs/ctree.h > fs/btrfs/file.c > fs/btrfs/inode.c Why are these Conflicts: lines here? Anyway, fixed up, and all queued up now, thansk! greg k-h