|
@@ -57,6 +57,9 @@ static struct task_struct *nlmsvc_task;
|
|
|
static struct svc_rqst *nlmsvc_rqst;
|
|
|
unsigned long nlmsvc_timeout;
|
|
|
|
|
|
+atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
|
|
|
+DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
|
|
|
+
|
|
|
unsigned int lockd_net_id;
|
|
|
|
|
|
/*
|
|
@@ -293,7 +296,8 @@ static int lockd_inetaddr_event(struct notifier_block *this,
|
|
|
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
|
|
|
struct sockaddr_in sin;
|
|
|
|
|
|
- if (event != NETDEV_DOWN)
|
|
|
+ if ((event != NETDEV_DOWN) ||
|
|
|
+ !atomic_inc_not_zero(&nlm_ntf_refcnt))
|
|
|
goto out;
|
|
|
|
|
|
if (nlmsvc_rqst) {
|
|
@@ -304,6 +308,8 @@ static int lockd_inetaddr_event(struct notifier_block *this,
|
|
|
svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
|
|
|
(struct sockaddr *)&sin);
|
|
|
}
|
|
|
+ atomic_dec(&nlm_ntf_refcnt);
|
|
|
+ wake_up(&nlm_ntf_wq);
|
|
|
|
|
|
out:
|
|
|
return NOTIFY_DONE;
|
|
@@ -320,7 +326,8 @@ static int lockd_inet6addr_event(struct notifier_block *this,
|
|
|
struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
|
|
|
struct sockaddr_in6 sin6;
|
|
|
|
|
|
- if (event != NETDEV_DOWN)
|
|
|
+ if ((event != NETDEV_DOWN) ||
|
|
|
+ !atomic_inc_not_zero(&nlm_ntf_refcnt))
|
|
|
goto out;
|
|
|
|
|
|
if (nlmsvc_rqst) {
|
|
@@ -332,6 +339,8 @@ static int lockd_inet6addr_event(struct notifier_block *this,
|
|
|
svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
|
|
|
(struct sockaddr *)&sin6);
|
|
|
}
|
|
|
+ atomic_dec(&nlm_ntf_refcnt);
|
|
|
+ wake_up(&nlm_ntf_wq);
|
|
|
|
|
|
out:
|
|
|
return NOTIFY_DONE;
|
|
@@ -348,10 +357,12 @@ static void lockd_unregister_notifiers(void)
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
|
unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
|
|
|
#endif
|
|
|
+ wait_event(nlm_ntf_wq, atomic_read(&nlm_ntf_refcnt) == 0);
|
|
|
}
|
|
|
|
|
|
static void lockd_svc_exit_thread(void)
|
|
|
{
|
|
|
+ atomic_dec(&nlm_ntf_refcnt);
|
|
|
lockd_unregister_notifiers();
|
|
|
svc_exit_thread(nlmsvc_rqst);
|
|
|
}
|
|
@@ -376,6 +387,7 @@ static int lockd_start_svc(struct svc_serv *serv)
|
|
|
goto out_rqst;
|
|
|
}
|
|
|
|
|
|
+ atomic_inc(&nlm_ntf_refcnt);
|
|
|
svc_sock_update_bufs(serv);
|
|
|
serv->sv_maxconn = nlm_max_connections;
|
|
|
|