From patchwork Tue Sep 30 14:40:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 5003751 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E4B3B9F327 for ; Tue, 30 Sep 2014 14:41:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EAE2520131 for ; Tue, 30 Sep 2014 14:41:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E85DE2012D for ; Tue, 30 Sep 2014 14:41:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751901AbaI3OlE (ORCPT ); Tue, 30 Sep 2014 10:41:04 -0400 Received: from mail-pd0-f172.google.com ([209.85.192.172]:33125 "EHLO mail-pd0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751467AbaI3OlC (ORCPT ); Tue, 30 Sep 2014 10:41:02 -0400 Received: by mail-pd0-f172.google.com with SMTP id p10so2938717pdj.17 for ; Tue, 30 Sep 2014 07:41:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:user-agent:mime-version :content-type; bh=yyLxbQHzlrzFYmGAFODzw8sbYW1MkqA5J2pge5scFFU=; b=PLVJFUZM9A/7+rGn+0p0DMzErh/zd5RjJAaTbGRUgG5hUe2aqWYMr+RQ2mePxrXRtA EmOophxKn1vFNFkC/IK8hUJ7XH9Bfk0U0HQwdh4wMJHn8xV4qSshNQGpTcH3JLJu2kPQ w39JIrsjBWp+0sIBGckI45o3oY+wVVUNlFe+7f+A3YMhqcec7JUhSsYUgvATuA+G9qVk Ni0B66P3VSuWSHo9KKn8Gh+oqQR5y7s5Pkotw6Wul8OOzAj18HirkvA2HieacpTqmqr/ OL8+/M80sDCu/v7wPRTjsomC6lfCUTQFTNG8Fail4d7Xh4oN6u5GvFqjq+FqS0Lytw/p UHyg== X-Received: by 10.66.157.73 with SMTP id wk9mr69851636pab.101.1412088061774; Tue, 30 Sep 2014 07:41:01 -0700 (PDT) Received: from ako (pl398.nas931.p-kanagawa.nttpc.ne.jp. [219.102.77.142]) by mx.google.com with ESMTPSA id e5sm15396094pdn.62.2014.09.30.07.40.59 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 30 Sep 2014 07:41:00 -0700 (PDT) From: Naohiro Aota To: linux-btrfs Cc: bo.li.liu@oracle.com Subject: [PATCH] btrfs-progs: do not reclaim extent buffer Date: Tue, 30 Sep 2014 23:40:56 +0900 Message-ID: <87zjdh41dz.fsf@elisp.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We should kill free_some_buffers() to stop reclaiming extent buffers or we will hit a problem described below. As of commit 53ee1bccf99cd5b474fe1aa857b7dd176e3a1407, we are not counting a reference for tree->lru anymore. However free_some_buffers() is still left and is reclaiming extent buffers whose @refs == 1. This cause extent buffers to be reclaimed unintentionally. Thus the following steps could happen: 1. A buffer at address A is reclaimed by free_some_buffers() (address A is also free()ed) 2. Some code call alloc_extent_buffer() 3. Address A is assigned to newly allocated buffer 4. You see a buffer pointed by A suddenly changed its content This problem is also pointed out here and it has a reproducer: https://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg36703.html This commit drop free_some_buffers() and related variables, and also it modify extent_io_tree_cleanup() to catch non-free'ed buffers properly. Signed-off-by: Naohiro Aota --- extent_io.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/extent_io.c b/extent_io.c index 1df377d..425af8a 100644 --- a/extent_io.c +++ b/extent_io.c @@ -30,9 +30,6 @@ #include "ctree.h" #include "volumes.h" -static u64 cache_soft_max = 1024 * 1024 * 256; -static u64 cache_hard_max = 1 * 1024 * 1024 * 1024; - void extent_io_tree_init(struct extent_io_tree *tree) { cache_tree_init(&tree->state); @@ -77,12 +74,9 @@ void extent_io_tree_cleanup(struct extent_io_tree *tree) while(!list_empty(&tree->lru)) { eb = list_entry(tree->lru.next, struct extent_buffer, lru); - if (eb->refs != 1) { - fprintf(stderr, "extent buffer leak: " - "start %llu len %u\n", - (unsigned long long)eb->start, eb->len); - eb->refs = 1; - } + fprintf(stderr, "extent buffer leak: " + "start %llu len %u\n", + (unsigned long long)eb->start, eb->len); free_extent_buffer(eb); } @@ -541,30 +535,6 @@ out: return ret; } -static int free_some_buffers(struct extent_io_tree *tree) -{ - u32 nrscan = 0; - struct extent_buffer *eb; - struct list_head *node, *next; - - if (tree->cache_size < cache_soft_max) - return 0; - - list_for_each_safe(node, next, &tree->lru) { - eb = list_entry(node, struct extent_buffer, lru); - if (eb->refs == 1 && !(eb->flags & EXTENT_DIRTY)) { - free_extent_buffer(eb); - if (tree->cache_size < cache_hard_max) - break; - } else { - list_move_tail(&eb->lru, &tree->lru); - } - if (nrscan++ > 64 && tree->cache_size < cache_hard_max) - break; - } - return 0; -} - static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, u64 bytenr, u32 blocksize) { @@ -589,7 +559,6 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, eb->cache_node.size = blocksize; INIT_LIST_HEAD(&eb->recow); - free_some_buffers(tree); ret = insert_cache_extent(&tree->cache, &eb->cache_node); if (ret) { free(eb);