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: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever 2020-11-10 09:57:14 -05:00
parent 5ef2826c76
commit a161e6c76a
3 changed files with 27 additions and 35 deletions

View File

@ -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;

View File

@ -1219,6 +1219,28 @@ out:
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",

View File

@ -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);