From patchwork Mon Mar 11 12:42:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yan, Zheng" X-Patchwork-Id: 2248651 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 1E6CC3FCF6 for ; Mon, 11 Mar 2013 12:42:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754107Ab3CKMmw (ORCPT ); Mon, 11 Mar 2013 08:42:52 -0400 Received: from mga09.intel.com ([134.134.136.24]:39024 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753961Ab3CKMmv (ORCPT ); Mon, 11 Mar 2013 08:42:51 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 11 Mar 2013 05:41:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,822,1355126400"; d="scan'208";a="276352354" Received: from unknown (HELO zyan5-mobl.ccr.corp.intel.com) ([10.255.20.118]) by orsmga001.jf.intel.com with ESMTP; 11 Mar 2013 05:42:47 -0700 From: "Yan, Zheng" To: ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: sage@inktank.com, greg@inktank.com, david@fromorbit.com, viro@zeniv.linux.org.uk, "Yan, Zheng" Subject: [PATCH 1/2] fs: remove dentry_lru_prune() Date: Mon, 11 Mar 2013 20:42:45 +0800 Message-Id: <1363005765-15305-1-git-send-email-zheng.z.yan@intel.com> X-Mailer: git-send-email 1.7.11.7 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org From: "Yan, Zheng" When pruning a dentry, its ancestor dentry can also be pruned. But the ancestor dentry does not go through dput(), so it does not get put on the dentry LRU. Hence associating d_prune with removing the dentry from the LRU is the wrong. The fix is remove dentry_lru_prune(). Modify all its callers to use dentry_lru_del() and call file system's d_prune() callback directly. Signed-off-by: Yan, Zheng --- fs/dcache.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 19153a0..ceedd04 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -337,23 +337,6 @@ static void dentry_lru_del(struct dentry *dentry) } } -/* - * Remove a dentry that is unreferenced and about to be pruned - * (unhashed and destroyed) from the LRU, and inform the file system. - * This wrapper should be called _prior_ to unhashing a victim dentry. - */ -static void dentry_lru_prune(struct dentry *dentry) -{ - if (!list_empty(&dentry->d_lru)) { - if (dentry->d_flags & DCACHE_OP_PRUNE) - dentry->d_op->d_prune(dentry); - - spin_lock(&dcache_lru_lock); - __dentry_lru_del(dentry); - spin_unlock(&dcache_lru_lock); - } -} - static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list) { spin_lock(&dcache_lru_lock); @@ -486,11 +469,13 @@ relock: if (ref) dentry->d_count--; /* - * if dentry was on the d_lru list delete it from there. * inform the fs via d_prune that this dentry is about to be * unhashed and destroyed. */ - dentry_lru_prune(dentry); + if (dentry->d_flags & DCACHE_OP_PRUNE) + dentry->d_op->d_prune(dentry); + + dentry_lru_del(dentry); /* if it was on the hash then remove it */ __d_drop(dentry); return d_kill(dentry, parent); @@ -921,11 +906,13 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) struct inode *inode; /* - * remove the dentry from the lru, and inform - * the fs that this dentry is about to be + * inform the fs that this dentry is about to be * unhashed and destroyed. */ - dentry_lru_prune(dentry); + if (dentry->d_flags & DCACHE_OP_PRUNE) + dentry->d_op->d_prune(dentry); + + dentry_lru_del(dentry); __d_shrink(dentry); if (dentry->d_count != 0) {