btrfs: qgroup: Fix wrong qgroup reservation update for relationship modification
authorQu Wenruo <wqu@suse.com>
Tue, 12 Dec 2017 07:34:26 +0000 (15:34 +0800)
committerDavid Sterba <dsterba@suse.com>
Fri, 30 Mar 2018 23:41:13 +0000 (01:41 +0200)
commit429d6275d50199dd4c3a5876754003ae06c7f927
treeb47ee31fb7a7cad1a85e734142bf28512c416f3f
parentdba213242fbcfc5495004ab76ca27c35ce1bf304
btrfs: qgroup: Fix wrong qgroup reservation update for relationship modification

When modifying qgroup relationship, for qgroup which only owns exclusive
extents, we will go through quick update path.

In this path, we will add/subtract exclusive and reference number for
parent qgroup, since the source (child) qgroup only has exclusive
extents, destination (parent) qgroup will also own or lose those extents
exclusively.

The same should be the same for reservation, since later reservation
adding/releasing will also affect parent qgroup, without the reservation
carried from child, parent will underflow reservation or have dead
reservation which will never be freed.

However original code doesn't do the same thing for reservation.
It handles qgroup reservation quite differently:

It removes qgroup reservation, as it's allocating space from the
reserved qgroup for relationship adding.
But does nothing for qgroup reservation if we're removing a qgroup
relationship.

According to the original code, it looks just like because we're adding
qgroup->rfer, the code assumes we're writing new data, so it's follows
the normal write routine, by reducing qgroup->reserved and adding
qgroup->rfer/excl.

This old behavior is wrong, and should be fixed to follow the same
excl/rfer behavior.

Just fix it by using the correct behavior described above.

Fixes: 31193213f1f9 ("Btrfs: qgroup: Introduce a may_use to account space_info->bytes_may_use.")
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/qgroup.c