diff options
-rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 45 |
2 files changed, 46 insertions, 0 deletions
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 78512cfe1fe6..b7dabc4baafd 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h | |||
@@ -128,6 +128,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, | |||
128 | const unsigned short port); | 128 | const unsigned short port); |
129 | int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); | 129 | int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); |
130 | void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt); | 130 | void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt); |
131 | void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *); | ||
131 | 132 | ||
132 | static inline void svc_xprt_get(struct svc_xprt *xprt) | 133 | static inline void svc_xprt_get(struct svc_xprt *xprt) |
133 | { | 134 | { |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index a6cbb2104667..7422f28818b2 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -10,11 +10,13 @@ | |||
10 | #include <linux/kthread.h> | 10 | #include <linux/kthread.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <net/sock.h> | 12 | #include <net/sock.h> |
13 | #include <linux/sunrpc/addr.h> | ||
13 | #include <linux/sunrpc/stats.h> | 14 | #include <linux/sunrpc/stats.h> |
14 | #include <linux/sunrpc/svc_xprt.h> | 15 | #include <linux/sunrpc/svc_xprt.h> |
15 | #include <linux/sunrpc/svcsock.h> | 16 | #include <linux/sunrpc/svcsock.h> |
16 | #include <linux/sunrpc/xprt.h> | 17 | #include <linux/sunrpc/xprt.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/netdevice.h> | ||
18 | #include <trace/events/sunrpc.h> | 20 | #include <trace/events/sunrpc.h> |
19 | 21 | ||
20 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 22 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
@@ -938,6 +940,49 @@ static void svc_age_temp_xprts(unsigned long closure) | |||
938 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); | 940 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); |
939 | } | 941 | } |
940 | 942 | ||
943 | /* Close temporary transports whose xpt_local matches server_addr immediately | ||
944 | * instead of waiting for them to be picked up by the timer. | ||
945 | * | ||
946 | * This is meant to be called from a notifier_block that runs when an ip | ||
947 | * address is deleted. | ||
948 | */ | ||
949 | void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr) | ||
950 | { | ||
951 | struct svc_xprt *xprt; | ||
952 | struct svc_sock *svsk; | ||
953 | struct socket *sock; | ||
954 | struct list_head *le, *next; | ||
955 | LIST_HEAD(to_be_closed); | ||
956 | struct linger no_linger = { | ||
957 | .l_onoff = 1, | ||
958 | .l_linger = 0, | ||
959 | }; | ||
960 | |||
961 | spin_lock_bh(&serv->sv_lock); | ||
962 | list_for_each_safe(le, next, &serv->sv_tempsocks) { | ||
963 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
964 | if (rpc_cmp_addr(server_addr, (struct sockaddr *) | ||
965 | &xprt->xpt_local)) { | ||
966 | dprintk("svc_age_temp_xprts_now: found %p\n", xprt); | ||
967 | list_move(le, &to_be_closed); | ||
968 | } | ||
969 | } | ||
970 | spin_unlock_bh(&serv->sv_lock); | ||
971 | |||
972 | while (!list_empty(&to_be_closed)) { | ||
973 | le = to_be_closed.next; | ||
974 | list_del_init(le); | ||
975 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
976 | dprintk("svc_age_temp_xprts_now: closing %p\n", xprt); | ||
977 | svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
978 | sock = svsk->sk_sock; | ||
979 | kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, | ||
980 | (char *)&no_linger, sizeof(no_linger)); | ||
981 | svc_close_xprt(xprt); | ||
982 | } | ||
983 | } | ||
984 | EXPORT_SYMBOL_GPL(svc_age_temp_xprts_now); | ||
985 | |||
941 | static void call_xpt_users(struct svc_xprt *xprt) | 986 | static void call_xpt_users(struct svc_xprt *xprt) |
942 | { | 987 | { |
943 | struct svc_xpt_user *u; | 988 | struct svc_xpt_user *u; |