diff options
author | David S. Miller <davem@davemloft.net> | 2016-09-06 23:46:26 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-06 23:46:26 +0300 |
commit | 0122c6d5faa3c2bb2523119aa1e20ac5a2f10dd7 (patch) | |
tree | 7d7c4254ff7f02a9aa3a6cdc1ba9181c53113529 /net | |
parent | 5e1e61a33f987eb5d87c5acb199da99b6a9da93d (diff) | |
parent | 434e6120036d1dd1004cadf5a99941cdd9c1a59f (diff) | |
download | linux-0122c6d5faa3c2bb2523119aa1e20ac5a2f10dd7.tar.xz |
Merge tag 'rxrpc-rewrite-20160904-1' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says:
====================
rxrpc: Small fixes
Here's a set of small fix patches:
(1) Fix some uninitialised variables.
(2) Set the client call state before making it live by attaching it to the
conn struct.
(3) Randomise the epoch and starting client conn ID values, and don't
change the epoch when the client conn ID rolls round.
(4) Replace deprecated create_singlethread_workqueue() calls.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/rxrpc/af_rxrpc.c | 9 | ||||
-rw-r--r-- | net/rxrpc/call_event.c | 5 | ||||
-rw-r--r-- | net/rxrpc/call_object.c | 4 | ||||
-rw-r--r-- | net/rxrpc/conn_client.c | 36 |
4 files changed, 23 insertions, 31 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 32d544995dda..b66a9e6f8d04 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -16,6 +16,7 @@ #include <linux/net.h> #include <linux/slab.h> #include <linux/skbuff.h> +#include <linux/random.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/key-type.h> @@ -700,7 +701,13 @@ static int __init af_rxrpc_init(void) BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > FIELD_SIZEOF(struct sk_buff, cb)); - rxrpc_epoch = get_seconds(); + get_random_bytes(&rxrpc_epoch, sizeof(rxrpc_epoch)); + rxrpc_epoch |= RXRPC_RANDOM_EPOCH; + get_random_bytes(&rxrpc_client_conn_ids.cur, + sizeof(rxrpc_client_conn_ids.cur)); + rxrpc_client_conn_ids.cur &= 0x3fffffff; + if (rxrpc_client_conn_ids.cur == 0) + rxrpc_client_conn_ids.cur = 1; ret = -ENOMEM; rxrpc_call_jar = kmem_cache_create( diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index de72de662044..4754c7fb6242 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c @@ -868,7 +868,6 @@ skip_msg_init: /* deal with events of a final nature */ if (test_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events)) { enum rxrpc_skb_mark mark; - int error; clear_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events); clear_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events); @@ -876,10 +875,10 @@ skip_msg_init: if (call->completion == RXRPC_CALL_NETWORK_ERROR) { mark = RXRPC_SKB_MARK_NET_ERROR; - _debug("post net error %d", error); + _debug("post net error %d", call->error); } else { mark = RXRPC_SKB_MARK_LOCAL_ERROR; - _debug("post net local error %d", error); + _debug("post net local error %d", call->error); } if (rxrpc_post_message(call, mark, call->error, true) < 0) diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 516d8ea82f02..65691742199b 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -197,8 +197,6 @@ static int rxrpc_begin_client_call(struct rxrpc_call *call, if (ret < 0) return ret; - call->state = RXRPC_CALL_CLIENT_SEND_REQUEST; - spin_lock(&call->conn->params.peer->lock); hlist_add_head(&call->error_link, &call->conn->params.peer->error_targets); spin_unlock(&call->conn->params.peer->lock); @@ -586,7 +584,7 @@ static void rxrpc_dead_call_expired(unsigned long _call) */ static void rxrpc_mark_call_released(struct rxrpc_call *call) { - bool sched; + bool sched = false; rxrpc_see_call(call); write_lock(&call->state_lock); diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index 4b213bc0f554..82de1aeaef21 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c @@ -108,12 +108,12 @@ static DECLARE_DELAYED_WORK(rxrpc_client_conn_reap, /* * Get a connection ID and epoch for a client connection from the global pool. * The connection struct pointer is then recorded in the idr radix tree. The - * epoch is changed if this wraps. + * epoch doesn't change until the client is rebooted (or, at least, unless the + * module is unloaded). */ static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn, gfp_t gfp) { - u32 epoch; int id; _enter(""); @@ -121,34 +121,18 @@ static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn, idr_preload(gfp); spin_lock(&rxrpc_conn_id_lock); - epoch = rxrpc_epoch; - - /* We could use idr_alloc_cyclic() here, but we really need to know - * when the thing wraps so that we can advance the epoch. - */ - if (rxrpc_client_conn_ids.cur == 0) - rxrpc_client_conn_ids.cur = 1; - id = idr_alloc(&rxrpc_client_conn_ids, conn, - rxrpc_client_conn_ids.cur, 0x40000000, GFP_NOWAIT); - if (id < 0) { - if (id != -ENOSPC) - goto error; - id = idr_alloc(&rxrpc_client_conn_ids, conn, - 1, 0x40000000, GFP_NOWAIT); - if (id < 0) - goto error; - epoch++; - rxrpc_epoch = epoch; - } - rxrpc_client_conn_ids.cur = id + 1; + id = idr_alloc_cyclic(&rxrpc_client_conn_ids, conn, + 1, 0x40000000, GFP_NOWAIT); + if (id < 0) + goto error; spin_unlock(&rxrpc_conn_id_lock); idr_preload_end(); - conn->proto.epoch = epoch; + conn->proto.epoch = rxrpc_epoch; conn->proto.cid = id << RXRPC_CIDSHIFT; set_bit(RXRPC_CONN_HAS_IDR, &conn->flags); - _leave(" [CID %x:%x]", epoch, conn->proto.cid); + _leave(" [CID %x]", conn->proto.cid); return 0; error: @@ -537,6 +521,10 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn, struct rxrpc_call, chan_wait_link); u32 call_id = chan->call_counter + 1; + write_lock_bh(&call->state_lock); + call->state = RXRPC_CALL_CLIENT_SEND_REQUEST; + write_unlock_bh(&call->state_lock); + rxrpc_see_call(call); list_del_init(&call->chan_wait_link); conn->active_chans |= 1 << channel; |