Merge branch 'devel' into next
Conflicts: fs/nfs/file.c Fix up the conflict with Jon Corbet's bkl-removal tree
This commit is contained in:
@@ -63,22 +63,11 @@ static const struct rpc_credops gss_nullops;
|
||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||
#endif
|
||||
|
||||
#define NFS_NGROUPS 16
|
||||
|
||||
#define GSS_CRED_SLACK 1024 /* XXX: unused */
|
||||
#define GSS_CRED_SLACK 1024
|
||||
/* length of a krb5 verifier (48), plus data added before arguments when
|
||||
* using integrity (two 4-byte integers): */
|
||||
#define GSS_VERF_SLACK 100
|
||||
|
||||
/* XXX this define must match the gssd define
|
||||
* as it is passed to gssd to signal the use of
|
||||
* machine creds should be part of the shared rpc interface */
|
||||
|
||||
#define CA_RUN_AS_MACHINE 0x00000200
|
||||
|
||||
/* dump the buffer in `emacs-hexl' style */
|
||||
#define isprint(c) ((c > 0x1f) && (c < 0x7f))
|
||||
|
||||
struct gss_auth {
|
||||
struct kref kref;
|
||||
struct rpc_auth rpc_auth;
|
||||
@@ -146,7 +135,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
|
||||
q = (const void *)((const char *)p + len);
|
||||
if (unlikely(q > end || q < p))
|
||||
return ERR_PTR(-EFAULT);
|
||||
dest->data = kmemdup(p, len, GFP_KERNEL);
|
||||
dest->data = kmemdup(p, len, GFP_NOFS);
|
||||
if (unlikely(dest->data == NULL))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
dest->len = len;
|
||||
@@ -171,7 +160,7 @@ gss_alloc_context(void)
|
||||
{
|
||||
struct gss_cl_ctx *ctx;
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_NOFS);
|
||||
if (ctx != NULL) {
|
||||
ctx->gc_proc = RPC_GSS_PROC_DATA;
|
||||
ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */
|
||||
@@ -272,7 +261,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to add a upcall to the pipefs queue.
|
||||
/* Try to add an upcall to the pipefs queue.
|
||||
* If an upcall owned by our uid already exists, then we return a reference
|
||||
* to that upcall instead of adding the new upcall.
|
||||
*/
|
||||
@@ -341,7 +330,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
|
||||
{
|
||||
struct gss_upcall_msg *gss_msg;
|
||||
|
||||
gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL);
|
||||
gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
|
||||
if (gss_msg != NULL) {
|
||||
INIT_LIST_HEAD(&gss_msg->list);
|
||||
rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
|
||||
@@ -493,7 +482,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
||||
{
|
||||
const void *p, *end;
|
||||
void *buf;
|
||||
struct rpc_clnt *clnt;
|
||||
struct gss_upcall_msg *gss_msg;
|
||||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
struct gss_cl_ctx *ctx;
|
||||
@@ -503,11 +491,10 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
||||
if (mlen > MSG_BUF_MAXSIZE)
|
||||
goto out;
|
||||
err = -ENOMEM;
|
||||
buf = kmalloc(mlen, GFP_KERNEL);
|
||||
buf = kmalloc(mlen, GFP_NOFS);
|
||||
if (!buf)
|
||||
goto out;
|
||||
|
||||
clnt = RPC_I(inode)->private;
|
||||
err = -EFAULT;
|
||||
if (copy_from_user(buf, src, mlen))
|
||||
goto err;
|
||||
@@ -806,7 +793,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
|
||||
dprintk("RPC: gss_create_cred for uid %d, flavor %d\n",
|
||||
acred->uid, auth->au_flavor);
|
||||
|
||||
if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL)))
|
||||
if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
|
||||
goto out_err;
|
||||
|
||||
rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
|
||||
|
@@ -70,7 +70,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
|
||||
q = (const void *)((const char *)p + len);
|
||||
if (unlikely(q > end || q < p))
|
||||
return ERR_PTR(-EFAULT);
|
||||
res->data = kmemdup(p, len, GFP_KERNEL);
|
||||
res->data = kmemdup(p, len, GFP_NOFS);
|
||||
if (unlikely(res->data == NULL))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
res->len = len;
|
||||
@@ -131,7 +131,7 @@ gss_import_sec_context_kerberos(const void *p,
|
||||
struct krb5_ctx *ctx;
|
||||
int tmp;
|
||||
|
||||
if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
|
||||
if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS)))
|
||||
goto out_err;
|
||||
|
||||
p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
|
||||
|
@@ -76,7 +76,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
|
||||
q = (const void *)((const char *)p + len);
|
||||
if (unlikely(q > end || q < p))
|
||||
return ERR_PTR(-EFAULT);
|
||||
res->data = kmemdup(p, len, GFP_KERNEL);
|
||||
res->data = kmemdup(p, len, GFP_NOFS);
|
||||
if (unlikely(res->data == NULL))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return q;
|
||||
@@ -90,7 +90,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
|
||||
struct spkm3_ctx *ctx;
|
||||
int version;
|
||||
|
||||
if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
|
||||
if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS)))
|
||||
goto out_err;
|
||||
|
||||
p = simple_get_bytes(p, end, &version, sizeof(version));
|
||||
|
@@ -90,7 +90,7 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits)
|
||||
int
|
||||
decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen)
|
||||
{
|
||||
if (!(out->data = kzalloc(explen,GFP_KERNEL)))
|
||||
if (!(out->data = kzalloc(explen,GFP_NOFS)))
|
||||
return 0;
|
||||
out->len = explen;
|
||||
memcpy(out->data, in, enclen);
|
||||
|
@@ -66,7 +66,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
|
||||
dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
|
||||
acred->uid, acred->gid);
|
||||
|
||||
if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
|
||||
if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS)))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp_lock.h>
|
||||
@@ -58,7 +59,6 @@ static void call_start(struct rpc_task *task);
|
||||
static void call_reserve(struct rpc_task *task);
|
||||
static void call_reserveresult(struct rpc_task *task);
|
||||
static void call_allocate(struct rpc_task *task);
|
||||
static void call_encode(struct rpc_task *task);
|
||||
static void call_decode(struct rpc_task *task);
|
||||
static void call_bind(struct rpc_task *task);
|
||||
static void call_bind_status(struct rpc_task *task);
|
||||
@@ -70,9 +70,9 @@ static void call_refreshresult(struct rpc_task *task);
|
||||
static void call_timeout(struct rpc_task *task);
|
||||
static void call_connect(struct rpc_task *task);
|
||||
static void call_connect_status(struct rpc_task *task);
|
||||
static __be32 * call_header(struct rpc_task *task);
|
||||
static __be32 * call_verify(struct rpc_task *task);
|
||||
|
||||
static __be32 *rpc_encode_header(struct rpc_task *task);
|
||||
static __be32 *rpc_verify_header(struct rpc_task *task);
|
||||
static int rpc_ping(struct rpc_clnt *clnt, int flags);
|
||||
|
||||
static void rpc_register_client(struct rpc_clnt *clnt)
|
||||
@@ -324,6 +324,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
|
||||
clnt->cl_autobind = 1;
|
||||
if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
|
||||
clnt->cl_discrtry = 1;
|
||||
if (!(args->flags & RPC_CLNT_CREATE_QUIET))
|
||||
clnt->cl_chatty = 1;
|
||||
|
||||
return clnt;
|
||||
}
|
||||
@@ -690,6 +692,21 @@ rpc_restart_call(struct rpc_task *task)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_restart_call);
|
||||
|
||||
#ifdef RPC_DEBUG
|
||||
static const char *rpc_proc_name(const struct rpc_task *task)
|
||||
{
|
||||
const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
|
||||
|
||||
if (proc) {
|
||||
if (proc->p_name)
|
||||
return proc->p_name;
|
||||
else
|
||||
return "NULL";
|
||||
} else
|
||||
return "no proc";
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 0. Initial state
|
||||
*
|
||||
@@ -701,9 +718,9 @@ call_start(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_clnt *clnt = task->tk_client;
|
||||
|
||||
dprintk("RPC: %5u call_start %s%d proc %d (%s)\n", task->tk_pid,
|
||||
dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid,
|
||||
clnt->cl_protname, clnt->cl_vers,
|
||||
task->tk_msg.rpc_proc->p_proc,
|
||||
rpc_proc_name(task),
|
||||
(RPC_IS_ASYNC(task) ? "async" : "sync"));
|
||||
|
||||
/* Increment call count */
|
||||
@@ -861,7 +878,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
|
||||
* 3. Encode arguments of an RPC call
|
||||
*/
|
||||
static void
|
||||
call_encode(struct rpc_task *task)
|
||||
rpc_xdr_encode(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
kxdrproc_t encode;
|
||||
@@ -876,23 +893,19 @@ call_encode(struct rpc_task *task)
|
||||
(char *)req->rq_buffer + req->rq_callsize,
|
||||
req->rq_rcvsize);
|
||||
|
||||
/* Encode header and provided arguments */
|
||||
encode = task->tk_msg.rpc_proc->p_encode;
|
||||
if (!(p = call_header(task))) {
|
||||
printk(KERN_INFO "RPC: call_header failed, exit EIO\n");
|
||||
p = rpc_encode_header(task);
|
||||
if (p == NULL) {
|
||||
printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n");
|
||||
rpc_exit(task, -EIO);
|
||||
return;
|
||||
}
|
||||
|
||||
encode = task->tk_msg.rpc_proc->p_encode;
|
||||
if (encode == NULL)
|
||||
return;
|
||||
|
||||
task->tk_status = rpcauth_wrap_req(task, encode, req, p,
|
||||
task->tk_msg.rpc_argp);
|
||||
if (task->tk_status == -ENOMEM) {
|
||||
/* XXX: Is this sane? */
|
||||
rpc_delay(task, 3*HZ);
|
||||
task->tk_status = -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -929,11 +942,9 @@ call_bind_status(struct rpc_task *task)
|
||||
}
|
||||
|
||||
switch (task->tk_status) {
|
||||
case -EAGAIN:
|
||||
dprintk("RPC: %5u rpcbind waiting for another request "
|
||||
"to finish\n", task->tk_pid);
|
||||
/* avoid busy-waiting here -- could be a network outage. */
|
||||
rpc_delay(task, 5*HZ);
|
||||
case -ENOMEM:
|
||||
dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid);
|
||||
rpc_delay(task, HZ >> 2);
|
||||
goto retry_timeout;
|
||||
case -EACCES:
|
||||
dprintk("RPC: %5u remote rpcbind: RPC program/version "
|
||||
@@ -1046,10 +1057,16 @@ call_transmit(struct rpc_task *task)
|
||||
/* Encode here so that rpcsec_gss can use correct sequence number. */
|
||||
if (rpc_task_need_encode(task)) {
|
||||
BUG_ON(task->tk_rqstp->rq_bytes_sent != 0);
|
||||
call_encode(task);
|
||||
rpc_xdr_encode(task);
|
||||
/* Did the encode result in an error condition? */
|
||||
if (task->tk_status != 0)
|
||||
if (task->tk_status != 0) {
|
||||
/* Was the error nonfatal? */
|
||||
if (task->tk_status == -EAGAIN)
|
||||
rpc_delay(task, HZ >> 4);
|
||||
else
|
||||
rpc_exit(task, task->tk_status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
xprt_transmit(task);
|
||||
if (task->tk_status < 0)
|
||||
@@ -1132,7 +1149,8 @@ call_status(struct rpc_task *task)
|
||||
rpc_exit(task, status);
|
||||
break;
|
||||
default:
|
||||
printk("%s: RPC call returned error %d\n",
|
||||
if (clnt->cl_chatty)
|
||||
printk("%s: RPC call returned error %d\n",
|
||||
clnt->cl_protname, -status);
|
||||
rpc_exit(task, status);
|
||||
}
|
||||
@@ -1157,7 +1175,8 @@ call_timeout(struct rpc_task *task)
|
||||
task->tk_timeouts++;
|
||||
|
||||
if (RPC_IS_SOFT(task)) {
|
||||
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
|
||||
if (clnt->cl_chatty)
|
||||
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
|
||||
clnt->cl_protname, clnt->cl_server);
|
||||
rpc_exit(task, -EIO);
|
||||
return;
|
||||
@@ -1165,7 +1184,8 @@ call_timeout(struct rpc_task *task)
|
||||
|
||||
if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) {
|
||||
task->tk_flags |= RPC_CALL_MAJORSEEN;
|
||||
printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
|
||||
if (clnt->cl_chatty)
|
||||
printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
|
||||
clnt->cl_protname, clnt->cl_server);
|
||||
}
|
||||
rpc_force_rebind(clnt);
|
||||
@@ -1196,8 +1216,9 @@ call_decode(struct rpc_task *task)
|
||||
task->tk_pid, task->tk_status);
|
||||
|
||||
if (task->tk_flags & RPC_CALL_MAJORSEEN) {
|
||||
printk(KERN_NOTICE "%s: server %s OK\n",
|
||||
clnt->cl_protname, clnt->cl_server);
|
||||
if (clnt->cl_chatty)
|
||||
printk(KERN_NOTICE "%s: server %s OK\n",
|
||||
clnt->cl_protname, clnt->cl_server);
|
||||
task->tk_flags &= ~RPC_CALL_MAJORSEEN;
|
||||
}
|
||||
|
||||
@@ -1224,8 +1245,7 @@ call_decode(struct rpc_task *task)
|
||||
goto out_retry;
|
||||
}
|
||||
|
||||
/* Verify the RPC header */
|
||||
p = call_verify(task);
|
||||
p = rpc_verify_header(task);
|
||||
if (IS_ERR(p)) {
|
||||
if (p == ERR_PTR(-EAGAIN))
|
||||
goto out_retry;
|
||||
@@ -1243,7 +1263,7 @@ call_decode(struct rpc_task *task)
|
||||
return;
|
||||
out_retry:
|
||||
task->tk_status = 0;
|
||||
/* Note: call_verify() may have freed the RPC slot */
|
||||
/* Note: rpc_verify_header() may have freed the RPC slot */
|
||||
if (task->tk_rqstp == req) {
|
||||
req->rq_received = req->rq_rcv_buf.len = 0;
|
||||
if (task->tk_client->cl_discrtry)
|
||||
@@ -1290,11 +1310,8 @@ call_refreshresult(struct rpc_task *task)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call header serialization
|
||||
*/
|
||||
static __be32 *
|
||||
call_header(struct rpc_task *task)
|
||||
rpc_encode_header(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_clnt *clnt = task->tk_client;
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
@@ -1314,11 +1331,8 @@ call_header(struct rpc_task *task)
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reply header verification
|
||||
*/
|
||||
static __be32 *
|
||||
call_verify(struct rpc_task *task)
|
||||
rpc_verify_header(struct rpc_task *task)
|
||||
{
|
||||
struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
|
||||
int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
|
||||
@@ -1392,7 +1406,7 @@ call_verify(struct rpc_task *task)
|
||||
task->tk_action = call_bind;
|
||||
goto out_retry;
|
||||
case RPC_AUTH_TOOWEAK:
|
||||
printk(KERN_NOTICE "call_verify: server %s requires stronger "
|
||||
printk(KERN_NOTICE "RPC: server %s requires stronger "
|
||||
"authentication.\n", task->tk_client->cl_server);
|
||||
break;
|
||||
default:
|
||||
@@ -1431,10 +1445,10 @@ call_verify(struct rpc_task *task)
|
||||
error = -EPROTONOSUPPORT;
|
||||
goto out_err;
|
||||
case RPC_PROC_UNAVAIL:
|
||||
dprintk("RPC: %5u %s: proc %p unsupported by program %u, "
|
||||
dprintk("RPC: %5u %s: proc %s unsupported by program %u, "
|
||||
"version %u on server %s\n",
|
||||
task->tk_pid, __func__,
|
||||
task->tk_msg.rpc_proc,
|
||||
rpc_proc_name(task),
|
||||
task->tk_client->cl_prog,
|
||||
task->tk_client->cl_vers,
|
||||
task->tk_client->cl_server);
|
||||
@@ -1517,44 +1531,53 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
|
||||
EXPORT_SYMBOL_GPL(rpc_call_null);
|
||||
|
||||
#ifdef RPC_DEBUG
|
||||
static void rpc_show_header(void)
|
||||
{
|
||||
printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
|
||||
"-timeout ---ops--\n");
|
||||
}
|
||||
|
||||
static void rpc_show_task(const struct rpc_clnt *clnt,
|
||||
const struct rpc_task *task)
|
||||
{
|
||||
const char *rpc_waitq = "none";
|
||||
char *p, action[KSYM_SYMBOL_LEN];
|
||||
|
||||
if (RPC_IS_QUEUED(task))
|
||||
rpc_waitq = rpc_qname(task->tk_waitqueue);
|
||||
|
||||
/* map tk_action pointer to a function name; then trim off
|
||||
* the "+0x0 [sunrpc]" */
|
||||
sprint_symbol(action, (unsigned long)task->tk_action);
|
||||
p = strchr(action, '+');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
||||
printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n",
|
||||
task->tk_pid, task->tk_flags, task->tk_status,
|
||||
clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops,
|
||||
clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task),
|
||||
action, rpc_waitq);
|
||||
}
|
||||
|
||||
void rpc_show_tasks(void)
|
||||
{
|
||||
struct rpc_clnt *clnt;
|
||||
struct rpc_task *t;
|
||||
struct rpc_task *task;
|
||||
int header = 0;
|
||||
|
||||
spin_lock(&rpc_client_lock);
|
||||
if (list_empty(&all_clients))
|
||||
goto out;
|
||||
printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
|
||||
"-rpcwait -action- ---ops--\n");
|
||||
list_for_each_entry(clnt, &all_clients, cl_clients) {
|
||||
if (list_empty(&clnt->cl_tasks))
|
||||
continue;
|
||||
spin_lock(&clnt->cl_lock);
|
||||
list_for_each_entry(t, &clnt->cl_tasks, tk_task) {
|
||||
const char *rpc_waitq = "none";
|
||||
int proc;
|
||||
|
||||
if (t->tk_msg.rpc_proc)
|
||||
proc = t->tk_msg.rpc_proc->p_proc;
|
||||
else
|
||||
proc = -1;
|
||||
|
||||
if (RPC_IS_QUEUED(t))
|
||||
rpc_waitq = rpc_qname(t->tk_waitqueue);
|
||||
|
||||
printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
|
||||
t->tk_pid, proc,
|
||||
t->tk_flags, t->tk_status,
|
||||
t->tk_client,
|
||||
(t->tk_client ? t->tk_client->cl_prog : 0),
|
||||
t->tk_rqstp, t->tk_timeout,
|
||||
rpc_waitq,
|
||||
t->tk_action, t->tk_ops);
|
||||
list_for_each_entry(task, &clnt->cl_tasks, tk_task) {
|
||||
if (!header) {
|
||||
rpc_show_header();
|
||||
header++;
|
||||
}
|
||||
rpc_show_task(clnt, task);
|
||||
}
|
||||
spin_unlock(&clnt->cl_lock);
|
||||
}
|
||||
out:
|
||||
spin_unlock(&rpc_client_lock);
|
||||
}
|
||||
#endif
|
||||
|
@@ -32,6 +32,10 @@
|
||||
#define RPCBIND_PROGRAM (100000u)
|
||||
#define RPCBIND_PORT (111u)
|
||||
|
||||
#define RPCBVERS_2 (2u)
|
||||
#define RPCBVERS_3 (3u)
|
||||
#define RPCBVERS_4 (4u)
|
||||
|
||||
enum {
|
||||
RPCBPROC_NULL,
|
||||
RPCBPROC_SET,
|
||||
@@ -64,6 +68,7 @@ enum {
|
||||
#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
|
||||
|
||||
static void rpcb_getport_done(struct rpc_task *, void *);
|
||||
static void rpcb_map_release(void *data);
|
||||
static struct rpc_program rpcb_program;
|
||||
|
||||
struct rpcbind_args {
|
||||
@@ -76,27 +81,22 @@ struct rpcbind_args {
|
||||
const char * r_netid;
|
||||
const char * r_addr;
|
||||
const char * r_owner;
|
||||
|
||||
int r_status;
|
||||
};
|
||||
|
||||
static struct rpc_procinfo rpcb_procedures2[];
|
||||
static struct rpc_procinfo rpcb_procedures3[];
|
||||
static struct rpc_procinfo rpcb_procedures4[];
|
||||
|
||||
struct rpcb_info {
|
||||
int rpc_vers;
|
||||
u32 rpc_vers;
|
||||
struct rpc_procinfo * rpc_proc;
|
||||
};
|
||||
|
||||
static struct rpcb_info rpcb_next_version[];
|
||||
static struct rpcb_info rpcb_next_version6[];
|
||||
|
||||
static void rpcb_map_release(void *data)
|
||||
{
|
||||
struct rpcbind_args *map = data;
|
||||
|
||||
xprt_put(map->r_xprt);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops rpcb_getport_ops = {
|
||||
.rpc_call_done = rpcb_getport_done,
|
||||
.rpc_release = rpcb_map_release,
|
||||
@@ -108,9 +108,46 @@ static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
|
||||
rpc_wake_up_status(&xprt->binding, status);
|
||||
}
|
||||
|
||||
static void rpcb_map_release(void *data)
|
||||
{
|
||||
struct rpcbind_args *map = data;
|
||||
|
||||
rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
|
||||
xprt_put(map->r_xprt);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static const struct sockaddr_in rpcb_inaddr_loopback = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
||||
.sin_port = htons(RPCBIND_PORT),
|
||||
};
|
||||
|
||||
static const struct sockaddr_in6 rpcb_in6addr_loopback = {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_addr = IN6ADDR_LOOPBACK_INIT,
|
||||
.sin6_port = htons(RPCBIND_PORT),
|
||||
};
|
||||
|
||||
static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
|
||||
size_t addrlen, u32 version)
|
||||
{
|
||||
struct rpc_create_args args = {
|
||||
.protocol = XPRT_TRANSPORT_UDP,
|
||||
.address = addr,
|
||||
.addrsize = addrlen,
|
||||
.servername = "localhost",
|
||||
.program = &rpcb_program,
|
||||
.version = version,
|
||||
.authflavor = RPC_AUTH_UNIX,
|
||||
.flags = RPC_CLNT_CREATE_NOPING,
|
||||
};
|
||||
|
||||
return rpc_create(&args);
|
||||
}
|
||||
|
||||
static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
|
||||
size_t salen, int proto, u32 version,
|
||||
int privileged)
|
||||
size_t salen, int proto, u32 version)
|
||||
{
|
||||
struct rpc_create_args args = {
|
||||
.protocol = proto,
|
||||
@@ -120,7 +157,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
|
||||
.program = &rpcb_program,
|
||||
.version = version,
|
||||
.authflavor = RPC_AUTH_UNIX,
|
||||
.flags = RPC_CLNT_CREATE_NOPING,
|
||||
.flags = (RPC_CLNT_CREATE_NOPING |
|
||||
RPC_CLNT_CREATE_NONPRIVPORT),
|
||||
};
|
||||
|
||||
switch (srvaddr->sa_family) {
|
||||
@@ -134,29 +172,72 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!privileged)
|
||||
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
|
||||
return rpc_create(&args);
|
||||
}
|
||||
|
||||
static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
|
||||
u32 version, struct rpc_message *msg,
|
||||
int *result)
|
||||
{
|
||||
struct rpc_clnt *rpcb_clnt;
|
||||
int error = 0;
|
||||
|
||||
*result = 0;
|
||||
|
||||
rpcb_clnt = rpcb_create_local(addr, addrlen, version);
|
||||
if (!IS_ERR(rpcb_clnt)) {
|
||||
error = rpc_call_sync(rpcb_clnt, msg, 0);
|
||||
rpc_shutdown_client(rpcb_clnt);
|
||||
} else
|
||||
error = PTR_ERR(rpcb_clnt);
|
||||
|
||||
if (error < 0)
|
||||
printk(KERN_WARNING "RPC: failed to contact local rpcbind "
|
||||
"server (errno %d).\n", -error);
|
||||
dprintk("RPC: registration status %d/%d\n", error, *result);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcb_register - set or unset a port registration with the local rpcbind svc
|
||||
* @prog: RPC program number to bind
|
||||
* @vers: RPC version number to bind
|
||||
* @prot: transport protocol to use to make this request
|
||||
* @prot: transport protocol to register
|
||||
* @port: port value to register
|
||||
* @okay: result code
|
||||
* @okay: OUT: result code
|
||||
*
|
||||
* port == 0 means unregister, port != 0 means register.
|
||||
* RPC services invoke this function to advertise their contact
|
||||
* information via the system's rpcbind daemon. RPC services
|
||||
* invoke this function once for each [program, version, transport]
|
||||
* tuple they wish to advertise.
|
||||
*
|
||||
* This routine supports only rpcbind version 2.
|
||||
* Callers may also unregister RPC services that are no longer
|
||||
* available by setting the passed-in port to zero. This removes
|
||||
* all registered transports for [program, version] from the local
|
||||
* rpcbind database.
|
||||
*
|
||||
* Returns zero if the registration request was dispatched
|
||||
* successfully and a reply was received. The rpcbind daemon's
|
||||
* boolean result code is stored in *okay.
|
||||
*
|
||||
* Returns an errno value and sets *result to zero if there was
|
||||
* some problem that prevented the rpcbind request from being
|
||||
* dispatched, or if the rpcbind daemon did not respond within
|
||||
* the timeout.
|
||||
*
|
||||
* This function uses rpcbind protocol version 2 to contact the
|
||||
* local rpcbind daemon.
|
||||
*
|
||||
* Registration works over both AF_INET and AF_INET6, and services
|
||||
* registered via this function are advertised as available for any
|
||||
* address. If the local rpcbind daemon is listening on AF_INET6,
|
||||
* services registered via this function will be advertised on
|
||||
* IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
|
||||
* addresses).
|
||||
*/
|
||||
int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
|
||||
{
|
||||
struct sockaddr_in sin = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
||||
};
|
||||
struct rpcbind_args map = {
|
||||
.r_prog = prog,
|
||||
.r_vers = vers,
|
||||
@@ -164,32 +245,159 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
|
||||
.r_port = port,
|
||||
};
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &rpcb_procedures2[port ?
|
||||
RPCBPROC_SET : RPCBPROC_UNSET],
|
||||
.rpc_argp = &map,
|
||||
.rpc_resp = okay,
|
||||
};
|
||||
struct rpc_clnt *rpcb_clnt;
|
||||
int error = 0;
|
||||
|
||||
dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
|
||||
"rpcbind\n", (port ? "" : "un"),
|
||||
prog, vers, prot, port);
|
||||
|
||||
rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
|
||||
sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1);
|
||||
if (IS_ERR(rpcb_clnt))
|
||||
return PTR_ERR(rpcb_clnt);
|
||||
msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
|
||||
if (port)
|
||||
msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
|
||||
|
||||
error = rpc_call_sync(rpcb_clnt, &msg, 0);
|
||||
return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
|
||||
sizeof(rpcb_inaddr_loopback),
|
||||
RPCBVERS_2, &msg, okay);
|
||||
}
|
||||
|
||||
rpc_shutdown_client(rpcb_clnt);
|
||||
if (error < 0)
|
||||
printk(KERN_WARNING "RPC: failed to contact local rpcbind "
|
||||
"server (errno %d).\n", -error);
|
||||
dprintk("RPC: registration status %d/%d\n", error, *okay);
|
||||
/*
|
||||
* Fill in AF_INET family-specific arguments to register
|
||||
*/
|
||||
static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
|
||||
struct rpc_message *msg)
|
||||
{
|
||||
struct rpcbind_args *map = msg->rpc_argp;
|
||||
unsigned short port = ntohs(address_to_register->sin_port);
|
||||
char buf[32];
|
||||
|
||||
return error;
|
||||
/* Construct AF_INET universal address */
|
||||
snprintf(buf, sizeof(buf),
|
||||
NIPQUAD_FMT".%u.%u",
|
||||
NIPQUAD(address_to_register->sin_addr.s_addr),
|
||||
port >> 8, port & 0xff);
|
||||
map->r_addr = buf;
|
||||
|
||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||
"local rpcbind\n", (port ? "" : "un"),
|
||||
map->r_prog, map->r_vers,
|
||||
map->r_addr, map->r_netid);
|
||||
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
|
||||
if (port)
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
||||
|
||||
return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
|
||||
sizeof(rpcb_inaddr_loopback),
|
||||
RPCBVERS_4, msg, msg->rpc_resp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in AF_INET6 family-specific arguments to register
|
||||
*/
|
||||
static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
|
||||
struct rpc_message *msg)
|
||||
{
|
||||
struct rpcbind_args *map = msg->rpc_argp;
|
||||
unsigned short port = ntohs(address_to_register->sin6_port);
|
||||
char buf[64];
|
||||
|
||||
/* Construct AF_INET6 universal address */
|
||||
snprintf(buf, sizeof(buf),
|
||||
NIP6_FMT".%u.%u",
|
||||
NIP6(address_to_register->sin6_addr),
|
||||
port >> 8, port & 0xff);
|
||||
map->r_addr = buf;
|
||||
|
||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||
"local rpcbind\n", (port ? "" : "un"),
|
||||
map->r_prog, map->r_vers,
|
||||
map->r_addr, map->r_netid);
|
||||
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
|
||||
if (port)
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
||||
|
||||
return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
|
||||
sizeof(rpcb_in6addr_loopback),
|
||||
RPCBVERS_4, msg, msg->rpc_resp);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcb_v4_register - set or unset a port registration with the local rpcbind
|
||||
* @program: RPC program number of service to (un)register
|
||||
* @version: RPC version number of service to (un)register
|
||||
* @address: address family, IP address, and port to (un)register
|
||||
* @netid: netid of transport protocol to (un)register
|
||||
* @result: result code from rpcbind RPC call
|
||||
*
|
||||
* RPC services invoke this function to advertise their contact
|
||||
* information via the system's rpcbind daemon. RPC services
|
||||
* invoke this function once for each [program, version, address,
|
||||
* netid] tuple they wish to advertise.
|
||||
*
|
||||
* Callers may also unregister RPC services that are no longer
|
||||
* available by setting the port number in the passed-in address
|
||||
* to zero. Callers pass a netid of "" to unregister all
|
||||
* transport netids associated with [program, version, address].
|
||||
*
|
||||
* Returns zero if the registration request was dispatched
|
||||
* successfully and a reply was received. The rpcbind daemon's
|
||||
* result code is stored in *result.
|
||||
*
|
||||
* Returns an errno value and sets *result to zero if there was
|
||||
* some problem that prevented the rpcbind request from being
|
||||
* dispatched, or if the rpcbind daemon did not respond within
|
||||
* the timeout.
|
||||
*
|
||||
* This function uses rpcbind protocol version 4 to contact the
|
||||
* local rpcbind daemon. The local rpcbind daemon must support
|
||||
* version 4 of the rpcbind protocol in order for these functions
|
||||
* to register a service successfully.
|
||||
*
|
||||
* Supported netids include "udp" and "tcp" for UDP and TCP over
|
||||
* IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6,
|
||||
* respectively.
|
||||
*
|
||||
* The contents of @address determine the address family and the
|
||||
* port to be registered. The usual practice is to pass INADDR_ANY
|
||||
* as the raw address, but specifying a non-zero address is also
|
||||
* supported by this API if the caller wishes to advertise an RPC
|
||||
* service on a specific network interface.
|
||||
*
|
||||
* Note that passing in INADDR_ANY does not create the same service
|
||||
* registration as IN6ADDR_ANY. The former advertises an RPC
|
||||
* service on any IPv4 address, but not on IPv6. The latter
|
||||
* advertises the service on all IPv4 and IPv6 addresses.
|
||||
*/
|
||||
int rpcb_v4_register(const u32 program, const u32 version,
|
||||
const struct sockaddr *address, const char *netid,
|
||||
int *result)
|
||||
{
|
||||
struct rpcbind_args map = {
|
||||
.r_prog = program,
|
||||
.r_vers = version,
|
||||
.r_netid = netid,
|
||||
.r_owner = RPCB_OWNER_STRING,
|
||||
};
|
||||
struct rpc_message msg = {
|
||||
.rpc_argp = &map,
|
||||
.rpc_resp = result,
|
||||
};
|
||||
|
||||
*result = 0;
|
||||
|
||||
switch (address->sa_family) {
|
||||
case AF_INET:
|
||||
return rpcb_register_netid4((struct sockaddr_in *)address,
|
||||
&msg);
|
||||
case AF_INET6:
|
||||
return rpcb_register_netid6((struct sockaddr_in6 *)address,
|
||||
&msg);
|
||||
}
|
||||
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +435,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
|
||||
__func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
|
||||
|
||||
rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
|
||||
sizeof(*sin), prot, 2, 0);
|
||||
sizeof(*sin), prot, RPCBVERS_2);
|
||||
if (IS_ERR(rpcb_clnt))
|
||||
return PTR_ERR(rpcb_clnt);
|
||||
|
||||
@@ -289,17 +497,16 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
/* Autobind on cloned rpc clients is discouraged */
|
||||
BUG_ON(clnt->cl_parent != clnt);
|
||||
|
||||
/* Put self on the wait queue to ensure we get notified if
|
||||
* some other task is already attempting to bind the port */
|
||||
rpc_sleep_on(&xprt->binding, task, NULL);
|
||||
|
||||
if (xprt_test_and_set_binding(xprt)) {
|
||||
status = -EAGAIN; /* tell caller to check again */
|
||||
dprintk("RPC: %5u %s: waiting for another binder\n",
|
||||
task->tk_pid, __func__);
|
||||
goto bailout_nowake;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Put self on queue before sending rpcbind request, in case
|
||||
* rpcb_getport_done completes before we return from rpc_run_task */
|
||||
rpc_sleep_on(&xprt->binding, task, NULL);
|
||||
|
||||
/* Someone else may have bound if we slept */
|
||||
if (xprt_bound(xprt)) {
|
||||
status = 0;
|
||||
@@ -338,7 +545,7 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
task->tk_pid, __func__, bind_version);
|
||||
|
||||
rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
|
||||
bind_version, 0);
|
||||
bind_version);
|
||||
if (IS_ERR(rpcb_clnt)) {
|
||||
status = PTR_ERR(rpcb_clnt);
|
||||
dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
|
||||
@@ -361,15 +568,15 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
||||
map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
|
||||
map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
|
||||
map->r_status = -EIO;
|
||||
|
||||
child = rpcb_call_async(rpcb_clnt, map, proc);
|
||||
rpc_release_client(rpcb_clnt);
|
||||
if (IS_ERR(child)) {
|
||||
status = -EIO;
|
||||
/* rpcb_map_release() has freed the arguments */
|
||||
dprintk("RPC: %5u %s: rpc_run_task failed\n",
|
||||
task->tk_pid, __func__);
|
||||
goto bailout_nofree;
|
||||
return;
|
||||
}
|
||||
rpc_put_task(child);
|
||||
|
||||
@@ -378,7 +585,6 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
|
||||
bailout_nofree:
|
||||
rpcb_wake_rpcbind_waiters(xprt, status);
|
||||
bailout_nowake:
|
||||
task->tk_status = status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcb_getport_async);
|
||||
@@ -417,9 +623,13 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
|
||||
dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
|
||||
child->tk_pid, status, map->r_port);
|
||||
|
||||
rpcb_wake_rpcbind_waiters(xprt, status);
|
||||
map->r_status = status;
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR functions for rpcbind
|
||||
*/
|
||||
|
||||
static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
|
||||
struct rpcbind_args *rpcb)
|
||||
{
|
||||
@@ -438,7 +648,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
|
||||
unsigned short *portp)
|
||||
{
|
||||
*portp = (unsigned short) ntohl(*p++);
|
||||
dprintk("RPC: rpcb_decode_getport result %u\n",
|
||||
dprintk("RPC: rpcb_decode_getport result %u\n",
|
||||
*portp);
|
||||
return 0;
|
||||
}
|
||||
@@ -447,8 +657,8 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
|
||||
unsigned int *boolp)
|
||||
{
|
||||
*boolp = (unsigned int) ntohl(*p++);
|
||||
dprintk("RPC: rpcb_decode_set result %u\n",
|
||||
*boolp);
|
||||
dprintk("RPC: rpcb_decode_set: call %s\n",
|
||||
(*boolp ? "succeeded" : "failed"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -571,52 +781,60 @@ out_err:
|
||||
static struct rpc_procinfo rpcb_procedures2[] = {
|
||||
PROC(SET, mapping, set),
|
||||
PROC(UNSET, mapping, set),
|
||||
PROC(GETADDR, mapping, getport),
|
||||
PROC(GETPORT, mapping, getport),
|
||||
};
|
||||
|
||||
static struct rpc_procinfo rpcb_procedures3[] = {
|
||||
PROC(SET, mapping, set),
|
||||
PROC(UNSET, mapping, set),
|
||||
PROC(SET, getaddr, set),
|
||||
PROC(UNSET, getaddr, set),
|
||||
PROC(GETADDR, getaddr, getaddr),
|
||||
};
|
||||
|
||||
static struct rpc_procinfo rpcb_procedures4[] = {
|
||||
PROC(SET, mapping, set),
|
||||
PROC(UNSET, mapping, set),
|
||||
PROC(SET, getaddr, set),
|
||||
PROC(UNSET, getaddr, set),
|
||||
PROC(GETADDR, getaddr, getaddr),
|
||||
PROC(GETVERSADDR, getaddr, getaddr),
|
||||
};
|
||||
|
||||
static struct rpcb_info rpcb_next_version[] = {
|
||||
#ifdef CONFIG_SUNRPC_BIND34
|
||||
{ 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
|
||||
{ 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
|
||||
#endif
|
||||
{ 2, &rpcb_procedures2[RPCBPROC_GETPORT] },
|
||||
{ 0, NULL },
|
||||
{
|
||||
.rpc_vers = RPCBVERS_2,
|
||||
.rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
|
||||
},
|
||||
{
|
||||
.rpc_proc = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct rpcb_info rpcb_next_version6[] = {
|
||||
#ifdef CONFIG_SUNRPC_BIND34
|
||||
{ 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
|
||||
{ 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
|
||||
#endif
|
||||
{ 0, NULL },
|
||||
{
|
||||
.rpc_vers = RPCBVERS_4,
|
||||
.rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
|
||||
},
|
||||
{
|
||||
.rpc_vers = RPCBVERS_3,
|
||||
.rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
|
||||
},
|
||||
{
|
||||
.rpc_proc = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct rpc_version rpcb_version2 = {
|
||||
.number = 2,
|
||||
.number = RPCBVERS_2,
|
||||
.nrprocs = RPCB_HIGHPROC_2,
|
||||
.procs = rpcb_procedures2
|
||||
};
|
||||
|
||||
static struct rpc_version rpcb_version3 = {
|
||||
.number = 3,
|
||||
.number = RPCBVERS_3,
|
||||
.nrprocs = RPCB_HIGHPROC_3,
|
||||
.procs = rpcb_procedures3
|
||||
};
|
||||
|
||||
static struct rpc_version rpcb_version4 = {
|
||||
.number = 4,
|
||||
.number = RPCBVERS_4,
|
||||
.nrprocs = RPCB_HIGHPROC_4,
|
||||
.procs = rpcb_procedures4
|
||||
};
|
||||
|
@@ -626,19 +626,15 @@ static void __rpc_execute(struct rpc_task *task)
|
||||
/*
|
||||
* Execute any pending callback.
|
||||
*/
|
||||
if (RPC_DO_CALLBACK(task)) {
|
||||
/* Define a callback save pointer */
|
||||
if (task->tk_callback) {
|
||||
void (*save_callback)(struct rpc_task *);
|
||||
|
||||
/*
|
||||
* If a callback exists, save it, reset it,
|
||||
* call it.
|
||||
* The save is needed to stop from resetting
|
||||
* another callback set within the callback handler
|
||||
* - Dave
|
||||
* We set tk_callback to NULL before calling it,
|
||||
* in case it sets the tk_callback field itself:
|
||||
*/
|
||||
save_callback=task->tk_callback;
|
||||
task->tk_callback=NULL;
|
||||
save_callback = task->tk_callback;
|
||||
task->tk_callback = NULL;
|
||||
save_callback(task);
|
||||
}
|
||||
|
||||
|
@@ -690,7 +690,7 @@ static void xprt_connect_status(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_xprt *xprt = task->tk_xprt;
|
||||
|
||||
if (task->tk_status >= 0) {
|
||||
if (task->tk_status == 0) {
|
||||
xprt->stat.connect_count++;
|
||||
xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start;
|
||||
dprintk("RPC: %5u xprt_connect_status: connection established\n",
|
||||
@@ -699,12 +699,6 @@ static void xprt_connect_status(struct rpc_task *task)
|
||||
}
|
||||
|
||||
switch (task->tk_status) {
|
||||
case -ECONNREFUSED:
|
||||
case -ECONNRESET:
|
||||
dprintk("RPC: %5u xprt_connect_status: server %s refused "
|
||||
"connection\n", task->tk_pid,
|
||||
task->tk_client->cl_server);
|
||||
break;
|
||||
case -ENOTCONN:
|
||||
dprintk("RPC: %5u xprt_connect_status: connection broken\n",
|
||||
task->tk_pid);
|
||||
@@ -878,6 +872,7 @@ void xprt_transmit(struct rpc_task *task)
|
||||
return;
|
||||
|
||||
req->rq_connect_cookie = xprt->connect_cookie;
|
||||
req->rq_xtime = jiffies;
|
||||
status = xprt->ops->send_request(task);
|
||||
if (status == 0) {
|
||||
dprintk("RPC: %5u xmit complete\n", task->tk_pid);
|
||||
|
@@ -579,7 +579,6 @@ static int xs_udp_send_request(struct rpc_task *task)
|
||||
req->rq_svec->iov_base,
|
||||
req->rq_svec->iov_len);
|
||||
|
||||
req->rq_xtime = jiffies;
|
||||
status = xs_sendpages(transport->sock,
|
||||
xs_addr(xprt),
|
||||
xprt->addrlen, xdr,
|
||||
@@ -671,7 +670,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
||||
* to cope with writespace callbacks arriving _after_ we have
|
||||
* called sendmsg(). */
|
||||
while (1) {
|
||||
req->rq_xtime = jiffies;
|
||||
status = xs_sendpages(transport->sock,
|
||||
NULL, 0, xdr, req->rq_bytes_sent);
|
||||
|
||||
|
Reference in New Issue
Block a user