NFSD: Update the NFSv2 GETACL result encoder to use struct xdr_stream

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever 2020-11-18 14:38:47 -05:00
parent 8edc064888
commit f8cba47344
3 changed files with 42 additions and 29 deletions

View File

@ -242,51 +242,41 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
/* GETACL */ /* GETACL */
static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p) static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
{ {
struct xdr_stream *xdr = &rqstp->rq_res_stream;
struct nfsd3_getaclres *resp = rqstp->rq_resp; struct nfsd3_getaclres *resp = rqstp->rq_resp;
struct dentry *dentry = resp->fh.fh_dentry; struct dentry *dentry = resp->fh.fh_dentry;
struct inode *inode; struct inode *inode;
struct kvec *head = rqstp->rq_res.head;
unsigned int base;
int n;
int w; int w;
*p++ = resp->status; if (!svcxdr_encode_stat(xdr, resp->status))
if (resp->status != nfs_ok)
return xdr_ressize_check(rqstp, p);
/*
* Since this is version 2, the check for nfserr in
* nfsd_dispatch actually ensures the following cannot happen.
* However, it seems fragile to depend on that.
*/
if (dentry == NULL || d_really_is_negative(dentry))
return 0; return 0;
if (dentry == NULL || d_really_is_negative(dentry))
return 1;
inode = d_inode(dentry); inode = d_inode(dentry);
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat); if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
*p++ = htonl(resp->mask); return 0;
if (!xdr_ressize_check(rqstp, p)) if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
return 0; return 0;
base = (char *)p - (char *)head->iov_base;
rqstp->rq_res.page_len = w = nfsacl_size( rqstp->rq_res.page_len = w = nfsacl_size(
(resp->mask & NFS_ACL) ? resp->acl_access : NULL, (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
(resp->mask & NFS_DFACL) ? resp->acl_default : NULL); (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
while (w > 0) { while (w > 0) {
if (!*(rqstp->rq_next_page++)) if (!*(rqstp->rq_next_page++))
return 0; return 1;
w -= PAGE_SIZE; w -= PAGE_SIZE;
} }
n = nfsacl_encode(&rqstp->rq_res, base, inode, if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
resp->acl_access, resp->mask & NFS_ACL, 0))
resp->mask & NFS_ACL, 0); return 0;
if (n > 0) if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
n = nfsacl_encode(&rqstp->rq_res, base + n, inode, resp->mask & NFS_DFACL, NFS_ACL_DEFAULT))
resp->acl_default, return 0;
resp->mask & NFS_DFACL,
NFS_ACL_DEFAULT); return 1;
return (n > 0);
} }
static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p) static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p)

View File

@ -26,7 +26,16 @@ static const u32 nfs_ftypes[] = {
* Basic NFSv2 data types (RFC 1094 Section 2.3) * Basic NFSv2 data types (RFC 1094 Section 2.3)
*/ */
static bool /**
* svcxdr_encode_stat - Encode an NFSv2 status code
* @xdr: XDR stream
* @status: status value to encode
*
* Return values:
* %false: Send buffer space was exhausted
* %true: Success
*/
bool
svcxdr_encode_stat(struct xdr_stream *xdr, __be32 status) svcxdr_encode_stat(struct xdr_stream *xdr, __be32 status)
{ {
__be32 *p; __be32 *p;
@ -250,7 +259,18 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
return p; return p;
} }
static bool /**
* svcxdr_encode_fattr - Encode NFSv2 file attributes
* @rqstp: Context of a completed RPC transaction
* @xdr: XDR stream
* @fhp: File handle to encode
* @stat: Attributes to encode
*
* Return values:
* %false: Send buffer space was exhausted
* %true: Success
*/
bool
svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr, svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
const struct svc_fh *fhp, const struct kstat *stat) const struct svc_fh *fhp, const struct kstat *stat)
{ {

View File

@ -170,5 +170,8 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);
/* Helper functions for NFSv2 ACL code */ /* Helper functions for NFSv2 ACL code */
__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat); __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat);
bool svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp); bool svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp);
bool svcxdr_encode_stat(struct xdr_stream *xdr, __be32 status);
bool svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
const struct svc_fh *fhp, const struct kstat *stat);
#endif /* LINUX_NFSD_H */ #endif /* LINUX_NFSD_H */