diff options
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/host.c | 24 | ||||
| -rw-r--r-- | fs/lockd/mon.c | 3 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 38 | ||||
| -rw-r--r-- | fs/lockd/svcsubs.c | 2 | 
4 files changed, 49 insertions, 18 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 0d4e590e0549..826a89184f90 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -578,8 +578,10 @@ static void nlm_complain_hosts(struct net *net)  		if (ln->nrhosts == 0)  			return; -		printk(KERN_WARNING "lockd: couldn't shutdown host module for net %p!\n", net); -		dprintk("lockd: %lu hosts left in net %p:\n", ln->nrhosts, net); +		pr_warn("lockd: couldn't shutdown host module for net %x!\n", +			net->ns.inum); +		dprintk("lockd: %lu hosts left in net %x:\n", ln->nrhosts, +			net->ns.inum);  	} else {  		if (nrhosts == 0)  			return; @@ -590,9 +592,9 @@ static void nlm_complain_hosts(struct net *net)  	for_each_host(host, chain, nlm_server_hosts) {  		if (net && host->net != net)  			continue; -		dprintk("       %s (cnt %d use %d exp %ld net %p)\n", +		dprintk("       %s (cnt %d use %d exp %ld net %x)\n",  			host->h_name, atomic_read(&host->h_count), -			host->h_inuse, host->h_expires, host->net); +			host->h_inuse, host->h_expires, host->net->ns.inum);  	}  } @@ -605,7 +607,8 @@ nlm_shutdown_hosts_net(struct net *net)  	mutex_lock(&nlm_host_mutex);  	/* First, make all hosts eligible for gc */ -	dprintk("lockd: nuking all hosts in net %p...\n", net); +	dprintk("lockd: nuking all hosts in net %x...\n", +		net ? net->ns.inum : 0);  	for_each_host(host, chain, nlm_server_hosts) {  		if (net && host->net != net)  			continue; @@ -618,9 +621,8 @@ nlm_shutdown_hosts_net(struct net *net)  	/* Then, perform a garbage collection pass */  	nlm_gc_hosts(net); -	mutex_unlock(&nlm_host_mutex); -  	nlm_complain_hosts(net); +	mutex_unlock(&nlm_host_mutex);  }  /* @@ -646,7 +648,8 @@ nlm_gc_hosts(struct net *net)  	struct hlist_node *next;  	struct nlm_host	*host; -	dprintk("lockd: host garbage collection for net %p\n", net); +	dprintk("lockd: host garbage collection for net %x\n", +		net ? net->ns.inum : 0);  	for_each_host(host, chain, nlm_server_hosts) {  		if (net && host->net != net)  			continue; @@ -662,9 +665,10 @@ nlm_gc_hosts(struct net *net)  		if (atomic_read(&host->h_count) || host->h_inuse  		 || time_before(jiffies, host->h_expires)) {  			dprintk("nlm_gc_hosts skipping %s " -				"(cnt %d use %d exp %ld net %p)\n", +				"(cnt %d use %d exp %ld net %x)\n",  				host->h_name, atomic_read(&host->h_count), -				host->h_inuse, host->h_expires, host->net); +				host->h_inuse, host->h_expires, +				host->net->ns.inum);  			continue;  		}  		nlm_destroy_host_locked(host); diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 9fbbd11f9ecb..96cfb2967ac7 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -110,7 +110,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,  	clnt = nsm_create(host->net, host->nodename);  	if (IS_ERR(clnt)) {  		dprintk("lockd: failed to create NSM upcall transport, " -			"status=%ld, net=%p\n", PTR_ERR(clnt), host->net); +			"status=%ld, net=%x\n", PTR_ERR(clnt), +			host->net->ns.inum);  		return PTR_ERR(clnt);  	} diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index a8e3777c94dc..9c36d614bf89 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -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;  /* @@ -259,7 +262,7 @@ static int lockd_up_net(struct svc_serv *serv, struct net *net)  	if (error < 0)  		goto err_bind;  	set_grace_period(net); -	dprintk("lockd_up_net: per-net data created; net=%p\n", net); +	dprintk("%s: per-net data created; net=%x\n", __func__, net->ns.inum);  	return 0;  err_bind: @@ -274,12 +277,15 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)  	if (ln->nlmsvc_users) {  		if (--ln->nlmsvc_users == 0) {  			nlm_shutdown_hosts_net(net); +			cancel_delayed_work_sync(&ln->grace_period_end); +			locks_end_grace(&ln->lockd_manager);  			svc_shutdown_net(serv, net); -			dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); +			dprintk("%s: per-net data destroyed; net=%x\n", +				__func__, net->ns.inum);  		}  	} else { -		printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", -				nlmsvc_task, net); +		pr_err("%s: no users! task=%p, net=%x\n", +			__func__, nlmsvc_task, net->ns.inum);  		BUG();  	}  } @@ -290,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) { @@ -301,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; @@ -317,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) { @@ -329,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; @@ -345,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);  } @@ -373,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; @@ -676,6 +691,17 @@ static int lockd_init_net(struct net *net)  static void lockd_exit_net(struct net *net)  { +	struct lockd_net *ln = net_generic(net, lockd_net_id); + +	WARN_ONCE(!list_empty(&ln->lockd_manager.list), +		  "net %x %s: lockd_manager.list is not empty\n", +		  net->ns.inum, __func__); +	WARN_ONCE(!list_empty(&ln->nsm_handles), +		  "net %x %s: nsm_handles list is not empty\n", +		  net->ns.inum, __func__); +	WARN_ONCE(delayed_work_pending(&ln->grace_period_end), +		  "net %x %s: grace_period_end was not cancelled\n", +		  net->ns.inum, __func__);  }  static struct pernet_operations lockd_net_ops = { diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index a563ddbc19e6..4ec3d6e03e76 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -370,7 +370,7 @@ nlmsvc_mark_resources(struct net *net)  {  	struct nlm_host hint; -	dprintk("lockd: nlmsvc_mark_resources for net %p\n", net); +	dprintk("lockd: %s for net %x\n", __func__, net ? net->ns.inum : 0);  	hint.net = net;  	nlm_traverse_files(&hint, nlmsvc_mark_host, NULL);  }  | 

