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

NFSD: Add a helper that encodes NFSv3 directory offset cookies



Refactor: De-duplicate identical code that handles encoding of
directory offset cookies across page boundaries.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 5ef2826c
Loading
Loading
Loading
Loading
+2 −22
Original line number Diff line number Diff line
@@ -495,17 +495,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
		count += PAGE_SIZE;
	}
	resp->count = count >> 2;
	if (resp->offset) {
		if (unlikely(resp->offset1)) {
			/* we ended up with offset on a page boundary */
			*resp->offset = htonl(offset >> 32);
			*resp->offset1 = htonl(offset & 0xffffffff);
			resp->offset1 = NULL;
		} else {
			xdr_encode_hyper(resp->offset, offset);
		}
		resp->offset = NULL;
	}
	nfs3svc_encode_cookie3(resp, offset);

	return rpc_success;
}
@@ -560,17 +550,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
		count += PAGE_SIZE;
	}
	resp->count = count >> 2;
	if (resp->offset) {
		if (unlikely(resp->offset1)) {
			/* we ended up with offset on a page boundary */
			*resp->offset = htonl(offset >> 32);
			*resp->offset1 = htonl(offset & 0xffffffff);
			resp->offset1 = NULL;
		} else {
			xdr_encode_hyper(resp->offset, offset);
		}
		resp->offset = NULL;
	}
	nfs3svc_encode_cookie3(resp, offset);

out:
	return rpc_success;
+23 −13
Original line number Diff line number Diff line
@@ -1219,6 +1219,28 @@ static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,
	return p;
}

/**
 * nfs3svc_encode_cookie3 - Encode a directory offset cookie
 * @resp: readdir result context
 * @offset: offset cookie to encode
 *
 */
void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset)
{
	if (!resp->offset)
		return;

	if (resp->offset1) {
		/* we ended up with offset on a page boundary */
		*resp->offset = cpu_to_be32(offset >> 32);
		*resp->offset1 = cpu_to_be32(offset & 0xffffffff);
		resp->offset1 = NULL;
	} else {
		xdr_encode_hyper(resp->offset, offset);
	}
	resp->offset = NULL;
}

/*
 * Encode a directory entry. This one works for both normal readdir
 * and readdirplus.
@@ -1244,19 +1266,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
	int		elen;		/* estimated entry length in words */
	int		num_entry_words = 0;	/* actual number of words */

	if (cd->offset) {
		u64 offset64 = offset;

		if (unlikely(cd->offset1)) {
			/* we ended up with offset on a page boundary */
			*cd->offset = htonl(offset64 >> 32);
			*cd->offset1 = htonl(offset64 & 0xffffffff);
			cd->offset1 = NULL;
		} else {
			xdr_encode_hyper(cd->offset, offset64);
		}
		cd->offset = NULL;
	}
	nfs3svc_encode_cookie3(cd, offset);

	/*
	dprintk("encode_entry(%.*s @%ld%s)\n",
+2 −0
Original line number Diff line number Diff line
@@ -300,6 +300,8 @@ int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *);

void nfs3svc_release_fhandle(struct svc_rqst *);
void nfs3svc_release_fhandle2(struct svc_rqst *);

void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset);
int nfs3svc_encode_entry(void *, const char *name,
				int namlen, loff_t offset, u64 ino,
				unsigned int);