RxRPC rewrite
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAV72yZ/Sw1s6N8H32AQITcQ//Tj+QPw2wnc6p6CAXSQ4CJAgprZP25dEY 11aaLsKBsBpJXyGjRWVxHJeoNnfVO05ATyZU1AjIlALDUY2Kq1IyNJWmmxZbx0M/ oaRN4kB41jKyJRGWnPdvQb7KL0SvjlyiEWNV9ztEk4W5Ik7UInAYl2sdovwzvgL0 Nw7KClg2lTLE8Nu4v0GYFxz5bCUw3M4a0+C5oXCSIpXwLOMQezAmXRhYNhlxHwmZ phuvJrP7xH0Z2G4MgVwvyOsQzzKptWoo3c5YxTWlhUl2qk1ZUKcu+eMv9ir/T3mD exiiMgDLd74Wb9J9U1AEmGp9NgfxM20MGR7O/ARZ8K8FUrxMWbEifjv/eqMl0YGr Wk/df+VwUsp3nfOMe7/UZaBCx5ZSV7x8WT6p6lRIQAIrJj1CFbo5pxHLgG/SPt5x EPniDw/oC+0G7sc3BjqTLZZP7qh27TuvuUVqAdgM7lJCpozk37Qnq4C0jwheJ7ct MvB1mGkfiHVnq3F0UL7emazmlYBULPTJvj7fN9iPAsvNYBbdENCbjfNP0T2YKNlW 1B08pUtMfHiS3/+LkFQ9yl0lhWnkApm++pNcOM1nLANi49Th92ch8lpfD6poAUBl vRWHcMeeqevnydl57WQJ40gtmJr1/5pKgVQwRY/sSBQztr/uqtM811dkNwlF3szw es7wA7HkKlI= =mirU -----END PGP SIGNATURE----- Merge tag 'rxrpc-rewrite-20160824-1' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs David Howells says: ==================== rxrpc: More fixes Here are a couple of fix patches: (1) Fix the conn-based retransmission patch posted yesterday. This breaks if it actually has to retransmit. However, it seems the likelihood of this happening is really low, despite the server I'm testing against being located >3000 miles away, and sometime of the time it's handled in the call background processor before we manage to disconnect the call - hence why I didn't spot it. (2) /proc/net/rxrpc_calls can cause a crash it accessed whilst a call is being torn down. The window of opportunity is pretty small, however, as calls don't stay in this state for long. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d3c10db138
|
@ -407,6 +407,7 @@ enum rxrpc_call_state {
|
|||
struct rxrpc_call {
|
||||
struct rcu_head rcu;
|
||||
struct rxrpc_connection *conn; /* connection carrying call */
|
||||
struct rxrpc_peer *peer; /* Peer record for remote address */
|
||||
struct rxrpc_sock *socket; /* socket responsible */
|
||||
struct timer_list lifetimer; /* lifetime remaining on call */
|
||||
struct timer_list deadspan; /* reap timer for re-ACK'ing, etc */
|
||||
|
@ -717,9 +718,10 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *,
|
|||
struct sockaddr_rxrpc *, gfp_t);
|
||||
struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *, gfp_t);
|
||||
|
||||
static inline void rxrpc_get_peer(struct rxrpc_peer *peer)
|
||||
static inline struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
|
||||
{
|
||||
atomic_inc(&peer->usage);
|
||||
return peer;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
|
@ -315,6 +315,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
|||
chan = sp->hdr.cid & RXRPC_CHANNELMASK;
|
||||
candidate->socket = rx;
|
||||
candidate->conn = conn;
|
||||
candidate->peer = conn->params.peer;
|
||||
candidate->cid = sp->hdr.cid;
|
||||
candidate->call_id = sp->hdr.callNumber;
|
||||
candidate->rx_data_post = 0;
|
||||
|
@ -384,6 +385,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
|||
rcu_assign_pointer(conn->channels[chan].call, call);
|
||||
sock_hold(&rx->sk);
|
||||
rxrpc_get_connection(conn);
|
||||
rxrpc_get_peer(call->peer);
|
||||
spin_unlock(&conn->channel_lock);
|
||||
|
||||
spin_lock(&conn->params.peer->lock);
|
||||
|
@ -610,6 +612,7 @@ static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
|
|||
struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
|
||||
|
||||
rxrpc_purge_queue(&call->rx_queue);
|
||||
rxrpc_put_peer(call->peer);
|
||||
kmem_cache_free(rxrpc_call_jar, call);
|
||||
}
|
||||
|
||||
|
|
|
@ -280,6 +280,7 @@ attached:
|
|||
found_channel:
|
||||
_debug("found chan");
|
||||
call->conn = conn;
|
||||
call->peer = rxrpc_get_peer(conn->params.peer);
|
||||
call->cid = conn->proto.cid | chan;
|
||||
call->call_id = ++conn->channels[chan].call_counter;
|
||||
conn->channels[chan].call_id = call->call_id;
|
||||
|
|
|
@ -42,6 +42,7 @@ static void rxrpc_conn_retransmit(struct rxrpc_connection *conn,
|
|||
} abort;
|
||||
struct {
|
||||
struct rxrpc_ackpacket ack;
|
||||
u8 padding[3];
|
||||
struct rxrpc_ackinfo info;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -732,7 +732,7 @@ void rxrpc_data_ready(struct sock *sk)
|
|||
/* For the previous service call, if completed
|
||||
* successfully, we discard all further packets.
|
||||
*/
|
||||
if (rxrpc_conn_is_service(call->conn) &&
|
||||
if (rxrpc_conn_is_service(conn) &&
|
||||
(chan->last_type == RXRPC_PACKET_TYPE_ACK ||
|
||||
sp->hdr.type == RXRPC_PACKET_TYPE_ABORT))
|
||||
goto discard_unlock;
|
||||
|
|
|
@ -46,7 +46,9 @@ static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
|
|||
|
||||
static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct rxrpc_connection *conn;
|
||||
struct rxrpc_local *local;
|
||||
struct rxrpc_sock *rx;
|
||||
struct rxrpc_peer *peer;
|
||||
struct rxrpc_call *call;
|
||||
char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
|
||||
|
||||
|
@ -60,15 +62,24 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
|||
|
||||
call = list_entry(v, struct rxrpc_call, link);
|
||||
|
||||
sprintf(lbuff, "%pI4:%u",
|
||||
&call->socket->local->srx.transport.sin.sin_addr,
|
||||
ntohs(call->socket->local->srx.transport.sin.sin_port));
|
||||
rx = READ_ONCE(call->socket);
|
||||
if (rx) {
|
||||
local = READ_ONCE(rx->local);
|
||||
if (local)
|
||||
sprintf(lbuff, "%pI4:%u",
|
||||
&local->srx.transport.sin.sin_addr,
|
||||
ntohs(local->srx.transport.sin.sin_port));
|
||||
else
|
||||
strcpy(lbuff, "no_local");
|
||||
} else {
|
||||
strcpy(lbuff, "no_socket");
|
||||
}
|
||||
|
||||
conn = call->conn;
|
||||
if (conn)
|
||||
peer = call->peer;
|
||||
if (peer)
|
||||
sprintf(rbuff, "%pI4:%u",
|
||||
&conn->params.peer->srx.transport.sin.sin_addr,
|
||||
ntohs(conn->params.peer->srx.transport.sin.sin_port));
|
||||
&peer->srx.transport.sin.sin_addr,
|
||||
ntohs(peer->srx.transport.sin.sin_port));
|
||||
else
|
||||
strcpy(rbuff, "no_connection");
|
||||
|
||||
|
|
Loading…
Reference in New Issue