Re: btrfs thinks fs is full, though 11GB should be still free

Qu Wenruo
2024-01-06T05:40:27Z

On 2024/1/6 11:12, Christoph Anton Mitterer wrote:
> On Fri, 2024-01-05 at 17:37 +1030, Qu Wenruo wrote:
>> but pretty hard to find a
>> good way to improve:
>
> I guess it would not be an alternative to do the work on truncate (i.e.
> check whether a lot is wasted and if so, create a new extent with just
> the right size), because that would need a full re-write of the
> extent... or would it?

I'm not sure if it's a valid idea to do all these on truncation.
It would involve doing all the backref walk to determine if it's needed
to do the COW.

>
> Also, a while ago in one of my mails I saw that:
> $ cat affected-file > new-file
> would also cause new-file to be affected... which I found pretty
> strange.
>
> Any idea why that happens?

Initially I thought that's impossible, until I tired it:

mkfs.btrfs -f $dev1
mount $dev1 $mnt
xfs_io -f -c "pwrite 0 128m" $mnt/file
sync
truncate -s 4k $mnt/file
sync
cat $mnt/file > $mnt/new
sync

Then dump tree indeed show the new file is sharing the same large extent:

item 6 key (257 INODE_ITEM 0) itemoff 15817 itemsize 160
generation 7 transid 8 size 4096 nbytes 4096
block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0
sequence 32770 flags 0x0(none)
item 7 key (257 INODE_REF 256) itemoff 15803 itemsize 14
index 2 namelen 4 name: file
item 8 key (257 EXTENT_DATA 0) itemoff 15750 itemsize 53
generation 7 type 1 (regular)
extent data disk byte 298844160 nr 134217728 <<<
extent data offset 0 nr 4096 ram 134217728
extent compression 0 (none)
item 9 key (258 INODE_ITEM 0) itemoff 15590 itemsize 160
generation 9 transid 9 size 4096 nbytes 4096
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 1 flags 0x0(none)
item 10 key (258 INODE_REF 256) itemoff 15577 itemsize 13
index 3 namelen 3 name: new
item 11 key (258 EXTENT_DATA 0) itemoff 15524 itemsize 53
generation 7 type 1 (regular)
extent data disk byte 298844160 nr 134217728 <<<
extent data offset 0 nr 4096 ram 134217728
extent compression 0 (none)

My guess is bash is doing something weird thus making the whole cat +
redirection into reflink.

But at least dd works as expected by creating a new extent.

>
>
>
>> My previous guess is totally wrong, it has nothing to do with
>> NODATACOW/PREALLOC flags at all.
>>
>> It's a defrag only problem.
>
> Sure, but I meant, if a file is NODATACOW and would be prealloced to a
> large size and then truncated - would it also loose the extra space?

That would be the same.

>
>
> And do you think that other CoW fs would be affected, too? IIRC XFS is
> also about to get CoW features... so may it's simply an IO pattern that
> developers need to avoid with modern filesystems.

Not sure, maybe XFS would do extra extent split to solve the problem.

Thanks,
Qu

>
>
> Cheers,
> Chris-
>