aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c51
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}
923EXPORT_SYMBOL_GPL(svc_close_xprt); 923EXPORT_SYMBOL_GPL(svc_close_xprt);
924 924
925static void svc_close_list(struct list_head *xprt_list) 925static 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
935void svc_close_all(struct svc_serv *serv) 937static 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
957static 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
971void 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 */
1103struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, 1121struct 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)