]> git.baikalelectronics.ru Git - kernel.git/commit
NFS: report more appropriate block size for directories.
authorNeilBrown <neilb@suse.de>
Fri, 8 May 2015 03:10:40 +0000 (13:10 +1000)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 2 Jun 2015 12:55:27 +0000 (08:55 -0400)
commitfb7f200f258361eb39380b2f1edb4bd984af97ce
treee6c6d1c377d0d379a85b2467122001b5e8c6e50b
parentcd789f978c22e47b62b91c4b0e74fc1ebddd2799
NFS: report more appropriate block size for directories.

In glibc 2.21 (and several previous), a call to opendir() will
result in a 32K (BUFSIZ*4) buffer being allocated and passed to
getdents.

However a call to fdopendir() results in an 'fstat' request to
determine block size and a matching buffer allocated for subsequent
use with getdents.  This will typically be 1M.

The first getdents call on an NFS directory will always use
READDIR_PLUS (or NFSv4 equivalent) if available.  Subsequent getdents
calls only use this more expensive version if some 'stat' requests are
made between the getdents calls.

For this reason it is good to keep at least that first getdents call
relatively short.  When fdopendir() and readdir() is used on a large
directory, it takes approximately 32 times as long to complete as
using "opendir".  Current versions of 'find' use fdopendir() and
demonstrate this slowness.

'stat' on a directory currently returns the 'wsize'.  This number has
no meaning on directories.
Actual READDIR requests are limited to ->dtsize, which itself is
capped at 4 pages, coincidently the same as BUFSIZ*4.
So this is a meaningful number to use as the blocksize on directories,
and has the effect of making 'find' on large directories go a lot
faster.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/inode.c