Skip to content
Snippets Groups Projects
Commit ed46208d authored by Qu Wenruo's avatar Qu Wenruo Committed by Yang Yingliang
Browse files

btrfs: allow btrfs_truncate_block() to fallback to nocow for data space reservation

mainline inclusion
from mainline-v5.13-rc5
commit 6d4572a9
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I39MZM
CVE: NA

------------------------------------------------------

[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.

Reference: https://patchwork.kernel.org/project/linux-btrfs/patch/20200130052822.11765-1-wqu@suse.com


Reported-by: default avatarMartin Doucha <martin.doucha@suse.com>
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Conflicts:
	fs/btrfs/file.c
	fs/btrfs/inode.c
Signed-off-by: default avatarGou Hao <gouhao@uniontech.com>
Signed-off-by: default avatarCheng Jian <cj.chengjian@huawei.com>
Reviewed-by: default avatarJiao Fenfang <jiaofenfang@uniontech.com>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 3a50d694
No related branches found
No related tags found
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment