aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 15:09:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 15:09:43 -0400
commitbe0c5d8c0bb0023e11f5c6d38e90f7b0f24edb64 (patch)
tree6d7a6e290f8ed2f2ca250965a8debdd9f02a9cc9 /net/sunrpc
parent1f792dd1765e6f047ecd2d5f6a81f025b50d471a (diff)
parent959d921f5eb8878ea16049a7f6e9bcbb6dfbcb88 (diff)
Merge tag 'nfs-for-3.11-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Feature highlights include: - Add basic client support for NFSv4.2 - Add basic client support for Labeled NFS (selinux for NFSv4.2) - Fix the use of credentials in NFSv4.1 stateful operations, and add support for NFSv4.1 state protection. Bugfix highlights: - Fix another NFSv4 open state recovery race - Fix an NFSv4.1 back channel session regression - Various rpc_pipefs races - Fix another issue with NFSv3 auth negotiation Please note that Labeled NFS does require some additional support from the security subsystem. The relevant changesets have all been reviewed and acked by James Morris." * tag 'nfs-for-3.11-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (54 commits) NFS: Set NFS_CS_MIGRATION for NFSv4 mounts NFSv4.1 Refactor nfs4_init_session and nfs4_init_channel_attrs nfs: have NFSv3 try server-specified auth flavors in turn nfs: have nfs_mount fake up a auth_flavs list when the server didn't provide it nfs: move server_authlist into nfs_try_mount_request nfs: refactor "need_mount" code out of nfs_try_mount SUNRPC: PipeFS MOUNT notification optimization for dying clients SUNRPC: split client creation routine into setup and registration SUNRPC: fix races on PipeFS UMOUNT notifications SUNRPC: fix races on PipeFS MOUNT notifications NFSv4.1 use pnfs_device maxcount for the objectlayout gdia_maxcount NFSv4.1 use pnfs_device maxcount for the blocklayout gdia_maxcount NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize NFS: Improve legacy idmapping fallback NFSv4.1 end back channel session draining NFS: Apply v4.1 capabilities to v4.2 NFSv4.1: Clean up layout segment comparison helper names NFSv4.1: layout segment comparison helpers should take 'const' parameters NFSv4: Move the DNS resolver into the NFSv4 module rpc_pipefs: only set rpc_dentry_ops if d_op isn't already set ...
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/clnt.c71
-rw-r--r--net/sunrpc/rpc_pipe.c8
-rw-r--r--net/sunrpc/sched.c19
3 files changed, 53 insertions, 45 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5a750b9c3640..f0339ae9bf37 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -157,20 +157,15 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
157} 157}
158 158
159static int 159static int
160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) 160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name,
161 struct super_block *pipefs_sb)
161{ 162{
162 struct net *net = rpc_net_ns(clnt);
163 struct super_block *pipefs_sb;
164 struct dentry *dentry; 163 struct dentry *dentry;
165 164
166 clnt->cl_dentry = NULL; 165 clnt->cl_dentry = NULL;
167 if (dir_name == NULL) 166 if (dir_name == NULL)
168 return 0; 167 return 0;
169 pipefs_sb = rpc_get_sb_net(net);
170 if (!pipefs_sb)
171 return 0;
172 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); 168 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
173 rpc_put_sb_net(net);
174 if (IS_ERR(dentry)) 169 if (IS_ERR(dentry))
175 return PTR_ERR(dentry); 170 return PTR_ERR(dentry);
176 clnt->cl_dentry = dentry; 171 clnt->cl_dentry = dentry;
@@ -182,6 +177,8 @@ static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event
182 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || 177 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
183 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) 178 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
184 return 1; 179 return 1;
180 if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
181 return 1;
185 return 0; 182 return 0;
186} 183}
187 184
@@ -241,8 +238,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
241 continue; 238 continue;
242 if (rpc_clnt_skip_event(clnt, event)) 239 if (rpc_clnt_skip_event(clnt, event))
243 continue; 240 continue;
244 if (atomic_inc_not_zero(&clnt->cl_count) == 0)
245 continue;
246 spin_unlock(&sn->rpc_client_lock); 241 spin_unlock(&sn->rpc_client_lock);
247 return clnt; 242 return clnt;
248 } 243 }
@@ -259,7 +254,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
259 254
260 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { 255 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) {
261 error = __rpc_pipefs_event(clnt, event, sb); 256 error = __rpc_pipefs_event(clnt, event, sb);
262 rpc_release_client(clnt);
263 if (error) 257 if (error)
264 break; 258 break;
265 } 259 }
@@ -289,12 +283,46 @@ static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
289 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); 283 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
290} 284}
291 285
286static int rpc_client_register(const struct rpc_create_args *args,
287 struct rpc_clnt *clnt)
288{
289 const struct rpc_program *program = args->program;
290 struct rpc_auth *auth;
291 struct net *net = rpc_net_ns(clnt);
292 struct super_block *pipefs_sb;
293 int err = 0;
294
295 pipefs_sb = rpc_get_sb_net(net);
296 if (pipefs_sb) {
297 err = rpc_setup_pipedir(clnt, program->pipe_dir_name, pipefs_sb);
298 if (err)
299 goto out;
300 }
301
302 auth = rpcauth_create(args->authflavor, clnt);
303 if (IS_ERR(auth)) {
304 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
305 args->authflavor);
306 err = PTR_ERR(auth);
307 goto err_auth;
308 }
309
310 rpc_register_client(clnt);
311out:
312 if (pipefs_sb)
313 rpc_put_sb_net(net);
314 return err;
315
316err_auth:
317 __rpc_clnt_remove_pipedir(clnt);
318 goto out;
319}
320
292static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 321static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
293{ 322{
294 const struct rpc_program *program = args->program; 323 const struct rpc_program *program = args->program;
295 const struct rpc_version *version; 324 const struct rpc_version *version;
296 struct rpc_clnt *clnt = NULL; 325 struct rpc_clnt *clnt = NULL;
297 struct rpc_auth *auth;
298 int err; 326 int err;
299 327
300 /* sanity check the name before trying to print it */ 328 /* sanity check the name before trying to print it */
@@ -354,25 +382,14 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
354 382
355 atomic_set(&clnt->cl_count, 1); 383 atomic_set(&clnt->cl_count, 1);
356 384
357 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
358 if (err < 0)
359 goto out_no_path;
360
361 auth = rpcauth_create(args->authflavor, clnt);
362 if (IS_ERR(auth)) {
363 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
364 args->authflavor);
365 err = PTR_ERR(auth);
366 goto out_no_auth;
367 }
368
369 /* save the nodename */ 385 /* save the nodename */
370 rpc_clnt_set_nodename(clnt, utsname()->nodename); 386 rpc_clnt_set_nodename(clnt, utsname()->nodename);
371 rpc_register_client(clnt); 387
388 err = rpc_client_register(args, clnt);
389 if (err)
390 goto out_no_path;
372 return clnt; 391 return clnt;
373 392
374out_no_auth:
375 rpc_clnt_remove_pipedir(clnt);
376out_no_path: 393out_no_path:
377 kfree(clnt->cl_principal); 394 kfree(clnt->cl_principal);
378out_no_principal: 395out_no_principal:
@@ -637,8 +654,8 @@ rpc_free_client(struct rpc_clnt *clnt)
637 rcu_dereference(clnt->cl_xprt)->servername); 654 rcu_dereference(clnt->cl_xprt)->servername);
638 if (clnt->cl_parent != clnt) 655 if (clnt->cl_parent != clnt)
639 rpc_release_client(clnt->cl_parent); 656 rpc_release_client(clnt->cl_parent);
640 rpc_unregister_client(clnt);
641 rpc_clnt_remove_pipedir(clnt); 657 rpc_clnt_remove_pipedir(clnt);
658 rpc_unregister_client(clnt);
642 rpc_free_iostats(clnt->cl_metrics); 659 rpc_free_iostats(clnt->cl_metrics);
643 kfree(clnt->cl_principal); 660 kfree(clnt->cl_principal);
644 clnt->cl_metrics = NULL; 661 clnt->cl_metrics = NULL;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e7ce4b3eb0bd..4679df5a6d50 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -667,7 +667,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
667 return ERR_PTR(-ENOMEM); 667 return ERR_PTR(-ENOMEM);
668 } 668 }
669 if (dentry->d_inode == NULL) { 669 if (dentry->d_inode == NULL) {
670 d_set_d_op(dentry, &rpc_dentry_operations); 670 if (!dentry->d_op)
671 d_set_d_op(dentry, &rpc_dentry_operations);
671 return dentry; 672 return dentry;
672 } 673 }
673 dput(dentry); 674 dput(dentry);
@@ -1126,6 +1127,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
1126 return -ENOMEM; 1127 return -ENOMEM;
1127 dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", 1128 dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n",
1128 net, NET_NAME(net)); 1129 net, NET_NAME(net));
1130 mutex_lock(&sn->pipefs_sb_lock);
1129 sn->pipefs_sb = sb; 1131 sn->pipefs_sb = sb;
1130 err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, 1132 err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
1131 RPC_PIPEFS_MOUNT, 1133 RPC_PIPEFS_MOUNT,
@@ -1133,6 +1135,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
1133 if (err) 1135 if (err)
1134 goto err_depopulate; 1136 goto err_depopulate;
1135 sb->s_fs_info = get_net(net); 1137 sb->s_fs_info = get_net(net);
1138 mutex_unlock(&sn->pipefs_sb_lock);
1136 return 0; 1139 return 0;
1137 1140
1138err_depopulate: 1141err_depopulate:
@@ -1141,6 +1144,7 @@ err_depopulate:
1141 sb); 1144 sb);
1142 sn->pipefs_sb = NULL; 1145 sn->pipefs_sb = NULL;
1143 __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); 1146 __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
1147 mutex_unlock(&sn->pipefs_sb_lock);
1144 return err; 1148 return err;
1145} 1149}
1146 1150
@@ -1162,12 +1166,12 @@ static void rpc_kill_sb(struct super_block *sb)
1162 goto out; 1166 goto out;
1163 } 1167 }
1164 sn->pipefs_sb = NULL; 1168 sn->pipefs_sb = NULL;
1165 mutex_unlock(&sn->pipefs_sb_lock);
1166 dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", 1169 dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
1167 net, NET_NAME(net)); 1170 net, NET_NAME(net));
1168 blocking_notifier_call_chain(&rpc_pipefs_notifier_list, 1171 blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
1169 RPC_PIPEFS_UMOUNT, 1172 RPC_PIPEFS_UMOUNT,
1170 sb); 1173 sb);
1174 mutex_unlock(&sn->pipefs_sb_lock);
1171 put_net(net); 1175 put_net(net);
1172out: 1176out:
1173 kill_litter_super(sb); 1177 kill_litter_super(sb);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 77d251e02593..93a7a4e94d80 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -446,20 +446,6 @@ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct r
446} 446}
447 447
448/* 448/*
449 * Tests whether rpc queue is empty
450 */
451int rpc_queue_empty(struct rpc_wait_queue *queue)
452{
453 int res;
454
455 spin_lock_bh(&queue->lock);
456 res = queue->qlen;
457 spin_unlock_bh(&queue->lock);
458 return res == 0;
459}
460EXPORT_SYMBOL_GPL(rpc_queue_empty);
461
462/*
463 * Wake up a task on a specific queue 449 * Wake up a task on a specific queue
464 */ 450 */
465void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) 451void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task)
@@ -804,7 +790,6 @@ static void __rpc_execute(struct rpc_task *task)
804 task->tk_flags |= RPC_TASK_KILLED; 790 task->tk_flags |= RPC_TASK_KILLED;
805 rpc_exit(task, -ERESTARTSYS); 791 rpc_exit(task, -ERESTARTSYS);
806 } 792 }
807 rpc_set_running(task);
808 dprintk("RPC: %5u sync task resuming\n", task->tk_pid); 793 dprintk("RPC: %5u sync task resuming\n", task->tk_pid);
809 } 794 }
810 795
@@ -825,9 +810,11 @@ static void __rpc_execute(struct rpc_task *task)
825 */ 810 */
826void rpc_execute(struct rpc_task *task) 811void rpc_execute(struct rpc_task *task)
827{ 812{
813 bool is_async = RPC_IS_ASYNC(task);
814
828 rpc_set_active(task); 815 rpc_set_active(task);
829 rpc_make_runnable(task); 816 rpc_make_runnable(task);
830 if (!RPC_IS_ASYNC(task)) 817 if (!is_async)
831 __rpc_execute(task); 818 __rpc_execute(task);
832} 819}
833 820