On 2019/12/10 上午8:52, Qu Wenruo wrote:
>
>
> On 2019/12/10 上午2:56, Martin Raiber wrote:
>> On 07.12.2019 08:28 Qu Wenruo wrote:
>>>
>>> On 2019/12/7 上午5:26, Martin Raiber wrote:
>>>> Hi,
>>>>
>>>> with kernel 5.4.1 I have the problem that df shows 100% space used. I
>>>> can still write to the btrfs volume, but my software looks at the
>>>> available space and starts deleting stuff if statfs() says there is a
>>>> low amount of available space.
>>> If the bug still happens, mind to try the snippet to see why this happened?
>>>
>>> You will need to:
>>> - Apply the patch to your kernel code
>>> - Recompile the kernel or btrfs module
>>> So this needs some experience in kernel compile.
>>> - Reboot to newly compiled kernel or load the debug btrfs module
>>>
>>> Thanks,
>>> Qu
>>>
>>> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
>>> index 23aa630f04c9..cf34c05b16d7 100644
>>> --- a/fs/btrfs/relocation.c
>>> +++ b/fs/btrfs/relocation.c
>>> @@ -523,7 +523,8 @@ static int should_ignore_root(struct btrfs_root *root)
>>> {
>>> struct btrfs_root *reloc_root;
>>>
>>> - if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
>>> + if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
>>> + test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
>>> return 0;
>>>
>>> reloc_root = root->reloc_root;
>>> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
>>> index f452a94abdc3..c2b70d97a63b 100644
>>> --- a/fs/btrfs/super.c
>>> +++ b/fs/btrfs/super.c
>>> @@ -2064,6 +2064,8 @@ static int btrfs_statfs(struct dentry *dentry,
>>> struct kstatfs *buf)
>>> found->disk_used;
>>> }
>>>
>>> + pr_info("%s: found type=0x%llx disk_used=%llu factor=%d\n",
>>> + __func__, found->flags, found->disk_used, factor);
>>> total_used += found->disk_used;
>>> }
>>>
>>> @@ -2071,6 +2073,8 @@ static int btrfs_statfs(struct dentry *dentry,
>>> struct kstatfs *buf)
>>>
>>> buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super),
>>> factor);
>>> buf->f_blocks >>= bits;
>>> + pr_info("%s: super_total_bytes=%llu total_used=%llu
>>> factor=%d\n", __func__,
>>> + btrfs_super_total_bytes(disk_super), total_used, factor);
>>> buf->f_bfree = buf->f_blocks - (div_u64(total_used, factor) >>
>>> bits);
>>>
>>> /* Account global block reserve as used, it's in logical size
>>> already */
>>>
>> Applied. It's currently 100% used directly after reboot, and I am
>> getting this log output:
>
> Thank you a lot for the debug output!
>
>>
>> [...]
>> [ 241.245150] btrfs_statfs: super_total_bytes=128835387392
>> total_used=93778841600 factor=1
>> [ 241.904824] btrfs_statfs: found type=0x1 disk_used=93464006656 factor=1
>> [ 241.904824] btrfs_statfs: found type=0x4 disk_used=314818560 factor=1
>> [ 241.904824] btrfs_statfs: found type=0x2 disk_used=16384 factor=1
>> [ 241.904824] btrfs_statfs: super_total_bytes=128835387392
>> total_used=93778841600 factor=1
>
> This proves the on-disk numbers are all correct, so far so good.
>
> The remaining problem is the block_rsv part. Which matches with the new
> ticket system introduced in v5.4.
>
> Mind to test the new debug snippet?
>
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index f452a94abdc3..516969534095 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -2076,6 +2076,8 @@ static int btrfs_statfs(struct dentry *dentry,
> struct kstatfs *buf)
> /* Account global block reserve as used, it's in logical size
> already */
> spin_lock(&block_rsv->lock);
> /* Mixed block groups accounting is not byte-accurate, avoid
> overflow */
> + pr_info("%s: block_rsv->size=%llu block_rsv->reserved=%llu\n",
> __func__,
> + block_rsv->size, block_rsv->reserved);
> if (buf->f_bfree >= block_rsv->size >> bits)
> buf->f_bfree -= block_rsv->size >> bits;
> else
>
And this extra snippet for available space.
Thanks,
Qu
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f452a94abdc3..f1a3e01a0ef5 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1911,6 +1911,7 @@ static inline int
btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
* We aren't under the device list lock, so this is racy-ish,
but good
* enough for our purposes.
*/
+ pr_info("%s: original_free_bytes=%llu\n", __func__, *free_bytes);
nr_devices = fs_info->fs_devices->open_devices;
if (!nr_devices) {
smp_mb();
@@ -2005,6 +2006,7 @@ static inline int
btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
kfree(devices_info);
*free_bytes = avail_space;
+ pr_info("%s: calculated_bytes=%llu\n", __func__, avail_space);
return 0;
}
Attachment:
signature.asc
Description: OpenPGP digital signature
