summaryrefslogtreecommitdiff
path: root/fs/nfs/internal.h
diff options
context:
space:
mode:
authorluanshi <zhangliguang@linux.alibaba.com>2019-01-29 10:34:17 +0300
committerTrond Myklebust <trond.myklebust@hammerspace.com>2019-02-21 01:33:55 +0300
commitbe4c2d4723a4a637f0d1b4f7c66447141a4b3564 (patch)
tree8b78cfcd65a43420fd5172e4d5f3793a583d3ee3 /fs/nfs/internal.h
parent40cc394be1aa18848b8757e03bd8ed23281f572e (diff)
downloadlinux-be4c2d4723a4a637f0d1b4f7c66447141a4b3564.tar.xz
NFS: readdirplus optimization by cache mechanism
When listing very large directories via NFS, clients may take a long time to complete. There are about three factors involved: First of all, ls and practically every other method of listing a directory including python os.listdir and find rely on libc readdir(). However readdir() only reads 32K of directory entries at a time, which means that if you have a lot of files in the same directory, it is going to take an insanely long time to read all the directory entries. Secondly, libc readdir() reads 32K of directory entries at a time, in kernel space 32K buffer split into 8 pages. One NFS readdirplus rpc will be called for one page, which introduces many readdirplus rpc calls. Lastly, one NFS readdirplus rpc asks for 32K data (filled by nfs_dentry) to fill one page (filled by dentry), we found that nearly one third of data was wasted. To solve above problems, pagecache mechanism was introduced. One NFS readdirplus rpc will ask for a large data (more than 32k), the data can fill more than one page, the cached pages can be used for next readdir call. This can reduce many readdirplus rpc calls and improve readdirplus performance. TESTING: When listing very large directories(include 300 thousand files) via NFS time ls -l /nfs_mount | wc -l without the patch: 300001 real 1m53.524s user 0m2.314s sys 0m2.599s with the patch: 300001 real 0m23.487s user 0m2.305s sys 0m2.558s Improved performance: 79.6% readdirplus rpc calls decrease: 85% Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/internal.h')
-rw-r--r--fs/nfs/internal.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index b26622d9686f..c7cf23ae6597 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -69,7 +69,8 @@ struct nfs_clone_mount {
* Maximum number of pages that readdir can use for creating
* a vmapped array of pages.
*/
-#define NFS_MAX_READDIR_PAGES 8
+#define NFS_MAX_READDIR_PAGES 64
+#define NFS_MAX_READDIR_RAPAGES 8
struct nfs_client_initdata {
unsigned long init_flags;