Commit a1409e2d authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Count bytes instead of pages in the NFSv3 READDIR encoder



Clean up: Counting the bytes used by each returned directory entry
seems less brittle to me than trying to measure consumed pages after
the fact.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent a161e6c7
Loading
Loading
Loading
Loading
+2 −29
Original line number Diff line number Diff line
@@ -462,10 +462,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
{
	struct nfsd3_readdirargs *argp = rqstp->rq_argp;
	struct nfsd3_readdirres  *resp = rqstp->rq_resp;
	int		count = 0;
	loff_t		offset;
	struct page	**p;
	caddr_t		page_addr = NULL;

	dprintk("nfsd: READDIR(3)  %s %d bytes at %d\n",
				SVCFH_fmt(&argp->fh),
@@ -476,6 +473,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
	/* Read directory and encode entries on the fly */
	fh_copy(&resp->fh, &argp->fh);

	resp->count = 0;
	resp->common.err = nfs_ok;
	resp->rqstp = rqstp;
	offset = argp->cookie;
@@ -483,18 +481,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
	resp->status = nfsd_readdir(rqstp, &resp->fh, &offset,
				    &resp->common, nfs3svc_encode_entry);
	memcpy(resp->verf, argp->verf, 8);
	count = 0;
	for (p = rqstp->rq_respages + 1; p < rqstp->rq_next_page; p++) {
		page_addr = page_address(*p);

		if (((caddr_t)resp->buffer >= page_addr) &&
		    ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) {
			count += (caddr_t)resp->buffer - page_addr;
			break;
		}
		count += PAGE_SIZE;
	}
	resp->count = count >> 2;
	nfs3svc_encode_cookie3(resp, offset);

	return rpc_success;
@@ -509,10 +495,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
{
	struct nfsd3_readdirargs *argp = rqstp->rq_argp;
	struct nfsd3_readdirres  *resp = rqstp->rq_resp;
	int	count = 0;
	loff_t	offset;
	struct page **p;
	caddr_t	page_addr = NULL;

	dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n",
				SVCFH_fmt(&argp->fh),
@@ -523,6 +506,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
	/* Read directory and encode entries on the fly */
	fh_copy(&resp->fh, &argp->fh);

	resp->count = 0;
	resp->common.err = nfs_ok;
	resp->rqstp = rqstp;
	offset = argp->cookie;
@@ -539,17 +523,6 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
	resp->status = nfsd_readdir(rqstp, &resp->fh, &offset,
				    &resp->common, nfs3svc_encode_entry_plus);
	memcpy(resp->verf, argp->verf, 8);
	for (p = rqstp->rq_respages + 1; p < rqstp->rq_next_page; p++) {
		page_addr = page_address(*p);

		if (((caddr_t)resp->buffer >= page_addr) &&
		    ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) {
			count += (caddr_t)resp->buffer - page_addr;
			break;
		}
		count += PAGE_SIZE;
	}
	resp->count = count >> 2;
	nfs3svc_encode_cookie3(resp, offset);

out:
+1 −0
Original line number Diff line number Diff line
@@ -1364,6 +1364,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
		return -EINVAL;
	}

	cd->count += num_entry_words;
	cd->buflen -= num_entry_words;
	cd->buffer = p;
	cd->common.err = nfs_ok;