From patchwork Wed Jan 23 12:03:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Liu X-Patchwork-Id: 214905 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 5F5732C007E for ; Wed, 23 Jan 2013 22:51:08 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755859Ab3AWLvF (ORCPT ); Wed, 23 Jan 2013 06:51:05 -0500 Received: from mail-pa0-f51.google.com ([209.85.220.51]:59961 "EHLO mail-pa0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755824Ab3AWLvC (ORCPT ); Wed, 23 Jan 2013 06:51:02 -0500 Received: by mail-pa0-f51.google.com with SMTP id fb11so4721234pad.24 for ; Wed, 23 Jan 2013 03:51:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=t2jnto8WuR0d5BjCNDoUb30SB+H2nC1PuwbV/t1OEUw=; b=pczybaZG9ACv3VfH4mxOCxRVq0saeBcx6Nqz4HxxCFlFNrKZiUz7UomO/CWk8n2RYj smEqoeXXqpHjdYquYCs9v8JGDVhugHBymg1EBJiI3sliT3CrQ5ntStIjKaADXU4BoZ9F /KZF4lq85bL3o9DIBTWBfrGuhHvIw3pho40puDaUrbGMQfIxOIVqTSbTLT6Q89A9et/E 04MMRYnPk1/LwQwznYYhnOFE9whY/8fKRI+MLSbScGOCRAIIVNq/h9XVJjPc1Zifp4if A44Da/rCCAxUmsBCl9CP0/H27m2P9rJrSXvPl8MJxWSdQGgmyFmhkyQPO0FBsvUd6aA9 z0qg== X-Received: by 10.68.239.99 with SMTP id vr3mr2578946pbc.154.1358941861142; Wed, 23 Jan 2013 03:51:01 -0800 (PST) Received: from lz-desktop.taobao.ali.com ([182.92.247.2]) by mx.google.com with ESMTPS id az8sm13439631pab.3.2013.01.23.03.50.55 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 23 Jan 2013 03:50:59 -0800 (PST) From: Zheng Liu To: linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: "Theodore Ts'o" , Dave Chinner , Zheng Liu Subject: [PATCH 08/10 v3] fs: allow for fs-specific objects to be pruned as part of pruning inodes Date: Wed, 23 Jan 2013 20:03:58 +0800 Message-Id: <1358942640-2262-9-git-send-email-wenqing.lz@taobao.com> X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e In-Reply-To: <1358942640-2262-1-git-send-email-wenqing.lz@taobao.com> References: <1358942640-2262-1-git-send-email-wenqing.lz@taobao.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Theodore Ts'o The VFS's prune_super() function allows for the file system to prune file-system specific objects. Ext4 would like to use this to prune parts of the inode's extent cache. The object lifetime rules used by ext4 is somewhat different from the those of the dentry and inode in the VFS. Ext4's extent cache objects can be pruned without removing the inode; however if an inode is pruned, all of the extent cache objects associated with the inode are immediately removed. To accomodate this rule, we measure the number of fs-specific objects before the dentry and inodes are pruned, and then measure them again afterwards. If the number of fs-specific objects have decreased, we credit that decrease as part of the shrink operation, so that we do not end up removing too many fs-specific objects. In the case where fs-specific objects are not removed when inodes are removed, this will not change the behavior of prune_super() in any appreciable way. (Currently the only other user of this facility is XFS, and this change should not affect XFS's usage of this facility for this reason.) Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: Dave Chinner Cc: Zheng Liu --- fs/super.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/super.c b/fs/super.c index 12f1237..fb57bd2 100644 --- a/fs/super.c +++ b/fs/super.c @@ -80,6 +80,7 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc) if (sc->nr_to_scan) { int dentries; int inodes; + int fs_to_scan = 0; /* proportion the scan between the caches */ dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) / @@ -87,7 +88,7 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc) inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) / total_objects; if (fs_objects) - fs_objects = (sc->nr_to_scan * fs_objects) / + fs_to_scan = (sc->nr_to_scan * fs_objects) / total_objects; /* * prune the dcache first as the icache is pinned by it, then @@ -96,8 +97,23 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc) prune_dcache_sb(sb, dentries); prune_icache_sb(sb, inodes); - if (fs_objects && sb->s_op->free_cached_objects) { - sb->s_op->free_cached_objects(sb, fs_objects); + /* + * If as a result of pruning the icache, we released some + * of the fs_objects, give credit to the fact and + * reduce the number of fs objects that we should try + * to release. + */ + if (fs_to_scan) { + int fs_objects_now = sb->s_op->nr_cached_objects(sb); + + if (fs_objects_now < fs_objects) + fs_to_scan -= fs_objects - fs_objects_now; + if (fs_to_scan < 0) + fs_to_scan = 0; + } + + if (fs_to_scan && sb->s_op->free_cached_objects) { + sb->s_op->free_cached_objects(sb, fs_to_scan); fs_objects = sb->s_op->nr_cached_objects(sb); } total_objects = sb->s_nr_dentry_unused +