From patchwork Tue Jun 21 05:49:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Li Zefan X-Patchwork-Id: 899822 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5L5iVYc007574 for ; Tue, 21 Jun 2011 05:44:32 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751430Ab1FUFo3 (ORCPT ); Tue, 21 Jun 2011 01:44:29 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:65395 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1750974Ab1FUFo2 (ORCPT ); Tue, 21 Jun 2011 01:44:28 -0400 Received: from tang.cn.fujitsu.com (tang.cn.fujitsu.com [10.167.250.3]) by song.cn.fujitsu.com (Postfix) with ESMTP id 82DE1170132; Tue, 21 Jun 2011 13:44:25 +0800 (CST) Received: from mailserver.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id p5L5iOTs010100; Tue, 21 Jun 2011 13:44:24 +0800 Received: from [10.167.225.230] ([10.167.225.230]) by mailserver.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.1FP4) with ESMTP id 2011062113440274-625370 ; Tue, 21 Jun 2011 13:44:02 +0800 Message-ID: <4E0030DF.4080704@cn.fujitsu.com> Date: Tue, 21 Jun 2011 13:49:19 +0800 From: Li Zefan User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.9) Gecko/20100921 Fedora/3.1.4-1.fc14 Thunderbird/3.1.4 MIME-Version: 1.0 To: "linux-btrfs@vger.kernel.org" CC: lidongyang@novell.com Subject: [PATCH 1/2] Btrfs: fix space leak when skipping small extents during trimming X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-06-21 13:44:02, Serialize by Router on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-06-21 13:44:03, Serialize complete at 2011-06-21 13:44:03 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 21 Jun 2011 05:44:32 +0000 (UTC) We're taking a free space extent out of the free space cache, trimming it and then putting it back into the cache. However for an extent that is smaller than the specified minimum length, it's taken out but won't be put back, which causes space leak. Signed-off-by: Li Zefan --- Unfortunately I have no trim-able device to test the patch. --- fs/btrfs/free-space-cache.c | 34 +++++++++++++++++----------------- 1 files changed, 17 insertions(+), 17 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 9f985a4..292c0d9 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -2460,6 +2460,7 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, u64 bytes = 0; u64 actually_trimmed; int ret = 0; + int update_ret; *trimmed = 0; @@ -2483,6 +2484,7 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, } if (entry->bitmap) { + bytes = 0; ret = search_bitmap(ctl, entry, &start, &bytes); if (!ret) { if (start >= end) { @@ -2490,6 +2492,8 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, break; } bytes = min(bytes, end - start); + if (bytes < minlen) + goto next; bitmap_clear_bits(ctl, entry, start, bytes); if (entry->bytes == 0) free_bitmap(ctl, entry); @@ -2503,33 +2507,29 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, } else { start = entry->offset; bytes = min(entry->bytes, end - start); + if (bytes < minlen) + goto next; unlink_free_space(ctl, entry); kmem_cache_free(btrfs_free_space_cachep, entry); } spin_unlock(&ctl->tree_lock); - if (bytes >= minlen) { - int update_ret; - update_ret = btrfs_update_reserved_bytes(block_group, - bytes, 1, 1); + update_ret = btrfs_update_reserved_bytes(block_group, + bytes, 1, 1); - ret = btrfs_error_discard_extent(fs_info->extent_root, - start, - bytes, - &actually_trimmed); + ret = btrfs_error_discard_extent(fs_info->extent_root, start, + bytes, &actually_trimmed); - btrfs_add_free_space(block_group, start, bytes); - if (!update_ret) - btrfs_update_reserved_bytes(block_group, - bytes, 0, 1); + btrfs_add_free_space(block_group, start, bytes); + if (!update_ret) + btrfs_update_reserved_bytes(block_group, bytes, 0, 1); - if (ret) - break; - *trimmed += actually_trimmed; - } + if (ret) + break; + *trimmed += actually_trimmed; +next: start += bytes; - bytes = 0; if (fatal_signal_pending(current)) { ret = -ERESTARTSYS;