From: Michael Vrable Date: Thu, 7 Jan 2010 00:05:25 +0000 (-0800) Subject: Improve NFS readdirplus to estimate response sizes. X-Git-Url: http://git.vrable.net/?p=bluesky.git;a=commitdiff_plain;h=53162a864578bcfbc2c35cbc59b9395d7108a2fe Improve NFS readdirplus to estimate response sizes. It should now give a response closer to, but not larger than, the requested size. --- diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 4b1b8c5..70273ff 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -747,7 +747,7 @@ nfsproc3_link_3_svc(link3args *argp, struct svc_req *rqstp) gint bluesky_dirent_compare(gconstpointer a, gconstpointer b, gpointer unused); -#define MAX_READDIR_DIRENTS 4 +#define MAX_READDIR_DIRENTS 64 readdir3res * nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp) { @@ -797,6 +797,13 @@ nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp) readdirplus3res * nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp) { + /* XDR-encoded sizes: + * post_op_attr: 88 bytes + * base readdirplus3resok: 88 + 16 bytes + * base directory entry: 24 bytes + filename + * attributes/fh3: 88 + 8 + filehandle size + */ + size_t dircount = 88 + 16, attrcount = 0; static readdirplus3res result; BlueSkyInode *dir = lookup_fh(&argp->dir); @@ -826,6 +833,11 @@ nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp) BlueSkyDirent *d = g_sequence_get(i); BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); if (inode != NULL) { + dircount += 24 + ((strlen(d->name) + 3) & ~3); + attrcount += 88 + 8 + 8; + if (dircount > argp->dircount + || dircount + attrcount > argp->maxcount) + break; dirents[count].fileid = d->inum; dirents[count].name = d->name; dirents[count].cookie = d->cookie;