diff options
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 74cb0d8e9ca1..4bda09d7e1a4 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -922,48 +922,65 @@ void svc_close_xprt(struct svc_xprt *xprt) | |||
922 | } | 922 | } |
923 | EXPORT_SYMBOL_GPL(svc_close_xprt); | 923 | EXPORT_SYMBOL_GPL(svc_close_xprt); |
924 | 924 | ||
925 | static void svc_close_list(struct list_head *xprt_list) | 925 | static void svc_close_list(struct list_head *xprt_list, struct net *net) |
926 | { | 926 | { |
927 | struct svc_xprt *xprt; | 927 | struct svc_xprt *xprt; |
928 | 928 | ||
929 | list_for_each_entry(xprt, xprt_list, xpt_list) { | 929 | list_for_each_entry(xprt, xprt_list, xpt_list) { |
930 | if (xprt->xpt_net != net) | ||
931 | continue; | ||
930 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 932 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
931 | set_bit(XPT_BUSY, &xprt->xpt_flags); | 933 | set_bit(XPT_BUSY, &xprt->xpt_flags); |
932 | } | 934 | } |
933 | } | 935 | } |
934 | 936 | ||
935 | void svc_close_all(struct svc_serv *serv) | 937 | static void svc_clear_pools(struct svc_serv *serv, struct net *net) |
936 | { | 938 | { |
937 | struct svc_pool *pool; | 939 | struct svc_pool *pool; |
938 | struct svc_xprt *xprt; | 940 | struct svc_xprt *xprt; |
939 | struct svc_xprt *tmp; | 941 | struct svc_xprt *tmp; |
940 | int i; | 942 | int i; |
941 | 943 | ||
942 | svc_close_list(&serv->sv_tempsocks); | ||
943 | svc_close_list(&serv->sv_permsocks); | ||
944 | |||
945 | for (i = 0; i < serv->sv_nrpools; i++) { | 944 | for (i = 0; i < serv->sv_nrpools; i++) { |
946 | pool = &serv->sv_pools[i]; | 945 | pool = &serv->sv_pools[i]; |
947 | 946 | ||
948 | spin_lock_bh(&pool->sp_lock); | 947 | spin_lock_bh(&pool->sp_lock); |
949 | while (!list_empty(&pool->sp_sockets)) { | 948 | list_for_each_entry_safe(xprt, tmp, &pool->sp_sockets, xpt_ready) { |
950 | xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready); | 949 | if (xprt->xpt_net != net) |
950 | continue; | ||
951 | list_del_init(&xprt->xpt_ready); | 951 | list_del_init(&xprt->xpt_ready); |
952 | } | 952 | } |
953 | spin_unlock_bh(&pool->sp_lock); | 953 | spin_unlock_bh(&pool->sp_lock); |
954 | } | 954 | } |
955 | } | ||
956 | |||
957 | static void svc_clear_list(struct list_head *xprt_list, struct net *net) | ||
958 | { | ||
959 | struct svc_xprt *xprt; | ||
960 | struct svc_xprt *tmp; | ||
961 | |||
962 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | ||
963 | if (xprt->xpt_net != net) | ||
964 | continue; | ||
965 | svc_delete_xprt(xprt); | ||
966 | } | ||
967 | list_for_each_entry(xprt, xprt_list, xpt_list) | ||
968 | BUG_ON(xprt->xpt_net == net); | ||
969 | } | ||
970 | |||
971 | void svc_close_net(struct svc_serv *serv, struct net *net) | ||
972 | { | ||
973 | svc_close_list(&serv->sv_tempsocks, net); | ||
974 | svc_close_list(&serv->sv_permsocks, net); | ||
975 | |||
976 | svc_clear_pools(serv, net); | ||
955 | /* | 977 | /* |
956 | * At this point the sp_sockets lists will stay empty, since | 978 | * At this point the sp_sockets lists will stay empty, since |
957 | * svc_enqueue will not add new entries without taking the | 979 | * svc_enqueue will not add new entries without taking the |
958 | * sp_lock and checking XPT_BUSY. | 980 | * sp_lock and checking XPT_BUSY. |
959 | */ | 981 | */ |
960 | list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list) | 982 | svc_clear_list(&serv->sv_tempsocks, net); |
961 | svc_delete_xprt(xprt); | 983 | svc_clear_list(&serv->sv_permsocks, net); |
962 | list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list) | ||
963 | svc_delete_xprt(xprt); | ||
964 | |||
965 | BUG_ON(!list_empty(&serv->sv_permsocks)); | ||
966 | BUG_ON(!list_empty(&serv->sv_tempsocks)); | ||
967 | } | 984 | } |
968 | 985 | ||
969 | /* | 986 | /* |
@@ -1089,6 +1106,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | |||
1089 | * svc_find_xprt - find an RPC transport instance | 1106 | * svc_find_xprt - find an RPC transport instance |
1090 | * @serv: pointer to svc_serv to search | 1107 | * @serv: pointer to svc_serv to search |
1091 | * @xcl_name: C string containing transport's class name | 1108 | * @xcl_name: C string containing transport's class name |
1109 | * @net: owner net pointer | ||
1092 | * @af: Address family of transport's local address | 1110 | * @af: Address family of transport's local address |
1093 | * @port: transport's IP port number | 1111 | * @port: transport's IP port number |
1094 | * | 1112 | * |
@@ -1101,7 +1119,8 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | |||
1101 | * service's list that has a matching class name. | 1119 | * service's list that has a matching class name. |
1102 | */ | 1120 | */ |
1103 | struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, | 1121 | struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, |
1104 | const sa_family_t af, const unsigned short port) | 1122 | struct net *net, const sa_family_t af, |
1123 | const unsigned short port) | ||
1105 | { | 1124 | { |
1106 | struct svc_xprt *xprt; | 1125 | struct svc_xprt *xprt; |
1107 | struct svc_xprt *found = NULL; | 1126 | struct svc_xprt *found = NULL; |
@@ -1112,6 +1131,8 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, | |||
1112 | 1131 | ||
1113 | spin_lock_bh(&serv->sv_lock); | 1132 | spin_lock_bh(&serv->sv_lock); |
1114 | list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { | 1133 | list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { |
1134 | if (xprt->xpt_net != net) | ||
1135 | continue; | ||
1115 | if (strcmp(xprt->xpt_class->xcl_name, xcl_name)) | 1136 | if (strcmp(xprt->xpt_class->xcl_name, xcl_name)) |
1116 | continue; | 1137 | continue; |
1117 | if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family) | 1138 | if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family) |