mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: jirislaby@gmail.com
Cc: linux-kernel@vger.kernel.org, NeilBrown <neilb@suse.de>,
	Jiri Slaby <jslaby@suse.cz>,
	Trond Myklebust <Trond.Myklebust@netapp.com>,
	linux-nfs@vger.kernel.org
Subject: [PATCH 09/15] Make selection of 'readdir-plus' adapt to usage patterns.
Date: Tue,  7 May 2013 16:18:17 +0200	[thread overview]
Message-ID: <1367936303-13386-9-git-send-email-jslaby@suse.cz> (raw)
In-Reply-To: <1367936303-13386-1-git-send-email-jslaby@suse.cz>

From: NeilBrown <neilb@suse.de>

While the use of READDIRPLUS is significantly more efficient than
READDIR followed by many GETATTR calls, it is still less efficient
than just READDIR if the attributes are not required.

We can get a hint as to whether the application requires attr information
by looking at whether any ->getattr calls are made between
->readdir calls.
If there are any, then getting the attributes seems to be worth while.

This patch tracks whether there have been recent getattr calls on
children of a directory and uses that information to selectively
disable READDIRPLUS on that directory.

The first 'readdir' call is always served using READDIRPLUS.
Subsequent calls only use READDIRPLUS if there was a getattr on a child
in the mean time.

The locking of ->d_parent access needs to be reviewed.
As the bit is simply a hint, it isn't critical that it is set
on the "correct" parent if a rename is happening, but it is
critical that the 'set' doesn't set a bit in something that
isn't even an inode any more.

Acked-by: NeilBrown <neilb@suse.de>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: linux-nfs@vger.kernel.org
---
 fs/nfs/dir.c           | 3 +++
 fs/nfs/inode.c         | 9 +++++++++
 include/linux/nfs_fs.h | 4 ++++
 3 files changed, 16 insertions(+)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e093e73..f5b367c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -826,6 +826,9 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 	desc->dir_cookie = &dir_ctx->dir_cookie;
 	desc->decode = NFS_PROTO(inode)->decode_dirent;
 	desc->plus = nfs_use_readdirplus(inode, filp) ? 1 : 0;
+	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 c1c7a9d..c15071d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -520,6 +520,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 fc01d5c..633e2a9 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -220,6 +220,10 @@ struct nfs_inode {
 #define NFS_INO_COMMIT		(7)		/* inode is committing unstable writes */
 #define NFS_INO_LAYOUTCOMMIT	(9)		/* layoutcommit required */
 #define NFS_INO_LAYOUTCOMMITTING (10)		/* layoutcommit inflight */
+#define NFS_INO_SEEN_GETATTR	(11)		/* flag to track if app is calling
+						 * getattr in a directory during
+						 * readdir
+						 */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {
-- 
1.8.2.1


  parent reply	other threads:[~2013-05-07 14:19 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-07 14:18 [PATCH 01/15] Char: lp, protect LPGETSTATUS with port_mutex Jiri Slaby
2013-05-07 14:18 ` [PATCH 02/15] mISDN: Add support for group membership check Jiri Slaby
2013-05-07 14:18 ` [PATCH 03/15] ehea: add alias entry for portN properties Jiri Slaby
2013-05-07 14:18 ` [PATCH 04/15] drm/cirrus: Correct register values for 16bpp Jiri Slaby
2013-05-07 14:18 ` [PATCH 05/15] connection tracking helper for SLP Jiri Slaby
2013-05-08  2:03   ` Pablo Neira Ayuso
2013-05-07 14:18 ` [PATCH 06/15] netfilter: Implement RFC 1123 for FTP conntrack Jiri Slaby
2013-05-07 14:18 ` [PATCH 07/15] hfs: avoid crash in hfs_bnode_create Jiri Slaby
2013-05-07 19:05   ` Vyacheslav Dubeyko
2013-05-08 15:26     ` [PATCH v2 07/14] " Jiri Slaby
2013-05-07 14:18 ` [PATCH 08/15] reiserfs: fix deadlock with nfs racing on create/lookup Jiri Slaby
2013-05-07 14:18 ` Jiri Slaby [this message]
2013-05-07 14:27   ` [PATCH 09/15] Make selection of 'readdir-plus' adapt to usage patterns Myklebust, Trond
2013-05-07 14:32     ` Jiri Slaby
2013-05-07 14:18 ` [PATCH 10/15] acpi: ec_sys: access user space with get_user()/put_user() Jiri Slaby
2013-05-07 14:18 ` [PATCH 11/15] nouveau: Make vga_switcheroo code depend on VGA_SWITCHEROO Jiri Slaby
2013-05-07 14:18 ` [PATCH 12/15] geodefb: Depend on X86_32 Jiri Slaby
2013-05-07 14:18 ` [PATCH 13/15] chipidea: Allow user to select PCI/IMX options Jiri Slaby
2013-05-08  9:07   ` Alexander Shishkin
2013-05-15 15:59     ` Jiri Slaby
2013-05-16  9:36       ` Alexander Shishkin
2013-05-22  8:51         ` Jiri Slaby
2013-05-22 11:10           ` Alexander Shishkin
2013-05-07 14:18 ` [PATCH 14/15] staging/sb105x: remove asm/segment.h dependency Jiri Slaby
2013-05-07 14:18 ` [PATCH 15/15] ptp: PTP_1588_CLOCK_PCH depends on x86 Jiri Slaby
2013-05-07 19:29   ` Richard Cochran
2013-05-14 14:20     ` Jiri Slaby
2013-05-14 18:12       ` Ben Hutchings
2013-05-20 22:31         ` Keller, Jacob E
2013-05-07 14:48 ` [PATCH 01/15] Char: lp, protect LPGETSTATUS with port_mutex Arnd Bergmann
2013-05-07 15:41   ` Jiri Slaby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1367936303-13386-9-git-send-email-jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=Trond.Myklebust@netapp.com \
    --cc=jirislaby@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®