aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index bb7ed2f3aee6..25c3da53fb69 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -204,21 +204,37 @@ static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
204 return err; 204 return err;
205} 205}
206 206
207static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
208{
209 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
210 struct rpc_clnt *clnt;
211
212 spin_lock(&sn->rpc_client_lock);
213 list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
214 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
215 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
216 continue;
217 atomic_inc(&clnt->cl_count);
218 spin_unlock(&sn->rpc_client_lock);
219 return clnt;
220 }
221 spin_unlock(&sn->rpc_client_lock);
222 return NULL;
223}
224
207static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 225static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
208 void *ptr) 226 void *ptr)
209{ 227{
210 struct super_block *sb = ptr; 228 struct super_block *sb = ptr;
211 struct rpc_clnt *clnt; 229 struct rpc_clnt *clnt;
212 int error = 0; 230 int error = 0;
213 struct sunrpc_net *sn = net_generic(sb->s_fs_info, sunrpc_net_id);
214 231
215 spin_lock(&sn->rpc_client_lock); 232 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) {
216 list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
217 error = __rpc_pipefs_event(clnt, event, sb); 233 error = __rpc_pipefs_event(clnt, event, sb);
234 rpc_release_client(clnt);
218 if (error) 235 if (error)
219 break; 236 break;
220 } 237 }
221 spin_unlock(&sn->rpc_client_lock);
222 return error; 238 return error;
223} 239}
224 240