Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1551373

[PATCH 4.8 28/85] Btrfs: fix memory leak in reading btree blocks

From Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Newsgroups linux.kernel
Subject [PATCH 4.8 28/85] Btrfs: fix memory leak in reading btree blocks
Date 2017-01-04 22:20 +0100
Message-ID <sW18u-1M9-33@gated-at.bofh.it> (permalink)
References <sW0P7-1np-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


4.8-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Liu Bo <bo.li.liu@oracle.com>

commit 2571e739677f1e4c0c63f5ed49adcc0857923625 upstream.

So we can read a btree block via readahead or intentional read,
and we can end up with a memory leak when something happens as
follows,
1) readahead starts to read block A but does not wait for read
   completion,
2) btree_readpage_end_io_hook finds that block A is corrupted,
   and it needs to clear all block A's pages' uptodate bit.
3) meanwhile an intentional read kicks in and checks block A's
   pages' uptodate to decide which page needs to be read.
4) when some pages have the uptodate bit during 3)'s check so
   3) doesn't count them for eb->io_pages, but they are later
   cleared by 2) so we has to readpage on the page, we get
   the wrong eb->io_pages which results in a memory leak of
   this block.

This fixes the problem by firstly getting all pages's locking and
then checking pages' uptodate bit.

   t1(readahead)                              t2(readahead endio)                                       t3(the following read)
read_extent_buffer_pages                    end_bio_extent_readpage
  for pg in eb:                                for page 0,1,2 in eb:
      if pg is uptodate:                           btree_readpage_end_io_hook(pg)
          num_reads++                              if uptodate:
  eb->io_pages = num_reads                             SetPageUptodate(pg)              _______________
  for pg in eb:                                for page 3 in eb:                                     read_extent_buffer_pages
       if pg is NOT uptodate:                      btree_readpage_end_io_hook(pg)                       for pg in eb:
           __extent_read_full_page(pg)                 sanity check reports something wrong                 if pg is uptodate:
                                                       clear_extent_buffer_uptodate(eb)                         num_reads++
                                                           for pg in eb:                                eb->io_pages = num_reads
                                                               ClearPageUptodate(page)  _______________
                                                                                                        for pg in eb:
                                                                                                            if pg is NOT uptodate:
                                                                                                                __extent_read_full_page(pg)

So t3's eb->io_pages is not consistent with the number of pages it's reading,
and during endio(), atomic_dec_and_test(&eb->io_pages) will get a negative
number so that we're not able to free the eb.

Signed-off-by: Liu Bo <bo.li.liu@oracle.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>

---
 fs/btrfs/extent_io.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5209,11 +5209,20 @@ int read_extent_buffer_pages(struct exte
 			lock_page(page);
 		}
 		locked_pages++;
+	}
+	/*
+	 * We need to firstly lock all pages to make sure that
+	 * the uptodate bit of our pages won't be affected by
+	 * clear_extent_buffer_uptodate().
+	 */
+	for (i = start_i; i < num_pages; i++) {
+		page = eb->pages[i];
 		if (!PageUptodate(page)) {
 			num_reads++;
 			all_uptodate = 0;
 		}
 	}
+
 	if (all_uptodate) {
 		if (start_i == 0)
 			set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 4.8 00/85] 4.8.16-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:10 +0100
  [PATCH 4.8 13/85] USB: cdc-acm: add device id for GW Instek AFG-125 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 27/85] clk: ti: omap36xx: Work around sprz319 advisory 2.1 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 24/85] ALSA: hda - fix headset-mic problem on a Dell laptop Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 21/85] ALSA: hiface: Fix M2Tech hiFace driver sampling rate change Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 02/85] btrfs: limit async_work allocation and worker func duration Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 33/85] Btrfs: fix memory leak in do_walk_down Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 29/85] Btrfs: bail out if block group has different mixed flag Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 28/85] Btrfs: fix memory leak in reading btree blocks Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 01/85] aoe: fix crash in page count manipulation Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 15/85] usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 26/85] ALSA: hda: when comparing pin configurations, ignore assoc in addition to seq Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 34/85] btrfs: fix a possible umount deadlock Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 31/85] Btrfs: dont leak reloc root nodes on error Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 32/85] btrfs: clean the old superblocks before freeing the device Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 18/85] USB: UHCI: report non-PME wakeup signalling for Intel hardware Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  [PATCH 4.8 11/85] USB: serial: option: add dlink dwm-158 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:20 +0100
  Re: [PATCH 4.8 00/85] 4.8.16-stable review Shuah Khan <shuah.kh@samsung.com> - 2017-01-05 01:50 +0100
  Re: [PATCH 4.8 00/85] 4.8.16-stable review Guenter Roeck <linux@roeck-us.net> - 2017-01-05 05:50 +0100

csiph-web