/* * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. * (Note: buffer memory is freed in rpc_task_release). */ static void call_allocate(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; unsigned int bufsiz; dprintk("RPC: %4d call_allocate (status %d)\n", task->tk_pid, task->tk_status); task->tk_action = call_encode; if (task->tk_buffer) return; /* FIXME: compute buffer requirements more exactly using * auth->au_wslack */ bufsiz = rpcproc_bufsiz(clnt, task->tk_msg.rpc_proc) + RPC_SLACK_SPACE; if ((task->tk_buffer = rpc_malloc(task, bufsiz << 1)) != NULL) return; printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) { xprt_release(task); task->tk_action = call_reserve; rpc_delay(task, HZ>>4); return; }
/* * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. * (Note: buffer memory is freed in rpc_task_release). */ static void call_allocate(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; unsigned int bufsiz; dprintk("RPC: %4d call_allocate (status %d)\n", task->tk_pid, task->tk_status); task->tk_action = call_encode; if (task->tk_buffer) return; /* FIXME: compute buffer requirements more exactly using * auth->au_wslack */ bufsiz = rpcproc_bufsiz(clnt, task->tk_proc) + RPC_SLACK_SPACE; if ((task->tk_buffer = rpc_malloc(task, bufsiz)) != NULL) return; printk("RPC: buffer allocation failed for task %p\n", task); if (!signalled()) { xprt_release(task); task->tk_action = call_reserve; rpc_delay(task, HZ); return; } rpc_exit(task, -ERESTARTSYS); }
/* * 3. Encode arguments of an RPC call */ static void call_encode(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; unsigned int bufsiz; kxdrproc_t encode; int status; u32 *p; dprintk("RPC: %4d call_encode (status %d)\n", task->tk_pid, task->tk_status); task->tk_action = call_transmit; /* Default buffer setup */ bufsiz = rpcproc_bufsiz(clnt, task->tk_proc)+RPC_SLACK_SPACE; req->rq_svec[0].iov_base = task->tk_buffer; req->rq_svec[0].iov_len = bufsiz; req->rq_slen = 0; req->rq_snr = 1; req->rq_rvec[0].iov_base = task->tk_buffer; req->rq_rvec[0].iov_len = bufsiz; req->rq_rlen = bufsiz; req->rq_rnr = 1; if (task->tk_proc > clnt->cl_maxproc) { printk(KERN_WARNING "%s (vers %d): bad procedure number %d\n", clnt->cl_protname, clnt->cl_vers, task->tk_proc); rpc_exit(task, -EIO); return; } /* Zero buffer so we have automatic zero-padding of opaque & string */ memset(task->tk_buffer, 0, bufsiz); /* Encode header and provided arguments */ encode = rpcproc_encode(clnt, task->tk_proc); if (!(p = call_header(task))) { printk("RPC: call_header failed, exit EIO\n"); rpc_exit(task, -EIO); } else if ((status = encode(req, p, task->tk_argp)) < 0) { printk(KERN_WARNING "%s: can't encode arguments: %d\n", clnt->cl_protname, -status); rpc_exit(task, status); } }