rxrpc: Support network namespacing
Support network namespacing in AF_RXRPC with the following changes:
(1) All the local endpoint, peer and call lists, locks, counters, etc. are
moved into the per-namespace record.
(2) All the connection tracking is moved into the per-namespace record
with the exception of the client connection ID tree, which is kept
global so that connection IDs are kept unique per-machine.
(3) Each namespace gets its own epoch. This allows each network namespace
to pretend to be a separate client machine.
(4) The /proc/net/rxrpc_xxx files are now called /proc/net/rxrpc/xxx and
the contents reflect the namespace.
fs/afs/ should be okay with this patch as it explicitly requires the current
net namespace to be init_net to permit a mount to proceed at the moment. It
will, however, need updating so that cells, IP addresses and DNS records are
per-namespace also.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
878cd3ba37
commit
2baec2c3f8
@@ -44,8 +44,6 @@ const char *const rxrpc_call_completions[NR__RXRPC_CALL_COMPLETIONS] = {
|
||||
};
|
||||
|
||||
struct kmem_cache *rxrpc_call_jar;
|
||||
LIST_HEAD(rxrpc_calls);
|
||||
DEFINE_RWLOCK(rxrpc_call_lock);
|
||||
|
||||
static void rxrpc_call_timer_expired(unsigned long _call)
|
||||
{
|
||||
@@ -207,6 +205,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
||||
__releases(&rx->sk.sk_lock.slock)
|
||||
{
|
||||
struct rxrpc_call *call, *xcall;
|
||||
struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk));
|
||||
struct rb_node *parent, **pp;
|
||||
const void *here = __builtin_return_address(0);
|
||||
int ret;
|
||||
@@ -255,9 +254,9 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
||||
|
||||
write_unlock(&rx->call_lock);
|
||||
|
||||
write_lock(&rxrpc_call_lock);
|
||||
list_add_tail(&call->link, &rxrpc_calls);
|
||||
write_unlock(&rxrpc_call_lock);
|
||||
write_lock(&rxnet->call_lock);
|
||||
list_add_tail(&call->link, &rxnet->calls);
|
||||
write_unlock(&rxnet->call_lock);
|
||||
|
||||
/* From this point on, the call is protected by its own lock. */
|
||||
release_sock(&rx->sk);
|
||||
@@ -508,6 +507,7 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
|
||||
*/
|
||||
void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
|
||||
{
|
||||
struct rxrpc_net *rxnet;
|
||||
const void *here = __builtin_return_address(0);
|
||||
int n;
|
||||
|
||||
@@ -520,9 +520,12 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
|
||||
_debug("call %d dead", call->debug_id);
|
||||
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
|
||||
|
||||
write_lock(&rxrpc_call_lock);
|
||||
list_del_init(&call->link);
|
||||
write_unlock(&rxrpc_call_lock);
|
||||
if (!list_empty(&call->link)) {
|
||||
rxnet = rxrpc_net(sock_net(&call->socket->sk));
|
||||
write_lock(&rxnet->call_lock);
|
||||
list_del_init(&call->link);
|
||||
write_unlock(&rxnet->call_lock);
|
||||
}
|
||||
|
||||
rxrpc_cleanup_call(call);
|
||||
}
|
||||
@@ -570,21 +573,23 @@ void rxrpc_cleanup_call(struct rxrpc_call *call)
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that all calls are gone.
|
||||
* Make sure that all calls are gone from a network namespace. To reach this
|
||||
* point, any open UDP sockets in that namespace must have been closed, so any
|
||||
* outstanding calls cannot be doing I/O.
|
||||
*/
|
||||
void __exit rxrpc_destroy_all_calls(void)
|
||||
void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
|
||||
{
|
||||
struct rxrpc_call *call;
|
||||
|
||||
_enter("");
|
||||
|
||||
if (list_empty(&rxrpc_calls))
|
||||
if (list_empty(&rxnet->calls))
|
||||
return;
|
||||
|
||||
write_lock(&rxrpc_call_lock);
|
||||
write_lock(&rxnet->call_lock);
|
||||
|
||||
while (!list_empty(&rxrpc_calls)) {
|
||||
call = list_entry(rxrpc_calls.next, struct rxrpc_call, link);
|
||||
while (!list_empty(&rxnet->calls)) {
|
||||
call = list_entry(rxnet->calls.next, struct rxrpc_call, link);
|
||||
_debug("Zapping call %p", call);
|
||||
|
||||
rxrpc_see_call(call);
|
||||
@@ -595,10 +600,10 @@ void __exit rxrpc_destroy_all_calls(void)
|
||||
rxrpc_call_states[call->state],
|
||||
call->flags, call->events);
|
||||
|
||||
write_unlock(&rxrpc_call_lock);
|
||||
write_unlock(&rxnet->call_lock);
|
||||
cond_resched();
|
||||
write_lock(&rxrpc_call_lock);
|
||||
write_lock(&rxnet->call_lock);
|
||||
}
|
||||
|
||||
write_unlock(&rxrpc_call_lock);
|
||||
write_unlock(&rxnet->call_lock);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user