]> git.hungrycats.org Git - linux/commitdiff
btrfs: fix double put of block group with nocow
authorJosef Bacik <josef@toxicpanda.com>
Mon, 6 Jul 2020 13:14:12 +0000 (09:14 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Mon, 31 Aug 2020 19:10:51 +0000 (15:10 -0400)
commit 230ed397435e85b54f055c524fcb267ae2ce3bc4 upstream.

While debugging a patch that I wrote I was hitting use-after-free panics
when accessing block groups on unmount.  This turned out to be because
in the nocow case if we bail out of doing the nocow for whatever reason
we need to call btrfs_dec_nocow_writers() if we called the inc.  This
puts our block group, but a few error cases does

if (nocow) {
    btrfs_dec_nocow_writers();
    goto error;
}

unfortunately, error is

error:
if (nocow)
btrfs_dec_nocow_writers();

so we get a double put on our block group.  Fix this by dropping the
error cases calling of btrfs_dec_nocow_writers(), as it's handled at the
error label now.

Fixes: 762bf09893b4 ("btrfs: improve error handling in run_delalloc_nocow")
CC: stable@vger.kernel.org # 5.4+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 026f830e0ba388b2f7db3510f3e89c0cacd9eb8e)

fs/btrfs/inode.c

index b37a72b765e98cd013794a0435fcedf5710dea7e..57b324dd528d4b0abcde136b2fb25c0f3fe47090 100644 (file)
@@ -1680,12 +1680,8 @@ out_check:
                        ret = fallback_to_cow(inode, locked_page, cow_start,
                                              found_key.offset - 1,
                                              page_started, nr_written);
-                       if (ret) {
-                               if (nocow)
-                                       btrfs_dec_nocow_writers(fs_info,
-                                                               disk_bytenr);
+                       if (ret)
                                goto error;
-                       }
                        cow_start = (u64)-1;
                }
 
@@ -1701,9 +1697,6 @@ out_check:
                                          ram_bytes, BTRFS_COMPRESS_NONE,
                                          BTRFS_ORDERED_PREALLOC);
                        if (IS_ERR(em)) {
-                               if (nocow)
-                                       btrfs_dec_nocow_writers(fs_info,
-                                                               disk_bytenr);
                                ret = PTR_ERR(em);
                                goto error;
                        }