diff mbox series

[4/5] btrfs: dont clear qgroup rsv bit in release_folio

Message ID 9a8e2f9639330dd5e82db11a49f84fa17cb9988d.1701464169.git.boris@bur.io (mailing list archive)
State New, archived
Headers show
Series btrfs: qgroups rsv fixes | expand

Commit Message

Boris Burkov Dec. 1, 2023, 9 p.m. UTC
The EXTENT_QGROUP_RESERVED bit is used to "lock" regions of the file for
duplicate reservations. That is two writes to that range in one
transaction shouldn't create two reservations, as the reservation will
only be freed once when the write finally goes down. Therefore, it is
never OK to clear that bit without freeing the associated qgroup rsv. At
this point, we don't want to be freeing the rsv, so mask off the bit.

Signed-off-by: Boris Burkov <boris@bur.io>
---
 fs/btrfs/extent_io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Qu Wenruo Dec. 4, 2023, 9:09 p.m. UTC | #1
On 2023/12/2 07:30, Boris Burkov wrote:
> The EXTENT_QGROUP_RESERVED bit is used to "lock" regions of the file for
> duplicate reservations. That is two writes to that range in one
> transaction shouldn't create two reservations, as the reservation will
> only be freed once when the write finally goes down. Therefore, it is
> never OK to clear that bit without freeing the associated qgroup rsv. At
> this point, we don't want to be freeing the rsv, so mask off the bit.

Did you have any dmesg output for this case? I believe this would lead
to a underflow.
>
> Signed-off-by: Boris Burkov <boris@bur.io>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/extent_io.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index 0143bf63044c..87283087c669 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -2310,7 +2310,8 @@ static int try_release_extent_state(struct extent_io_tree *tree,
>   		ret = 0;
>   	} else {
>   		u32 clear_bits = ~(EXTENT_LOCKED | EXTENT_NODATASUM |
> -				   EXTENT_DELALLOC_NEW | EXTENT_CTLBITS);
> +				   EXTENT_DELALLOC_NEW | EXTENT_CTLBITS
> +				   | EXTENT_QGROUP_RESERVED);
>
>   		/*
>   		 * At this point we can safely clear everything except the
diff mbox series

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 0143bf63044c..87283087c669 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2310,7 +2310,8 @@  static int try_release_extent_state(struct extent_io_tree *tree,
 		ret = 0;
 	} else {
 		u32 clear_bits = ~(EXTENT_LOCKED | EXTENT_NODATASUM |
-				   EXTENT_DELALLOC_NEW | EXTENT_CTLBITS);
+				   EXTENT_DELALLOC_NEW | EXTENT_CTLBITS
+				   | EXTENT_QGROUP_RESERVED);
 
 		/*
 		 * At this point we can safely clear everything except the