summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobbie Ko <robbieko@synology.com>2020-07-20 09:42:09 +0800
committerDavid Sterba <dsterba@suse.com>2020-07-21 22:08:53 +0200
commit5909ca110b29aa16b23b52b8de8d3bb1035fd738 (patch)
tree234936c92deb13a58c926fa4a0edcbad13e34099
parentfa91e4aa1716004ea8096d5185ec0451e206aea0 (diff)
btrfs: fix page leaks after failure to lock page for delalloc
When locking pages for delalloc, we check if it's dirty and mapping still matches. If it does not match, we need to return -EAGAIN and release all pages. Only the current page was put though, iterate over all the remaining pages too. CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Robbie Ko <robbieko@synology.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/extent_io.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 95313bb7fe40..72c836b54efc 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1999,7 +1999,8 @@ static int __process_pages_contig(struct address_space *mapping,
if (!PageDirty(pages[i]) ||
pages[i]->mapping != mapping) {
unlock_page(pages[i]);
- put_page(pages[i]);
+ for (; i < ret; i++)
+ put_page(pages[i]);
err = -EAGAIN;
goto out;
}