summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/9p/client.c2
-rw-r--r--net/9p/trans_xen.c2
-rw-r--r--net/ceph/ceph_common.c18
-rw-r--r--net/ceph/mon_client.c9
-rw-r--r--net/sunrpc/clnt.c44
-rw-r--r--net/sunrpc/xprt.c2
-rw-r--r--net/sunrpc/xprtsock.c6
7 files changed, 57 insertions, 26 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 357214a51f13..b85d51f4b8eb 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1061,7 +1061,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
p9_debug(P9_DEBUG_ERROR,
"Please specify a msize of at least 4k\n");
err = -EINVAL;
- goto free_client;
+ goto close_trans;
}
err = p9_client_version(clnt);
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index e2fbf3677b9b..29420ebb8f07 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -513,7 +513,7 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
- /* Missed the backend's CLOSING state -- fallthrough */
+ /* fall through - Missed the backend's CLOSING state */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 9cab80207ced..79eac465ec65 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -738,7 +738,6 @@ int __ceph_open_session(struct ceph_client *client, unsigned long started)
}
EXPORT_SYMBOL(__ceph_open_session);
-
int ceph_open_session(struct ceph_client *client)
{
int ret;
@@ -754,6 +753,23 @@ int ceph_open_session(struct ceph_client *client)
}
EXPORT_SYMBOL(ceph_open_session);
+int ceph_wait_for_latest_osdmap(struct ceph_client *client,
+ unsigned long timeout)
+{
+ u64 newest_epoch;
+ int ret;
+
+ ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
+ if (ret)
+ return ret;
+
+ if (client->osdc.osdmap->epoch >= newest_epoch)
+ return 0;
+
+ ceph_osdc_maybe_request_map(&client->osdc);
+ return ceph_monc_wait_osdmap(&client->monc, newest_epoch, timeout);
+}
+EXPORT_SYMBOL(ceph_wait_for_latest_osdmap);
static int __init init_ceph_lib(void)
{
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 18deb3d889c4..a53e4fbb6319 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -922,6 +922,15 @@ int ceph_monc_blacklist_add(struct ceph_mon_client *monc,
mutex_unlock(&monc->mutex);
ret = wait_generic_request(req);
+ if (!ret)
+ /*
+ * Make sure we have the osdmap that includes the blacklist
+ * entry. This is needed to ensure that the OSDs pick up the
+ * new blacklist before processing any future requests from
+ * this client.
+ */
+ ret = ceph_wait_for_latest_osdmap(monc->client, 0);
+
out:
put_generic_request(req);
return ret;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 4216fe33204a..187d10443a15 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1730,7 +1730,12 @@ call_allocate(struct rpc_task *task)
req->rq_callsize = RPC_CALLHDRSIZE + (auth->au_cslack << 1) +
proc->p_arglen;
req->rq_callsize <<= 2;
- req->rq_rcvsize = RPC_REPHDRSIZE + auth->au_rslack + proc->p_replen;
+ /*
+ * Note: the reply buffer must at minimum allocate enough space
+ * for the 'struct accepted_reply' from RFC5531.
+ */
+ req->rq_rcvsize = RPC_REPHDRSIZE + auth->au_rslack + \
+ max_t(size_t, proc->p_replen, 2);
req->rq_rcvsize <<= 2;
status = xprt->ops->buf_alloc(task);
@@ -2306,6 +2311,15 @@ out_exit:
rpc_exit(task, status);
}
+static bool
+rpc_check_connected(const struct rpc_rqst *req)
+{
+ /* No allocated request or transport? return true */
+ if (!req || !req->rq_xprt)
+ return true;
+ return xprt_connected(req->rq_xprt);
+}
+
static void
rpc_check_timeout(struct rpc_task *task)
{
@@ -2317,10 +2331,11 @@ rpc_check_timeout(struct rpc_task *task)
dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
task->tk_timeouts++;
- if (RPC_IS_SOFTCONN(task)) {
+ if (RPC_IS_SOFTCONN(task) && !rpc_check_connected(task->tk_rqstp)) {
rpc_exit(task, -ETIMEDOUT);
return;
}
+
if (RPC_IS_SOFT(task)) {
if (clnt->cl_chatty) {
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
@@ -2387,9 +2402,6 @@ call_decode(struct rpc_task *task)
WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
sizeof(req->rq_rcv_buf)) != 0);
- if (req->rq_rcv_buf.len < 12)
- goto out_retry;
-
xdr_init_decode(&xdr, &req->rq_rcv_buf,
req->rq_rcv_buf.head[0].iov_base, req);
switch (rpc_decode_header(task, &xdr)) {
@@ -2400,7 +2412,6 @@ call_decode(struct rpc_task *task)
task->tk_pid, __func__, task->tk_status);
return;
case -EAGAIN:
-out_retry:
task->tk_status = 0;
/* Note: rpc_decode_header() may have freed the RPC slot */
if (task->tk_rqstp == req) {
@@ -2449,7 +2460,7 @@ static noinline int
rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
{
struct rpc_clnt *clnt = task->tk_client;
- int error = -EACCES;
+ int error;
__be32 *p;
/* RFC-1014 says that the representation of XDR data must be a
@@ -2458,7 +2469,7 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
* undefined results
*/
if (task->tk_rqstp->rq_rcv_buf.len & 3)
- goto out_badlen;
+ goto out_unparsable;
p = xdr_inline_decode(xdr, 3 * sizeof(*p));
if (!p)
@@ -2492,10 +2503,12 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
error = -EOPNOTSUPP;
goto out_err;
case rpc_garbage_args:
+ case rpc_system_err:
trace_rpc__garbage_args(task);
+ error = -EIO;
break;
default:
- trace_rpc__unparsable(task);
+ goto out_unparsable;
}
out_garbage:
@@ -2509,11 +2522,6 @@ out_err:
rpc_exit(task, error);
return error;
-out_badlen:
- trace_rpc__unparsable(task);
- error = -EIO;
- goto out_err;
-
out_unparsable:
trace_rpc__unparsable(task);
error = -EIO;
@@ -2524,6 +2532,7 @@ out_verifier:
goto out_garbage;
out_msg_denied:
+ error = -EACCES;
p = xdr_inline_decode(xdr, sizeof(*p));
if (!p)
goto out_unparsable;
@@ -2535,9 +2544,7 @@ out_msg_denied:
error = -EPROTONOSUPPORT;
goto out_err;
default:
- trace_rpc__unparsable(task);
- error = -EIO;
- goto out_err;
+ goto out_unparsable;
}
p = xdr_inline_decode(xdr, sizeof(*p));
@@ -2572,8 +2579,7 @@ out_msg_denied:
task->tk_xprt->servername);
break;
default:
- trace_rpc__unparsable(task);
- error = -EIO;
+ goto out_unparsable;
}
goto out_err;
}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index e096c5a725df..d7117d241460 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -664,7 +664,7 @@ void xprt_disconnect_done(struct rpc_xprt *xprt)
spin_lock_bh(&xprt->transport_lock);
xprt_clear_connected(xprt);
xprt_clear_write_space_locked(xprt);
- xprt_wake_pending_tasks(xprt, -EAGAIN);
+ xprt_wake_pending_tasks(xprt, -ENOTCONN);
spin_unlock_bh(&xprt->transport_lock);
}
EXPORT_SYMBOL_GPL(xprt_disconnect_done);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 42f45d33dc56..732d4b57411a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -453,7 +453,7 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
goto out;
if (ret != want)
goto out;
- } else
+ } else if (offset < seek_init)
offset = seek_init;
ret = -EMSGSIZE;
out:
@@ -495,8 +495,8 @@ xs_read_stream_request(struct sock_xprt *transport, struct msghdr *msg,
int flags, struct rpc_rqst *req)
{
struct xdr_buf *buf = &req->rq_private_buf;
- size_t want, read;
- ssize_t ret;
+ size_t want, uninitialized_var(read);
+ ssize_t uninitialized_var(ret);
xs_read_header(transport, buf);