NFSD: Clean up nfsd4_encode_copy_notify()
Replace open-coded encoding logic with the use of conventional XDR utility functions. Note that if we replace the cpn_sec and cpn_nsec fields with a single struct timespec64 field, the encoder can use nfsd4_encode_nfstime4(), as that is the data type specified by the XDR spec. NFS4ERR_INVAL seems inappropriate if the encoder doesn't support encoding the response. Instead use NFS4ERR_SERVERFAULT, since this condition is a software bug on the server. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
02e0297f16
commit
21d316a767
@ -1939,8 +1939,8 @@ nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cn->cpn_sec = nn->nfsd4_lease;
|
||||
cn->cpn_nsec = 0;
|
||||
cn->cpn_lease_time.tv_sec = nn->nfsd4_lease;
|
||||
cn->cpn_lease_time.tv_nsec = 0;
|
||||
|
||||
status = nfserrno(-ENOMEM);
|
||||
cps = nfs4_alloc_init_cpntf_state(nn, stid);
|
||||
|
@ -2575,6 +2575,19 @@ nfsd4_encode_change_info4(struct xdr_stream *xdr, const struct nfsd4_change_info
|
||||
return nfsd4_encode_changeid4(xdr, c->after_change);
|
||||
}
|
||||
|
||||
static __be32 nfsd4_encode_netaddr4(struct xdr_stream *xdr,
|
||||
const struct nfs42_netaddr *addr)
|
||||
{
|
||||
__be32 status;
|
||||
|
||||
/* na_r_netid */
|
||||
status = nfsd4_encode_opaque(xdr, addr->netid, addr->netid_len);
|
||||
if (status != nfs_ok)
|
||||
return status;
|
||||
/* na_r_addr */
|
||||
return nfsd4_encode_opaque(xdr, addr->addr, addr->addr_len);
|
||||
}
|
||||
|
||||
/* Encode as an array of strings the string given with components
|
||||
* separated @sep, escaped with esc_enter and esc_exit.
|
||||
*/
|
||||
@ -5132,43 +5145,42 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
|
||||
nfsd4_encode_netloc4(struct xdr_stream *xdr, const struct nl4_server *ns)
|
||||
{
|
||||
struct xdr_stream *xdr = resp->xdr;
|
||||
struct nfs42_netaddr *addr;
|
||||
__be32 *p;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
*p++ = cpu_to_be32(ns->nl4_type);
|
||||
__be32 status;
|
||||
|
||||
if (xdr_stream_encode_u32(xdr, ns->nl4_type) != XDR_UNIT)
|
||||
return nfserr_resource;
|
||||
switch (ns->nl4_type) {
|
||||
case NL4_NETADDR:
|
||||
addr = &ns->u.nl4_addr;
|
||||
|
||||
/* netid_len, netid, uaddr_len, uaddr (port included
|
||||
* in RPCBIND_MAXUADDRLEN)
|
||||
*/
|
||||
p = xdr_reserve_space(xdr,
|
||||
4 /* netid len */ +
|
||||
(XDR_QUADLEN(addr->netid_len) * 4) +
|
||||
4 /* uaddr len */ +
|
||||
(XDR_QUADLEN(addr->addr_len) * 4));
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
||||
*p++ = cpu_to_be32(addr->netid_len);
|
||||
p = xdr_encode_opaque_fixed(p, addr->netid,
|
||||
addr->netid_len);
|
||||
*p++ = cpu_to_be32(addr->addr_len);
|
||||
p = xdr_encode_opaque_fixed(p, addr->addr,
|
||||
addr->addr_len);
|
||||
/* nl_addr */
|
||||
status = nfsd4_encode_netaddr4(xdr, &ns->u.nl4_addr);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
|
||||
return nfserr_inval;
|
||||
status = nfserr_serverfault;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static __be32
|
||||
nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
union nfsd4_op_u *u)
|
||||
{
|
||||
struct nfsd4_copy_notify *cn = &u->copy_notify;
|
||||
struct xdr_stream *xdr = resp->xdr;
|
||||
|
||||
/* cnr_lease_time */
|
||||
nfserr = nfsd4_encode_nfstime4(xdr, &cn->cpn_lease_time);
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
/* cnr_stateid */
|
||||
nfserr = nfsd4_encode_stateid4(xdr, &cn->cpn_cnr_stateid);
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
/* cnr_source_server<> */
|
||||
if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
|
||||
return nfserr_resource;
|
||||
return nfsd4_encode_netloc4(xdr, cn->cpn_src);
|
||||
}
|
||||
|
||||
static __be32
|
||||
@ -5261,42 +5273,6 @@ out:
|
||||
return nfserr;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
union nfsd4_op_u *u)
|
||||
{
|
||||
struct nfsd4_copy_notify *cn = &u->copy_notify;
|
||||
struct xdr_stream *xdr = resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
/* 8 sec, 4 nsec */
|
||||
p = xdr_reserve_space(xdr, 12);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
||||
/* cnr_lease_time */
|
||||
p = xdr_encode_hyper(p, cn->cpn_sec);
|
||||
*p++ = cpu_to_be32(cn->cpn_nsec);
|
||||
|
||||
/* cnr_stateid */
|
||||
nfserr = nfsd4_encode_stateid4(xdr, &cn->cpn_cnr_stateid);
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
/* cnr_src.nl_nsvr */
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
||||
*p++ = cpu_to_be32(1);
|
||||
|
||||
nfserr = nfsd42_encode_nl4_server(resp, cn->cpn_src);
|
||||
return nfserr;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
union nfsd4_op_u *u)
|
||||
|
@ -745,8 +745,7 @@ struct nfsd4_copy_notify {
|
||||
|
||||
/* response */
|
||||
stateid_t cpn_cnr_stateid;
|
||||
u64 cpn_sec;
|
||||
u32 cpn_nsec;
|
||||
struct timespec64 cpn_lease_time;
|
||||
struct nl4_server *cpn_src;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user