]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: do not free data reservation in fallback from inline due to -ENOSPC
authorFilipe Manana <fdmanana@suse.com>
Fri, 12 Dec 2025 17:10:10 +0000 (17:10 +0000)
committerDavid Sterba <dsterba@suse.com>
Tue, 16 Dec 2025 21:53:15 +0000 (22:53 +0100)
If we fail to create an inline extent due to -ENOSPC, we will attempt to
go through the normal COW path, reserve an extent, create an ordered
extent, etc. However we were always freeing the reserved qgroup data,
which is wrong since we will use data. Fix this by freeing the reserved
qgroup data in __cow_file_range_inline() only if we are not doing the
fallback (ret is <= 0).

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index 6633b3dc931409c3bc3355768319e83ef92497d9..c4c370b6aae9748fc04381b74d0e2ea44a1e95c9 100644 (file)
@@ -673,8 +673,12 @@ out:
         * it won't count as data extent, free them directly here.
         * And at reserve time, it's always aligned to page size, so
         * just free one page here.
+        *
+        * If we fallback to non-inline (ret == 1) due to -ENOSPC, then we need
+        * to keep the data reservation.
         */
-       btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL);
+       if (ret <= 0)
+               btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL);
        btrfs_free_path(path);
        btrfs_end_transaction(trans);
        return ret;