From patchwork Thu Mar 17 00:55:22 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 640811 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2H0tYZE027440 for ; Thu, 17 Mar 2011 00:55:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752297Ab1CQAzd (ORCPT ); Wed, 16 Mar 2011 20:55:33 -0400 Received: from cantor2.suse.de ([195.135.220.15]:45551 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752118Ab1CQAzd (ORCPT ); Wed, 16 Mar 2011 20:55:33 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id BF3B687104; Thu, 17 Mar 2011 01:55:31 +0100 (CET) Date: Thu, 17 Mar 2011 11:55:22 +1100 From: NeilBrown To: , Cc: , Subject: Re: Use of READDIRPLUS on large directories Message-ID: <20110317115522.29020461@notabene.brown> In-Reply-To: <20110317084038.6d4ea49d@notabene.brown> References: <20110316155528.31913c58@notabene.brown> <5E6794FC7B8FCA41A704019BE3C70E8B068397B4@MX31A.corp.emc.com> <20110317084038.6d4ea49d@notabene.brown> X-Mailer: Claws Mail 3.7.8 (GTK+ 2.20.1; x86_64-unknown-linux-gnu) Mime-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@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]); Thu, 17 Mar 2011 00:55:36 +0000 (UTC) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 2c3eb33..6882e14 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -804,6 +804,9 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) desc->dir_cookie = &nfs_file_open_context(filp)->dir_cookie; desc->decode = NFS_PROTO(inode)->decode_dirent; desc->plus = NFS_USE_READDIRPLUS(inode); + if (filp->f_pos > 0 && !test_bit(NFS_INO_SEEN_GETATTR, &NFS_I(inode)->flags)) + desc->plus = 0; + clear_bit(NFS_INO_SEEN_GETATTR, &NFS_I(inode)->flags); nfs_block_sillyrename(dentry); res = nfs_revalidate_mapping(inode, filp->f_mapping); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2f8e618..4cb17df 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -505,6 +505,15 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) struct inode *inode = dentry->d_inode; int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; int err; + struct dentry *p; + struct inode *pi; + + rcu_read_lock(); + p = dentry->d_parent; + pi = rcu_dereference(p)->d_inode; + if (pi && !test_bit(NFS_INO_SEEN_GETATTR, &NFS_I(pi)->flags)) + set_bit(NFS_INO_SEEN_GETATTR, &NFS_I(pi)->flags); + rcu_read_unlock(); /* Flush out writes to the server in order to update c/mtime. */ if (S_ISREG(inode->i_mode)) { diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 6023efa..2a04ed5 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -219,6 +219,10 @@ struct nfs_inode { #define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */ #define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */ #define NFS_INO_COMMIT (7) /* inode is committing unstable writes */ +#define NFS_INO_SEEN_GETATTR (8) /* flag to track if app is calling + * getattr in a directory during + * readdir + */ static inline struct nfs_inode *NFS_I(const struct inode *inode) {