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; count += PAGE_SIZE;
} }
resp->count = count >> 2; resp->count = count >> 2;
if (resp->offset) { nfs3svc_encode_cookie3(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;
}
return rpc_success; return rpc_success;
} }
@ -560,17 +550,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
count += PAGE_SIZE; count += PAGE_SIZE;
} }
resp->count = count >> 2; resp->count = count >> 2;
if (resp->offset) { nfs3svc_encode_cookie3(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;
}
out: out:
return rpc_success; return rpc_success;

View file

@ -1219,6 +1219,28 @@ static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,
return 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 * Encode a directory entry. This one works for both normal readdir
* and readdirplus. * 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 elen; /* estimated entry length in words */
int num_entry_words = 0; /* actual number of words */ int num_entry_words = 0; /* actual number of words */
if (cd->offset) { nfs3svc_encode_cookie3(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;
}
/* /*
dprintk("encode_entry(%.*s @%ld%s)\n", 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_fhandle(struct svc_rqst *);
void nfs3svc_release_fhandle2(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 nfs3svc_encode_entry(void *, const char *name,
int namlen, loff_t offset, u64 ino, int namlen, loff_t offset, u64 ino,
unsigned int); unsigned int);