static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_sequenceargs *args) { __be32 *p; int i; __be32 status; status = decode_sessionid(xdr, &args->csa_sessionid); if (status) goto out; status = htonl(NFS4ERR_RESOURCE); p = read_buf(xdr, 5 * sizeof(uint32_t)); if (unlikely(p == NULL)) goto out; args->csa_addr = svc_addr(rqstp); args->csa_sequenceid = ntohl(*p++); args->csa_slotid = ntohl(*p++); args->csa_highestslotid = ntohl(*p++); args->csa_cachethis = ntohl(*p++); args->csa_nrclists = ntohl(*p++); args->csa_rclists = NULL; if (args->csa_nrclists) { args->csa_rclists = kmalloc(args->csa_nrclists * sizeof(*args->csa_rclists), GFP_KERNEL); if (unlikely(args->csa_rclists == NULL)) goto out; for (i = 0; i < args->csa_nrclists; i++) { status = decode_rc_list(xdr, &args->csa_rclists[i]); if (status) goto out_free; } } status = 0; dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u slotid %u " "highestslotid %u cachethis %d nrclists %u\n", __func__, ((u32 *)&args->csa_sessionid)[0], ((u32 *)&args->csa_sessionid)[1], ((u32 *)&args->csa_sessionid)[2], ((u32 *)&args->csa_sessionid)[3], args->csa_sequenceid, args->csa_slotid, args->csa_highestslotid, args->csa_cachethis, args->csa_nrclists); out: dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; out_free: for (i = 0; i < args->csa_nrclists; i++) kfree(args->csa_rclists[i].rcl_refcalls); kfree(args->csa_rclists); goto out; }
static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, void *argp) { struct cb_sequenceargs *args = argp; __be32 *p; int i; __be32 status; status = decode_sessionid(xdr, &args->csa_sessionid); if (status) return status; p = read_buf(xdr, 5 * sizeof(uint32_t)); if (unlikely(p == NULL)) return htonl(NFS4ERR_RESOURCE); args->csa_addr = svc_addr(rqstp); args->csa_sequenceid = ntohl(*p++); args->csa_slotid = ntohl(*p++); args->csa_highestslotid = ntohl(*p++); args->csa_cachethis = ntohl(*p++); args->csa_nrclists = ntohl(*p++); args->csa_rclists = NULL; if (args->csa_nrclists) { args->csa_rclists = kmalloc_array(args->csa_nrclists, sizeof(*args->csa_rclists), GFP_KERNEL); if (unlikely(args->csa_rclists == NULL)) return htonl(NFS4ERR_RESOURCE); for (i = 0; i < args->csa_nrclists; i++) { status = decode_rc_list(xdr, &args->csa_rclists[i]); if (status) { args->csa_nrclists = i; goto out_free; } } } return 0; out_free: for (i = 0; i < args->csa_nrclists; i++) kfree(args->csa_rclists[i].rcl_refcalls); kfree(args->csa_rclists); return status; }
static __be32 decode_rc_list(struct xdr_stream *xdr, struct referring_call_list *rc_list) { __be32 *p; int i; __be32 status; status = decode_sessionid(xdr, &rc_list->rcl_sessionid); if (status) goto out; status = htonl(NFS4ERR_RESOURCE); p = read_buf(xdr, sizeof(uint32_t)); if (unlikely(p == NULL)) goto out; rc_list->rcl_nrefcalls = ntohl(*p++); if (rc_list->rcl_nrefcalls) { p = read_buf(xdr, rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); if (unlikely(p == NULL)) goto out; rc_list->rcl_refcalls = kmalloc(rc_list->rcl_nrefcalls * sizeof(*rc_list->rcl_refcalls), GFP_KERNEL); if (unlikely(rc_list->rcl_refcalls == NULL)) goto out; for (i = 0; i < rc_list->rcl_nrefcalls; i++) { rc_list->rcl_refcalls[i].rc_sequenceid = ntohl(*p++); rc_list->rcl_refcalls[i].rc_slotid = ntohl(*p++); } } status = 0; out: return status; }