From 316dc9666f2406985235a3b71ec19523a6d0c947 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Thu, 28 Jan 2010 12:53:16 -0800 Subject: [PATCH] Add inode prefetching support in NFS readdirplus. --- nfs3/nfs3.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 1b7e594..42ac46c 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -937,12 +937,32 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) uint64_t fh_bytes[MAX_READDIR_DIRENTS]; int count = 0; - /* TODO: Handle dircount, maxcount arguments from client. */ - + GSequenceIter *i; BlueSkyDirent start = {NULL, NULL, argp->cookie, 0}; - GSequenceIter *i = g_sequence_search(dir->dirents, &start, - bluesky_dirent_compare, NULL); + /* Perform a prefetch pass on inodes: for all the inodes we think we will + * return information about, try to load each one but don't wait. This + * should let multiple inodes be fetched in parallel, instead of + * sequentially in the loop that follows. */ + i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL); + while (count < MAX_READDIR_DIRENTS + && !g_sequence_iter_is_end(i) + && dircount <= argp->dircount + && dircount + attrcount <= argp->maxcount) + { + BlueSkyDirent *d = g_sequence_get(i); + BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); + if (inode != NULL) + bluesky_inode_unref(inode); + dircount += 24 + ((strlen(d->name) + 3) & ~3); + attrcount += 88 + 8 + 8; + i = g_sequence_iter_next(i); + } + + i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL); + count = 0; + dircount = 88 + 16; + attrcount = 0; while (count < MAX_READDIR_DIRENTS && !g_sequence_iter_is_end(i)) { BlueSkyDirent *d = g_sequence_get(i); BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); -- 2.20.1