• NeilBrown's avatar
    NFS: report more appropriate block size for directories. · 7ef5ca4f
    NeilBrown authored
    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: default avatarNeilBrown <neilb@suse.de>
    Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
    7ef5ca4f
inode.c 56.4 KB