|
@@ -1746,11 +1746,6 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#define RESERVE_SPACE(nbytes) do { \
|
|
|
- p = xdr_reserve_space(&resp->xdr, nbytes); \
|
|
|
- BUG_ON(!p); \
|
|
|
-} while (0)
|
|
|
-
|
|
|
/* Encode as an array of strings the string given with components
|
|
|
* separated @sep, escaped with esc_enter and esc_exit.
|
|
|
*/
|
|
@@ -2737,23 +2732,29 @@ fail:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
|
|
|
+static __be32
|
|
|
+nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
|
|
|
{
|
|
|
__be32 *p;
|
|
|
|
|
|
- RESERVE_SPACE(sizeof(stateid_t));
|
|
|
+ p = xdr_reserve_space(xdr, sizeof(stateid_t));
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(sid->si_generation);
|
|
|
WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static __be32
|
|
|
nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(8);
|
|
|
+ p = xdr_reserve_space(xdr, 8);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(access->ac_supported);
|
|
|
WRITE32(access->ac_resp_access);
|
|
|
}
|
|
@@ -2762,10 +2763,13 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|
|
|
|
|
static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
|
|
|
+ p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
|
|
|
WRITE32(bcts->dir);
|
|
|
/* Sorry, we do not yet support RDMA over 4.1: */
|
|
@@ -2777,8 +2781,10 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
|
|
|
static __be32
|
|
|
nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (!nfserr)
|
|
|
- nfsd4_encode_stateid(resp, &close->cl_stateid);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid);
|
|
|
|
|
|
return nfserr;
|
|
|
}
|
|
@@ -2787,10 +2793,13 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
|
|
|
static __be32
|
|
|
nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(NFS4_VERIFIER_SIZE);
|
|
|
+ p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE);
|
|
|
}
|
|
|
return nfserr;
|
|
@@ -2799,10 +2808,13 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|
|
static __be32
|
|
|
nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(32);
|
|
|
+ p = xdr_reserve_space(xdr, 32);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
write_cinfo(&p, &create->cr_cinfo);
|
|
|
WRITE32(2);
|
|
|
WRITE32(create->cr_bmval[0]);
|
|
@@ -2829,13 +2841,16 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
|
|
|
static __be32
|
|
|
nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
struct svc_fh *fhp = *fhpp;
|
|
|
unsigned int len;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
len = fhp->fh_handle.fh_size;
|
|
|
- RESERVE_SPACE(len + 4);
|
|
|
+ p = xdr_reserve_space(xdr, len + 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(len);
|
|
|
WRITEMEM(&fhp->fh_handle.fh_base, len);
|
|
|
}
|
|
@@ -2846,13 +2861,15 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
|
|
|
* Including all fields other than the name, a LOCK4denied structure requires
|
|
|
* 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
|
|
|
*/
|
|
|
-static void
|
|
|
-nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
|
|
|
+static __be32
|
|
|
+nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
|
|
|
{
|
|
|
struct xdr_netobj *conf = &ld->ld_owner;
|
|
|
__be32 *p;
|
|
|
|
|
|
- RESERVE_SPACE(32 + XDR_LEN(conf->len));
|
|
|
+ p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE64(ld->ld_start);
|
|
|
WRITE64(ld->ld_length);
|
|
|
WRITE32(ld->ld_type);
|
|
@@ -2865,15 +2882,18 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
|
|
|
WRITE64((u64)0); /* clientid */
|
|
|
WRITE32(0); /* length of owner name */
|
|
|
}
|
|
|
+ return nfserr_denied;
|
|
|
}
|
|
|
|
|
|
static __be32
|
|
|
nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (!nfserr)
|
|
|
- nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
|
|
|
else if (nfserr == nfserr_denied)
|
|
|
- nfsd4_encode_lock_denied(resp, &lock->lk_denied);
|
|
|
+ nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
|
|
|
|
|
|
return nfserr;
|
|
|
}
|
|
@@ -2881,16 +2901,20 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
|
|
|
static __be32
|
|
|
nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (nfserr == nfserr_denied)
|
|
|
- nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
|
|
|
+ nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
|
|
|
return nfserr;
|
|
|
}
|
|
|
|
|
|
static __be32
|
|
|
nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (!nfserr)
|
|
|
- nfsd4_encode_stateid(resp, &locku->lu_stateid);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid);
|
|
|
|
|
|
return nfserr;
|
|
|
}
|
|
@@ -2899,10 +2923,13 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
|
|
|
static __be32
|
|
|
nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(20);
|
|
|
+ p = xdr_reserve_space(xdr, 20);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
write_cinfo(&p, &link->li_cinfo);
|
|
|
}
|
|
|
return nfserr;
|
|
@@ -2912,13 +2939,18 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
|
|
|
static __be32
|
|
|
nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (nfserr)
|
|
|
goto out;
|
|
|
|
|
|
- nfsd4_encode_stateid(resp, &open->op_stateid);
|
|
|
- RESERVE_SPACE(40);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
|
|
|
+ if (nfserr)
|
|
|
+ goto out;
|
|
|
+ p = xdr_reserve_space(xdr, 40);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
write_cinfo(&p, &open->op_cinfo);
|
|
|
WRITE32(open->op_rflags);
|
|
|
WRITE32(2);
|
|
@@ -2930,8 +2962,12 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|
|
case NFS4_OPEN_DELEGATE_NONE:
|
|
|
break;
|
|
|
case NFS4_OPEN_DELEGATE_READ:
|
|
|
- nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
|
|
|
- RESERVE_SPACE(20);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
|
|
|
+ if (nfserr)
|
|
|
+ return nfserr;
|
|
|
+ p = xdr_reserve_space(xdr, 20);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(open->op_recall);
|
|
|
|
|
|
/*
|
|
@@ -2943,8 +2979,12 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|
|
WRITE32(0); /* XXX: is NULL principal ok? */
|
|
|
break;
|
|
|
case NFS4_OPEN_DELEGATE_WRITE:
|
|
|
- nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
|
|
|
- RESERVE_SPACE(32);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
|
|
|
+ if (nfserr)
|
|
|
+ return nfserr;
|
|
|
+ p = xdr_reserve_space(xdr, 32);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0);
|
|
|
|
|
|
/*
|
|
@@ -2966,12 +3006,16 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|
|
switch (open->op_why_no_deleg) {
|
|
|
case WND4_CONTENTION:
|
|
|
case WND4_RESOURCE:
|
|
|
- RESERVE_SPACE(8);
|
|
|
+ p = xdr_reserve_space(xdr, 8);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(open->op_why_no_deleg);
|
|
|
WRITE32(0); /* deleg signaling not supported yet */
|
|
|
break;
|
|
|
default:
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(open->op_why_no_deleg);
|
|
|
}
|
|
|
break;
|
|
@@ -2986,8 +3030,10 @@ out:
|
|
|
static __be32
|
|
|
nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (!nfserr)
|
|
|
- nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
|
|
|
|
|
|
return nfserr;
|
|
|
}
|
|
@@ -2995,8 +3041,10 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
|
|
|
static __be32
|
|
|
nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
if (!nfserr)
|
|
|
- nfsd4_encode_stateid(resp, &od->od_stateid);
|
|
|
+ nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid);
|
|
|
|
|
|
return nfserr;
|
|
|
}
|
|
@@ -3019,7 +3067,9 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
if (resp->xdr.buf->page_len)
|
|
|
return nfserr_resource;
|
|
|
|
|
|
- RESERVE_SPACE(8); /* eof flag and byte count */
|
|
|
+ p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
maxcount = svc_max_payload(resp->rqstp);
|
|
|
if (maxcount > read->rd_length)
|
|
@@ -3071,7 +3121,9 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
resp->xdr.buf->tail[0].iov_base = p;
|
|
|
resp->xdr.buf->tail[0].iov_len = 0;
|
|
|
if (maxcount&3) {
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0);
|
|
|
resp->xdr.buf->tail[0].iov_base += maxcount&3;
|
|
|
resp->xdr.buf->tail[0].iov_len = 4 - (maxcount&3);
|
|
@@ -3099,7 +3151,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
|
|
|
page = page_address(*(resp->rqstp->rq_next_page++));
|
|
|
|
|
|
maxcount = PAGE_SIZE;
|
|
|
- RESERVE_SPACE(4);
|
|
|
+
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
/*
|
|
|
* XXX: By default, the ->readlink() VFS op will truncate symlinks
|
|
@@ -3126,7 +3181,9 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
|
|
|
resp->xdr.buf->tail[0].iov_base = p;
|
|
|
resp->xdr.buf->tail[0].iov_len = 0;
|
|
|
if (maxcount&3) {
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0);
|
|
|
resp->xdr.buf->tail[0].iov_base += maxcount&3;
|
|
|
resp->xdr.buf->tail[0].iov_len = 4 - (maxcount&3);
|
|
@@ -3151,7 +3208,9 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
|
|
|
if (!*resp->rqstp->rq_next_page)
|
|
|
return nfserr_resource;
|
|
|
|
|
|
- RESERVE_SPACE(NFS4_VERIFIER_SIZE);
|
|
|
+ p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
|
|
|
WRITE32(0);
|
|
@@ -3220,10 +3279,13 @@ err_no_verf:
|
|
|
static __be32
|
|
|
nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(20);
|
|
|
+ p = xdr_reserve_space(xdr, 20);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
write_cinfo(&p, &remove->rm_cinfo);
|
|
|
}
|
|
|
return nfserr;
|
|
@@ -3232,10 +3294,13 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|
|
static __be32
|
|
|
nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(40);
|
|
|
+ p = xdr_reserve_space(xdr, 40);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
write_cinfo(&p, &rename->rn_sinfo);
|
|
|
write_cinfo(&p, &rename->rn_tinfo);
|
|
|
}
|
|
@@ -3243,7 +3308,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|
|
}
|
|
|
|
|
|
static __be32
|
|
|
-nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
+nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|
|
__be32 nfserr, struct svc_export *exp)
|
|
|
{
|
|
|
u32 i, nflavs, supported;
|
|
@@ -3254,6 +3319,7 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
|
|
|
if (nfserr)
|
|
|
goto out;
|
|
|
+ nfserr = nfserr_resource;
|
|
|
if (exp->ex_nflavors) {
|
|
|
flavs = exp->ex_flavors;
|
|
|
nflavs = exp->ex_nflavors;
|
|
@@ -3275,7 +3341,9 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
}
|
|
|
|
|
|
supported = 0;
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ goto out;
|
|
|
flavorsp = p++; /* to be backfilled later */
|
|
|
|
|
|
for (i = 0; i < nflavs; i++) {
|
|
@@ -3284,7 +3352,10 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
|
|
|
if (rpcauth_get_gssinfo(pf, &info) == 0) {
|
|
|
supported++;
|
|
|
- RESERVE_SPACE(4 + 4 + XDR_LEN(info.oid.len) + 4 + 4);
|
|
|
+ p = xdr_reserve_space(xdr, 4 + 4 +
|
|
|
+ XDR_LEN(info.oid.len) + 4 + 4);
|
|
|
+ if (!p)
|
|
|
+ goto out;
|
|
|
WRITE32(RPC_AUTH_GSS);
|
|
|
WRITE32(info.oid.len);
|
|
|
WRITEMEM(info.oid.data, info.oid.len);
|
|
@@ -3292,7 +3363,9 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
WRITE32(info.service);
|
|
|
} else if (pf < RPC_AUTH_MAXFLAVOR) {
|
|
|
supported++;
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ goto out;
|
|
|
WRITE32(pf);
|
|
|
} else {
|
|
|
if (report)
|
|
@@ -3304,7 +3377,7 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
|
|
|
if (nflavs != supported)
|
|
|
report = false;
|
|
|
*flavorsp = htonl(supported);
|
|
|
-
|
|
|
+ nfserr = 0;
|
|
|
out:
|
|
|
if (exp)
|
|
|
exp_put(exp);
|
|
@@ -3315,14 +3388,18 @@ static __be32
|
|
|
nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_secinfo *secinfo)
|
|
|
{
|
|
|
- return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
+ return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp);
|
|
|
}
|
|
|
|
|
|
static __be32
|
|
|
nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_secinfo_no_name *secinfo)
|
|
|
{
|
|
|
- return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
+
|
|
|
+ return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -3332,9 +3409,12 @@ nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
static __be32
|
|
|
nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
- RESERVE_SPACE(16);
|
|
|
+ p = xdr_reserve_space(xdr, 16);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
if (nfserr) {
|
|
|
WRITE32(3);
|
|
|
WRITE32(0);
|
|
@@ -3353,15 +3433,20 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
|
|
|
static __be32
|
|
|
nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE);
|
|
|
+ p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITEMEM(&scd->se_clientid, 8);
|
|
|
WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE);
|
|
|
}
|
|
|
else if (nfserr == nfserr_clid_inuse) {
|
|
|
- RESERVE_SPACE(8);
|
|
|
+ p = xdr_reserve_space(xdr, 8);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0);
|
|
|
WRITE32(0);
|
|
|
}
|
|
@@ -3371,10 +3456,13 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
|
|
|
static __be32
|
|
|
nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (!nfserr) {
|
|
|
- RESERVE_SPACE(16);
|
|
|
+ p = xdr_reserve_space(xdr, 16);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(write->wr_bytes_written);
|
|
|
WRITE32(write->wr_how_written);
|
|
|
WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE);
|
|
@@ -3394,6 +3482,7 @@ static __be32
|
|
|
nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_exchange_id *exid)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
char *major_id;
|
|
|
char *server_scope;
|
|
@@ -3409,11 +3498,13 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
server_scope = utsname()->nodename;
|
|
|
server_scope_sz = strlen(server_scope);
|
|
|
|
|
|
- RESERVE_SPACE(
|
|
|
+ p = xdr_reserve_space(xdr,
|
|
|
8 /* eir_clientid */ +
|
|
|
4 /* eir_sequenceid */ +
|
|
|
4 /* eir_flags */ +
|
|
|
4 /* spr_how */);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
WRITEMEM(&exid->clientid, 8);
|
|
|
WRITE32(exid->seqid);
|
|
@@ -3426,7 +3517,9 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
break;
|
|
|
case SP4_MACH_CRED:
|
|
|
/* spo_must_enforce, spo_must_allow */
|
|
|
- RESERVE_SPACE(16);
|
|
|
+ p = xdr_reserve_space(xdr, 16);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
/* spo_must_enforce bitmap: */
|
|
|
WRITE32(2);
|
|
@@ -3440,13 +3533,15 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
WARN_ON_ONCE(1);
|
|
|
}
|
|
|
|
|
|
- RESERVE_SPACE(
|
|
|
+ p = xdr_reserve_space(xdr,
|
|
|
8 /* so_minor_id */ +
|
|
|
4 /* so_major_id.len */ +
|
|
|
(XDR_QUADLEN(major_id_sz) * 4) +
|
|
|
4 /* eir_server_scope.len */ +
|
|
|
(XDR_QUADLEN(server_scope_sz) * 4) +
|
|
|
4 /* eir_server_impl_id.count (0) */);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
|
|
|
/* The server_owner struct */
|
|
|
WRITE64(minor_id); /* Minor id */
|
|
@@ -3467,17 +3562,22 @@ static __be32
|
|
|
nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_create_session *sess)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (nfserr)
|
|
|
return nfserr;
|
|
|
|
|
|
- RESERVE_SPACE(24);
|
|
|
+ p = xdr_reserve_space(xdr, 24);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
|
|
|
WRITE32(sess->seqid);
|
|
|
WRITE32(sess->flags);
|
|
|
|
|
|
- RESERVE_SPACE(28);
|
|
|
+ p = xdr_reserve_space(xdr, 28);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0); /* headerpadsz */
|
|
|
WRITE32(sess->fore_channel.maxreq_sz);
|
|
|
WRITE32(sess->fore_channel.maxresp_sz);
|
|
@@ -3487,11 +3587,15 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
WRITE32(sess->fore_channel.nr_rdma_attrs);
|
|
|
|
|
|
if (sess->fore_channel.nr_rdma_attrs) {
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(sess->fore_channel.rdma_attrs);
|
|
|
}
|
|
|
|
|
|
- RESERVE_SPACE(28);
|
|
|
+ p = xdr_reserve_space(xdr, 28);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(0); /* headerpadsz */
|
|
|
WRITE32(sess->back_channel.maxreq_sz);
|
|
|
WRITE32(sess->back_channel.maxresp_sz);
|
|
@@ -3501,7 +3605,9 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
WRITE32(sess->back_channel.nr_rdma_attrs);
|
|
|
|
|
|
if (sess->back_channel.nr_rdma_attrs) {
|
|
|
- RESERVE_SPACE(4);
|
|
|
+ p = xdr_reserve_space(xdr, 4);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITE32(sess->back_channel.rdma_attrs);
|
|
|
}
|
|
|
return 0;
|
|
@@ -3511,12 +3617,15 @@ static __be32
|
|
|
nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_sequence *seq)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (nfserr)
|
|
|
return nfserr;
|
|
|
|
|
|
- RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
|
|
|
+ p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
|
|
|
WRITE32(seq->seqid);
|
|
|
WRITE32(seq->slotid);
|
|
@@ -3533,13 +3642,16 @@ static __be32
|
|
|
nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|
|
struct nfsd4_test_stateid *test_stateid)
|
|
|
{
|
|
|
+ struct xdr_stream *xdr = &resp->xdr;
|
|
|
struct nfsd4_test_stateid_id *stateid, *next;
|
|
|
__be32 *p;
|
|
|
|
|
|
if (nfserr)
|
|
|
return nfserr;
|
|
|
|
|
|
- RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
|
|
|
+ p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
|
|
|
+ if (!p)
|
|
|
+ return nfserr_resource;
|
|
|
*p++ = htonl(test_stateid->ts_num_ids);
|
|
|
|
|
|
list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
|
|
@@ -3678,7 +3790,11 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
|
|
nfsd4_enc encoder;
|
|
|
__be32 *p;
|
|
|
|
|
|
- RESERVE_SPACE(8);
|
|
|
+ p = xdr_reserve_space(xdr, 8);
|
|
|
+ if (!p) {
|
|
|
+ WARN_ON_ONCE(1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
WRITE32(op->opnum);
|
|
|
post_err_offset = xdr->buf->len;
|
|
|
|
|
@@ -3730,18 +3846,21 @@ status:
|
|
|
* called with nfs4_lock_state() held
|
|
|
*/
|
|
|
void
|
|
|
-nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
|
|
+nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
|
|
|
{
|
|
|
__be32 *p;
|
|
|
struct nfs4_replay *rp = op->replay;
|
|
|
|
|
|
BUG_ON(!rp);
|
|
|
|
|
|
- RESERVE_SPACE(8);
|
|
|
+ p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
|
|
|
+ if (!p) {
|
|
|
+ WARN_ON_ONCE(1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
WRITE32(op->opnum);
|
|
|
*p++ = rp->rp_status; /* already xdr'ed */
|
|
|
|
|
|
- RESERVE_SPACE(rp->rp_buflen);
|
|
|
WRITEMEM(rp->rp_buf, rp->rp_buflen);
|
|
|
}
|
|
|
|