aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/nfs/super.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c1480
1 files changed, 906 insertions, 574 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2e7e8c878e5..c4daf4eaad9 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -41,6 +41,7 @@
41#include <linux/lockd/bind.h> 41#include <linux/lockd/bind.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/mount.h> 43#include <linux/mount.h>
44#include <linux/mnt_namespace.h>
44#include <linux/namei.h> 45#include <linux/namei.h>
45#include <linux/nfs_idmap.h> 46#include <linux/nfs_idmap.h>
46#include <linux/vfs.h> 47#include <linux/vfs.h>
@@ -52,10 +53,8 @@
52#include <linux/nfs_xdr.h> 53#include <linux/nfs_xdr.h>
53#include <linux/magic.h> 54#include <linux/magic.h>
54#include <linux/parser.h> 55#include <linux/parser.h>
55#include <linux/nsproxy.h>
56#include <linux/rcupdate.h>
57#include <linux/kthread.h>
58 56
57#include <asm/system.h>
59#include <asm/uaccess.h> 58#include <asm/uaccess.h>
60 59
61#include "nfs4_fs.h" 60#include "nfs4_fs.h"
@@ -64,14 +63,11 @@
64#include "iostat.h" 63#include "iostat.h"
65#include "internal.h" 64#include "internal.h"
66#include "fscache.h" 65#include "fscache.h"
67#include "nfs4session.h"
68#include "pnfs.h" 66#include "pnfs.h"
69#include "nfs.h"
70 67
71#define NFSDBG_FACILITY NFSDBG_VFS 68#define NFSDBG_FACILITY NFSDBG_VFS
72#define NFS_TEXT_DATA 1
73 69
74#if IS_ENABLED(CONFIG_NFS_V3) 70#ifdef CONFIG_NFS_V3
75#define NFS_DEFAULT_VERSION 3 71#define NFS_DEFAULT_VERSION 3
76#else 72#else
77#define NFS_DEFAULT_VERSION 2 73#define NFS_DEFAULT_VERSION 2
@@ -84,13 +80,13 @@ enum {
84 Opt_cto, Opt_nocto, 80 Opt_cto, Opt_nocto,
85 Opt_ac, Opt_noac, 81 Opt_ac, Opt_noac,
86 Opt_lock, Opt_nolock, 82 Opt_lock, Opt_nolock,
83 Opt_v2, Opt_v3, Opt_v4,
87 Opt_udp, Opt_tcp, Opt_rdma, 84 Opt_udp, Opt_tcp, Opt_rdma,
88 Opt_acl, Opt_noacl, 85 Opt_acl, Opt_noacl,
89 Opt_rdirplus, Opt_nordirplus, 86 Opt_rdirplus, Opt_nordirplus,
90 Opt_sharecache, Opt_nosharecache, 87 Opt_sharecache, Opt_nosharecache,
91 Opt_resvport, Opt_noresvport, 88 Opt_resvport, Opt_noresvport,
92 Opt_fscache, Opt_nofscache, 89 Opt_fscache, Opt_nofscache,
93 Opt_migration, Opt_nomigration,
94 90
95 /* Mount options that take integer arguments */ 91 /* Mount options that take integer arguments */
96 Opt_port, 92 Opt_port,
@@ -102,10 +98,10 @@ enum {
102 Opt_namelen, 98 Opt_namelen,
103 Opt_mountport, 99 Opt_mountport,
104 Opt_mountvers, 100 Opt_mountvers,
101 Opt_nfsvers,
105 Opt_minorversion, 102 Opt_minorversion,
106 103
107 /* Mount options that take string arguments */ 104 /* Mount options that take string arguments */
108 Opt_nfsvers,
109 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, 105 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
110 Opt_addr, Opt_mountaddr, Opt_clientaddr, 106 Opt_addr, Opt_mountaddr, Opt_clientaddr,
111 Opt_lookupcache, 107 Opt_lookupcache,
@@ -137,6 +133,9 @@ static const match_table_t nfs_mount_option_tokens = {
137 { Opt_noac, "noac" }, 133 { Opt_noac, "noac" },
138 { Opt_lock, "lock" }, 134 { Opt_lock, "lock" },
139 { Opt_nolock, "nolock" }, 135 { Opt_nolock, "nolock" },
136 { Opt_v2, "v2" },
137 { Opt_v3, "v3" },
138 { Opt_v4, "v4" },
140 { Opt_udp, "udp" }, 139 { Opt_udp, "udp" },
141 { Opt_tcp, "tcp" }, 140 { Opt_tcp, "tcp" },
142 { Opt_rdma, "rdma" }, 141 { Opt_rdma, "rdma" },
@@ -150,8 +149,6 @@ static const match_table_t nfs_mount_option_tokens = {
150 { Opt_noresvport, "noresvport" }, 149 { Opt_noresvport, "noresvport" },
151 { Opt_fscache, "fsc" }, 150 { Opt_fscache, "fsc" },
152 { Opt_nofscache, "nofsc" }, 151 { Opt_nofscache, "nofsc" },
153 { Opt_migration, "migration" },
154 { Opt_nomigration, "nomigration" },
155 152
156 { Opt_port, "port=%s" }, 153 { Opt_port, "port=%s" },
157 { Opt_rsize, "rsize=%s" }, 154 { Opt_rsize, "rsize=%s" },
@@ -167,10 +164,9 @@ static const match_table_t nfs_mount_option_tokens = {
167 { Opt_namelen, "namlen=%s" }, 164 { Opt_namelen, "namlen=%s" },
168 { Opt_mountport, "mountport=%s" }, 165 { Opt_mountport, "mountport=%s" },
169 { Opt_mountvers, "mountvers=%s" }, 166 { Opt_mountvers, "mountvers=%s" },
170 { Opt_minorversion, "minorversion=%s" },
171
172 { Opt_nfsvers, "nfsvers=%s" }, 167 { Opt_nfsvers, "nfsvers=%s" },
173 { Opt_nfsvers, "vers=%s" }, 168 { Opt_nfsvers, "vers=%s" },
169 { Opt_minorversion, "minorversion=%s" },
174 170
175 { Opt_sec, "sec=%s" }, 171 { Opt_sec, "sec=%s" },
176 { Opt_proto, "proto=%s" }, 172 { Opt_proto, "proto=%s" },
@@ -184,9 +180,6 @@ static const match_table_t nfs_mount_option_tokens = {
184 { Opt_fscache_uniq, "fsc=%s" }, 180 { Opt_fscache_uniq, "fsc=%s" },
185 { Opt_local_lock, "local_lock=%s" }, 181 { Opt_local_lock, "local_lock=%s" },
186 182
187 /* The following needs to be listed after all other options */
188 { Opt_nfsvers, "v%s" },
189
190 { Opt_err, NULL } 183 { Opt_err, NULL }
191}; 184};
192 185
@@ -267,34 +260,28 @@ static match_table_t nfs_local_lock_tokens = {
267 { Opt_local_lock_err, NULL } 260 { Opt_local_lock_err, NULL }
268}; 261};
269 262
270enum {
271 Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0,
272 Opt_vers_4_1,
273
274 Opt_vers_err
275};
276
277static match_table_t nfs_vers_tokens = {
278 { Opt_vers_2, "2" },
279 { Opt_vers_3, "3" },
280 { Opt_vers_4, "4" },
281 { Opt_vers_4_0, "4.0" },
282 { Opt_vers_4_1, "4.1" },
283
284 { Opt_vers_err, NULL }
285};
286 263
264static void nfs_umount_begin(struct super_block *);
265static int nfs_statfs(struct dentry *, struct kstatfs *);
266static int nfs_show_options(struct seq_file *, struct vfsmount *);
267static int nfs_show_devname(struct seq_file *, struct vfsmount *);
268static int nfs_show_path(struct seq_file *, struct vfsmount *);
269static int nfs_show_stats(struct seq_file *, struct vfsmount *);
270static struct dentry *nfs_fs_mount(struct file_system_type *,
271 int, const char *, void *);
287static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, 272static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
288 int flags, const char *dev_name, void *raw_data); 273 int flags, const char *dev_name, void *raw_data);
274static void nfs_put_super(struct super_block *);
275static void nfs_kill_super(struct super_block *);
276static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
289 277
290struct file_system_type nfs_fs_type = { 278static struct file_system_type nfs_fs_type = {
291 .owner = THIS_MODULE, 279 .owner = THIS_MODULE,
292 .name = "nfs", 280 .name = "nfs",
293 .mount = nfs_fs_mount, 281 .mount = nfs_fs_mount,
294 .kill_sb = nfs_kill_super, 282 .kill_sb = nfs_kill_super,
295 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 283 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
296}; 284};
297EXPORT_SYMBOL_GPL(nfs_fs_type);
298 285
299struct file_system_type nfs_xdev_fs_type = { 286struct file_system_type nfs_xdev_fs_type = {
300 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
@@ -304,11 +291,10 @@ struct file_system_type nfs_xdev_fs_type = {
304 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 291 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
305}; 292};
306 293
307const struct super_operations nfs_sops = { 294static const struct super_operations nfs_sops = {
308 .alloc_inode = nfs_alloc_inode, 295 .alloc_inode = nfs_alloc_inode,
309 .destroy_inode = nfs_destroy_inode, 296 .destroy_inode = nfs_destroy_inode,
310 .write_inode = nfs_write_inode, 297 .write_inode = nfs_write_inode,
311 .drop_inode = nfs_drop_inode,
312 .put_super = nfs_put_super, 298 .put_super = nfs_put_super,
313 .statfs = nfs_statfs, 299 .statfs = nfs_statfs,
314 .evict_inode = nfs_evict_inode, 300 .evict_inode = nfs_evict_inode,
@@ -319,40 +305,78 @@ const struct super_operations nfs_sops = {
319 .show_stats = nfs_show_stats, 305 .show_stats = nfs_show_stats,
320 .remount_fs = nfs_remount, 306 .remount_fs = nfs_remount,
321}; 307};
322EXPORT_SYMBOL_GPL(nfs_sops);
323 308
324#if IS_ENABLED(CONFIG_NFS_V4) 309#ifdef CONFIG_NFS_V4
325static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); 310static int nfs4_validate_text_mount_data(void *options,
326static int nfs4_validate_mount_data(void *options,
327 struct nfs_parsed_mount_data *args, const char *dev_name); 311 struct nfs_parsed_mount_data *args, const char *dev_name);
312static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
313 struct nfs_parsed_mount_data *data);
314static struct dentry *nfs4_mount(struct file_system_type *fs_type,
315 int flags, const char *dev_name, void *raw_data);
316static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
317 int flags, const char *dev_name, void *raw_data);
318static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
319 int flags, const char *dev_name, void *raw_data);
320static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
321 int flags, const char *dev_name, void *raw_data);
322static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
323 int flags, const char *dev_name, void *raw_data);
324static void nfs4_kill_super(struct super_block *sb);
325
326static struct file_system_type nfs4_fs_type = {
327 .owner = THIS_MODULE,
328 .name = "nfs4",
329 .mount = nfs4_mount,
330 .kill_sb = nfs4_kill_super,
331 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
332};
328 333
329struct file_system_type nfs4_fs_type = { 334static struct file_system_type nfs4_remote_fs_type = {
330 .owner = THIS_MODULE, 335 .owner = THIS_MODULE,
331 .name = "nfs4", 336 .name = "nfs4",
332 .mount = nfs_fs_mount, 337 .mount = nfs4_remote_mount,
333 .kill_sb = nfs_kill_super, 338 .kill_sb = nfs4_kill_super,
334 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 339 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
335}; 340};
336EXPORT_SYMBOL_GPL(nfs4_fs_type);
337 341
338static int __init register_nfs4_fs(void) 342struct file_system_type nfs4_xdev_fs_type = {
339{ 343 .owner = THIS_MODULE,
340 return register_filesystem(&nfs4_fs_type); 344 .name = "nfs4",
341} 345 .mount = nfs4_xdev_mount,
346 .kill_sb = nfs4_kill_super,
347 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
348};
342 349
343static void unregister_nfs4_fs(void) 350static struct file_system_type nfs4_remote_referral_fs_type = {
344{ 351 .owner = THIS_MODULE,
345 unregister_filesystem(&nfs4_fs_type); 352 .name = "nfs4",
346} 353 .mount = nfs4_remote_referral_mount,
347#else 354 .kill_sb = nfs4_kill_super,
348static int __init register_nfs4_fs(void) 355 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
349{ 356};
350 return 0;
351}
352 357
353static void unregister_nfs4_fs(void) 358struct file_system_type nfs4_referral_fs_type = {
354{ 359 .owner = THIS_MODULE,
355} 360 .name = "nfs4",
361 .mount = nfs4_referral_mount,
362 .kill_sb = nfs4_kill_super,
363 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
364};
365
366static const struct super_operations nfs4_sops = {
367 .alloc_inode = nfs_alloc_inode,
368 .destroy_inode = nfs_destroy_inode,
369 .write_inode = nfs_write_inode,
370 .put_super = nfs_put_super,
371 .statfs = nfs_statfs,
372 .evict_inode = nfs4_evict_inode,
373 .umount_begin = nfs_umount_begin,
374 .show_options = nfs_show_options,
375 .show_devname = nfs_show_devname,
376 .show_path = nfs_show_path,
377 .show_stats = nfs_show_stats,
378 .remount_fs = nfs_remount,
379};
356#endif 380#endif
357 381
358static struct shrinker acl_shrinker = { 382static struct shrinker acl_shrinker = {
@@ -371,18 +395,21 @@ int __init register_nfs_fs(void)
371 if (ret < 0) 395 if (ret < 0)
372 goto error_0; 396 goto error_0;
373 397
374 ret = register_nfs4_fs(); 398 ret = nfs_register_sysctl();
375 if (ret < 0) 399 if (ret < 0)
376 goto error_1; 400 goto error_1;
377 401#ifdef CONFIG_NFS_V4
378 ret = nfs_register_sysctl(); 402 ret = register_filesystem(&nfs4_fs_type);
379 if (ret < 0) 403 if (ret < 0)
380 goto error_2; 404 goto error_2;
405#endif
381 register_shrinker(&acl_shrinker); 406 register_shrinker(&acl_shrinker);
382 return 0; 407 return 0;
383 408
409#ifdef CONFIG_NFS_V4
384error_2: 410error_2:
385 unregister_nfs4_fs(); 411 nfs_unregister_sysctl();
412#endif
386error_1: 413error_1:
387 unregister_filesystem(&nfs_fs_type); 414 unregister_filesystem(&nfs_fs_type);
388error_0: 415error_0:
@@ -395,8 +422,10 @@ error_0:
395void __exit unregister_nfs_fs(void) 422void __exit unregister_nfs_fs(void)
396{ 423{
397 unregister_shrinker(&acl_shrinker); 424 unregister_shrinker(&acl_shrinker);
425#ifdef CONFIG_NFS_V4
426 unregister_filesystem(&nfs4_fs_type);
427#endif
398 nfs_unregister_sysctl(); 428 nfs_unregister_sysctl();
399 unregister_nfs4_fs();
400 unregister_filesystem(&nfs_fs_type); 429 unregister_filesystem(&nfs_fs_type);
401} 430}
402 431
@@ -407,7 +436,6 @@ void nfs_sb_active(struct super_block *sb)
407 if (atomic_inc_return(&server->active) == 1) 436 if (atomic_inc_return(&server->active) == 1)
408 atomic_inc(&sb->s_active); 437 atomic_inc(&sb->s_active);
409} 438}
410EXPORT_SYMBOL_GPL(nfs_sb_active);
411 439
412void nfs_sb_deactive(struct super_block *sb) 440void nfs_sb_deactive(struct super_block *sb)
413{ 441{
@@ -416,60 +444,11 @@ void nfs_sb_deactive(struct super_block *sb)
416 if (atomic_dec_and_test(&server->active)) 444 if (atomic_dec_and_test(&server->active))
417 deactivate_super(sb); 445 deactivate_super(sb);
418} 446}
419EXPORT_SYMBOL_GPL(nfs_sb_deactive);
420
421static int nfs_deactivate_super_async_work(void *ptr)
422{
423 struct super_block *sb = ptr;
424
425 deactivate_super(sb);
426 module_put_and_exit(0);
427 return 0;
428}
429
430/*
431 * same effect as deactivate_super, but will do final unmount in kthread
432 * context
433 */
434static void nfs_deactivate_super_async(struct super_block *sb)
435{
436 struct task_struct *task;
437 char buf[INET6_ADDRSTRLEN + 1];
438 struct nfs_server *server = NFS_SB(sb);
439 struct nfs_client *clp = server->nfs_client;
440
441 if (!atomic_add_unless(&sb->s_active, -1, 1)) {
442 rcu_read_lock();
443 snprintf(buf, sizeof(buf),
444 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));
445 rcu_read_unlock();
446
447 __module_get(THIS_MODULE);
448 task = kthread_run(nfs_deactivate_super_async_work, sb,
449 "%s-deactivate-super", buf);
450 if (IS_ERR(task)) {
451 pr_err("%s: kthread_run: %ld\n",
452 __func__, PTR_ERR(task));
453 /* make synchronous call and hope for the best */
454 deactivate_super(sb);
455 module_put(THIS_MODULE);
456 }
457 }
458}
459
460void nfs_sb_deactive_async(struct super_block *sb)
461{
462 struct nfs_server *server = NFS_SB(sb);
463
464 if (atomic_dec_and_test(&server->active))
465 nfs_deactivate_super_async(sb);
466}
467EXPORT_SYMBOL_GPL(nfs_sb_deactive_async);
468 447
469/* 448/*
470 * Deliver file system statistics to userspace 449 * Deliver file system statistics to userspace
471 */ 450 */
472int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) 451static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
473{ 452{
474 struct nfs_server *server = NFS_SB(dentry->d_sb); 453 struct nfs_server *server = NFS_SB(dentry->d_sb);
475 unsigned char blockbits; 454 unsigned char blockbits;
@@ -530,7 +509,6 @@ int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
530 dprintk("%s: statfs error = %d\n", __func__, -error); 509 dprintk("%s: statfs error = %d\n", __func__, -error);
531 return error; 510 return error;
532} 511}
533EXPORT_SYMBOL_GPL(nfs_statfs);
534 512
535/* 513/*
536 * Map the security flavour number to a name 514 * Map the security flavour number to a name
@@ -636,13 +614,14 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
636 nfs_show_mountd_netid(m, nfss, showdefaults); 614 nfs_show_mountd_netid(m, nfss, showdefaults);
637} 615}
638 616
639#if IS_ENABLED(CONFIG_NFS_V4) 617#ifdef CONFIG_NFS_V4
640static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, 618static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
641 int showdefaults) 619 int showdefaults)
642{ 620{
643 struct nfs_client *clp = nfss->nfs_client; 621 struct nfs_client *clp = nfss->nfs_client;
644 622
645 seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); 623 seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
624 seq_printf(m, ",minorversion=%u", clp->cl_minorversion);
646} 625}
647#else 626#else
648static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, 627static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
@@ -651,15 +630,6 @@ static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
651} 630}
652#endif 631#endif
653 632
654static void nfs_show_nfs_version(struct seq_file *m,
655 unsigned int version,
656 unsigned int minorversion)
657{
658 seq_printf(m, ",vers=%u", version);
659 if (version == 4)
660 seq_printf(m, ".%u", minorversion);
661}
662
663/* 633/*
664 * Describe the mount options in force on this server representation 634 * Describe the mount options in force on this server representation
665 */ 635 */
@@ -687,7 +657,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
687 u32 version = clp->rpc_ops->version; 657 u32 version = clp->rpc_ops->version;
688 int local_flock, local_fcntl; 658 int local_flock, local_fcntl;
689 659
690 nfs_show_nfs_version(m, version, clp->cl_minorversion); 660 seq_printf(m, ",vers=%u", version);
691 seq_printf(m, ",rsize=%u", nfss->rsize); 661 seq_printf(m, ",rsize=%u", nfss->rsize);
692 seq_printf(m, ",wsize=%u", nfss->wsize); 662 seq_printf(m, ",wsize=%u", nfss->wsize);
693 if (nfss->bsize != 0) 663 if (nfss->bsize != 0)
@@ -707,10 +677,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
707 else 677 else
708 seq_puts(m, nfs_infop->nostr); 678 seq_puts(m, nfs_infop->nostr);
709 } 679 }
710 rcu_read_lock();
711 seq_printf(m, ",proto=%s", 680 seq_printf(m, ",proto=%s",
712 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID)); 681 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID));
713 rcu_read_unlock();
714 if (version == 4) { 682 if (version == 4) {
715 if (nfss->port != NFS_PORT) 683 if (nfss->port != NFS_PORT)
716 seq_printf(m, ",port=%u", nfss->port); 684 seq_printf(m, ",port=%u", nfss->port);
@@ -730,9 +698,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
730 if (nfss->options & NFS_OPTION_FSCACHE) 698 if (nfss->options & NFS_OPTION_FSCACHE)
731 seq_printf(m, ",fsc"); 699 seq_printf(m, ",fsc");
732 700
733 if (nfss->options & NFS_OPTION_MIGRATION)
734 seq_printf(m, ",migration");
735
736 if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) { 701 if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
737 if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) 702 if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
738 seq_printf(m, ",lookupcache=none"); 703 seq_printf(m, ",lookupcache=none");
@@ -756,36 +721,30 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
756/* 721/*
757 * Describe the mount options on this VFS mountpoint 722 * Describe the mount options on this VFS mountpoint
758 */ 723 */
759int nfs_show_options(struct seq_file *m, struct dentry *root) 724static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
760{ 725{
761 struct nfs_server *nfss = NFS_SB(root->d_sb); 726 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
762 727
763 nfs_show_mount_options(m, nfss, 0); 728 nfs_show_mount_options(m, nfss, 0);
764 729
765 rcu_read_lock();
766 seq_printf(m, ",addr=%s", 730 seq_printf(m, ",addr=%s",
767 rpc_peeraddr2str(nfss->nfs_client->cl_rpcclient, 731 rpc_peeraddr2str(nfss->nfs_client->cl_rpcclient,
768 RPC_DISPLAY_ADDR)); 732 RPC_DISPLAY_ADDR));
769 rcu_read_unlock();
770 733
771 return 0; 734 return 0;
772} 735}
773EXPORT_SYMBOL_GPL(nfs_show_options);
774
775#if IS_ENABLED(CONFIG_NFS_V4)
776#ifdef CONFIG_NFS_V4_1 736#ifdef CONFIG_NFS_V4_1
777static void show_sessions(struct seq_file *m, struct nfs_server *server) 737void show_sessions(struct seq_file *m, struct nfs_server *server)
778{ 738{
779 if (nfs4_has_session(server->nfs_client)) 739 if (nfs4_has_session(server->nfs_client))
780 seq_printf(m, ",sessions"); 740 seq_printf(m, ",sessions");
781} 741}
782#else 742#else
783static void show_sessions(struct seq_file *m, struct nfs_server *server) {} 743void show_sessions(struct seq_file *m, struct nfs_server *server) {}
784#endif
785#endif 744#endif
786 745
787#ifdef CONFIG_NFS_V4_1 746#ifdef CONFIG_NFS_V4_1
788static void show_pnfs(struct seq_file *m, struct nfs_server *server) 747void show_pnfs(struct seq_file *m, struct nfs_server *server)
789{ 748{
790 seq_printf(m, ",pnfs="); 749 seq_printf(m, ",pnfs=");
791 if (server->pnfs_curr_ld) 750 if (server->pnfs_curr_ld)
@@ -793,36 +752,18 @@ static void show_pnfs(struct seq_file *m, struct nfs_server *server)
793 else 752 else
794 seq_printf(m, "not configured"); 753 seq_printf(m, "not configured");
795} 754}
755#else /* CONFIG_NFS_V4_1 */
756void show_pnfs(struct seq_file *m, struct nfs_server *server) {}
757#endif /* CONFIG_NFS_V4_1 */
796 758
797static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss) 759static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt)
798{
799 if (nfss->nfs_client && nfss->nfs_client->cl_implid) {
800 struct nfs41_impl_id *impl_id = nfss->nfs_client->cl_implid;
801 seq_printf(m, "\n\timpl_id:\tname='%s',domain='%s',"
802 "date='%llu,%u'",
803 impl_id->name, impl_id->domain,
804 impl_id->date.seconds, impl_id->date.nseconds);
805 }
806}
807#else
808#if IS_ENABLED(CONFIG_NFS_V4)
809static void show_pnfs(struct seq_file *m, struct nfs_server *server)
810{
811}
812#endif
813static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
814{
815}
816#endif
817
818int nfs_show_devname(struct seq_file *m, struct dentry *root)
819{ 760{
820 char *page = (char *) __get_free_page(GFP_KERNEL); 761 char *page = (char *) __get_free_page(GFP_KERNEL);
821 char *devname, *dummy; 762 char *devname, *dummy;
822 int err = 0; 763 int err = 0;
823 if (!page) 764 if (!page)
824 return -ENOMEM; 765 return -ENOMEM;
825 devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); 766 devname = nfs_path(&dummy, mnt->mnt_root, page, PAGE_SIZE);
826 if (IS_ERR(devname)) 767 if (IS_ERR(devname))
827 err = PTR_ERR(devname); 768 err = PTR_ERR(devname);
828 else 769 else
@@ -830,22 +771,20 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
830 free_page((unsigned long)page); 771 free_page((unsigned long)page);
831 return err; 772 return err;
832} 773}
833EXPORT_SYMBOL_GPL(nfs_show_devname);
834 774
835int nfs_show_path(struct seq_file *m, struct dentry *dentry) 775static int nfs_show_path(struct seq_file *m, struct vfsmount *mnt)
836{ 776{
837 seq_puts(m, "/"); 777 seq_puts(m, "/");
838 return 0; 778 return 0;
839} 779}
840EXPORT_SYMBOL_GPL(nfs_show_path);
841 780
842/* 781/*
843 * Present statistical information for this VFS mountpoint 782 * Present statistical information for this VFS mountpoint
844 */ 783 */
845int nfs_show_stats(struct seq_file *m, struct dentry *root) 784static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
846{ 785{
847 int i, cpu; 786 int i, cpu;
848 struct nfs_server *nfss = NFS_SB(root->d_sb); 787 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
849 struct rpc_auth *auth = nfss->client->cl_auth; 788 struct rpc_auth *auth = nfss->client->cl_auth;
850 struct nfs_iostats totals = { }; 789 struct nfs_iostats totals = { };
851 790
@@ -855,16 +794,14 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
855 * Display all mount option settings 794 * Display all mount option settings
856 */ 795 */
857 seq_printf(m, "\n\topts:\t"); 796 seq_printf(m, "\n\topts:\t");
858 seq_puts(m, root->d_sb->s_flags & MS_RDONLY ? "ro" : "rw"); 797 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
859 seq_puts(m, root->d_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : ""); 798 seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
860 seq_puts(m, root->d_sb->s_flags & MS_NOATIME ? ",noatime" : ""); 799 seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
861 seq_puts(m, root->d_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : ""); 800 seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
862 nfs_show_mount_options(m, nfss, 1); 801 nfs_show_mount_options(m, nfss, 1);
863 802
864 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ); 803 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
865 804
866 show_implementation_id(m, nfss);
867
868 seq_printf(m, "\n\tcaps:\t"); 805 seq_printf(m, "\n\tcaps:\t");
869 seq_printf(m, "caps=0x%x", nfss->caps); 806 seq_printf(m, "caps=0x%x", nfss->caps);
870 seq_printf(m, ",wtmult=%u", nfss->wtmult); 807 seq_printf(m, ",wtmult=%u", nfss->wtmult);
@@ -872,7 +809,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
872 seq_printf(m, ",bsize=%u", nfss->bsize); 809 seq_printf(m, ",bsize=%u", nfss->bsize);
873 seq_printf(m, ",namlen=%u", nfss->namelen); 810 seq_printf(m, ",namlen=%u", nfss->namelen);
874 811
875#if IS_ENABLED(CONFIG_NFS_V4) 812#ifdef CONFIG_NFS_V4
876 if (nfss->nfs_client->rpc_ops->version == 4) { 813 if (nfss->nfs_client->rpc_ops->version == 4) {
877 seq_printf(m, "\n\tnfsv4:\t"); 814 seq_printf(m, "\n\tnfsv4:\t");
878 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); 815 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
@@ -930,13 +867,12 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
930 867
931 return 0; 868 return 0;
932} 869}
933EXPORT_SYMBOL_GPL(nfs_show_stats);
934 870
935/* 871/*
936 * Begin unmount by attempting to remove all automounted mountpoints we added 872 * Begin unmount by attempting to remove all automounted mountpoints we added
937 * in response to xdev traversals and referrals 873 * in response to xdev traversals and referrals
938 */ 874 */
939void nfs_umount_begin(struct super_block *sb) 875static void nfs_umount_begin(struct super_block *sb)
940{ 876{
941 struct nfs_server *server; 877 struct nfs_server *server;
942 struct rpc_clnt *rpc; 878 struct rpc_clnt *rpc;
@@ -950,9 +886,8 @@ void nfs_umount_begin(struct super_block *sb)
950 if (!IS_ERR(rpc)) 886 if (!IS_ERR(rpc))
951 rpc_killall_tasks(rpc); 887 rpc_killall_tasks(rpc);
952} 888}
953EXPORT_SYMBOL_GPL(nfs_umount_begin);
954 889
955static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) 890static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
956{ 891{
957 struct nfs_parsed_mount_data *data; 892 struct nfs_parsed_mount_data *data;
958 893
@@ -967,9 +902,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
967 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 902 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
968 data->auth_flavors[0] = RPC_AUTH_UNIX; 903 data->auth_flavors[0] = RPC_AUTH_UNIX;
969 data->auth_flavor_len = 1; 904 data->auth_flavor_len = 1;
905 data->version = version;
970 data->minorversion = 0; 906 data->minorversion = 0;
971 data->need_mount = true;
972 data->net = current->nsproxy->net_ns;
973 security_init_mnt_opts(&data->lsm_opts); 907 security_init_mnt_opts(&data->lsm_opts);
974 } 908 }
975 return data; 909 return data;
@@ -1114,45 +1048,11 @@ static int nfs_parse_security_flavors(char *value,
1114 return 1; 1048 return 1;
1115} 1049}
1116 1050
1117static int nfs_parse_version_string(char *string,
1118 struct nfs_parsed_mount_data *mnt,
1119 substring_t *args)
1120{
1121 mnt->flags &= ~NFS_MOUNT_VER3;
1122 switch (match_token(string, nfs_vers_tokens, args)) {
1123 case Opt_vers_2:
1124 mnt->version = 2;
1125 break;
1126 case Opt_vers_3:
1127 mnt->flags |= NFS_MOUNT_VER3;
1128 mnt->version = 3;
1129 break;
1130 case Opt_vers_4:
1131 /* Backward compatibility option. In future,
1132 * the mount program should always supply
1133 * a NFSv4 minor version number.
1134 */
1135 mnt->version = 4;
1136 break;
1137 case Opt_vers_4_0:
1138 mnt->version = 4;
1139 mnt->minorversion = 0;
1140 break;
1141 case Opt_vers_4_1:
1142 mnt->version = 4;
1143 mnt->minorversion = 1;
1144 break;
1145 default:
1146 return 0;
1147 }
1148 return 1;
1149}
1150
1151static int nfs_get_option_str(substring_t args[], char **option) 1051static int nfs_get_option_str(substring_t args[], char **option)
1152{ 1052{
1153 kfree(*option); 1053 kfree(*option);
1154 *option = match_strdup(args); 1054 *option = match_strdup(args);
1155 return !*option; 1055 return !option;
1156} 1056}
1157 1057
1158static int nfs_get_option_ul(substring_t args[], unsigned long *option) 1058static int nfs_get_option_ul(substring_t args[], unsigned long *option)
@@ -1163,7 +1063,7 @@ static int nfs_get_option_ul(substring_t args[], unsigned long *option)
1163 string = match_strdup(args); 1063 string = match_strdup(args);
1164 if (string == NULL) 1064 if (string == NULL)
1165 return -ENOMEM; 1065 return -ENOMEM;
1166 rc = kstrtoul(string, 10, option); 1066 rc = strict_strtoul(string, 10, option);
1167 kfree(string); 1067 kfree(string);
1168 1068
1169 return rc; 1069 return rc;
@@ -1253,6 +1153,18 @@ static int nfs_parse_mount_options(char *raw,
1253 mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | 1153 mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK |
1254 NFS_MOUNT_LOCAL_FCNTL); 1154 NFS_MOUNT_LOCAL_FCNTL);
1255 break; 1155 break;
1156 case Opt_v2:
1157 mnt->flags &= ~NFS_MOUNT_VER3;
1158 mnt->version = 2;
1159 break;
1160 case Opt_v3:
1161 mnt->flags |= NFS_MOUNT_VER3;
1162 mnt->version = 3;
1163 break;
1164 case Opt_v4:
1165 mnt->flags &= ~NFS_MOUNT_VER3;
1166 mnt->version = 4;
1167 break;
1256 case Opt_udp: 1168 case Opt_udp:
1257 mnt->flags &= ~NFS_MOUNT_TCP; 1169 mnt->flags &= ~NFS_MOUNT_TCP;
1258 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1170 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1300,12 +1212,6 @@ static int nfs_parse_mount_options(char *raw,
1300 kfree(mnt->fscache_uniq); 1212 kfree(mnt->fscache_uniq);
1301 mnt->fscache_uniq = NULL; 1213 mnt->fscache_uniq = NULL;
1302 break; 1214 break;
1303 case Opt_migration:
1304 mnt->options |= NFS_OPTION_MIGRATION;
1305 break;
1306 case Opt_nomigration:
1307 mnt->options &= NFS_OPTION_MIGRATION;
1308 break;
1309 1215
1310 /* 1216 /*
1311 * options that take numeric values 1217 * options that take numeric values
@@ -1385,6 +1291,26 @@ static int nfs_parse_mount_options(char *raw,
1385 goto out_invalid_value; 1291 goto out_invalid_value;
1386 mnt->mount_server.version = option; 1292 mnt->mount_server.version = option;
1387 break; 1293 break;
1294 case Opt_nfsvers:
1295 if (nfs_get_option_ul(args, &option))
1296 goto out_invalid_value;
1297 switch (option) {
1298 case NFS2_VERSION:
1299 mnt->flags &= ~NFS_MOUNT_VER3;
1300 mnt->version = 2;
1301 break;
1302 case NFS3_VERSION:
1303 mnt->flags |= NFS_MOUNT_VER3;
1304 mnt->version = 3;
1305 break;
1306 case NFS4_VERSION:
1307 mnt->flags &= ~NFS_MOUNT_VER3;
1308 mnt->version = 4;
1309 break;
1310 default:
1311 goto out_invalid_value;
1312 }
1313 break;
1388 case Opt_minorversion: 1314 case Opt_minorversion:
1389 if (nfs_get_option_ul(args, &option)) 1315 if (nfs_get_option_ul(args, &option))
1390 goto out_invalid_value; 1316 goto out_invalid_value;
@@ -1396,15 +1322,6 @@ static int nfs_parse_mount_options(char *raw,
1396 /* 1322 /*
1397 * options that take text values 1323 * options that take text values
1398 */ 1324 */
1399 case Opt_nfsvers:
1400 string = match_strdup(args);
1401 if (string == NULL)
1402 goto out_nomem;
1403 rc = nfs_parse_version_string(string, mnt, args);
1404 kfree(string);
1405 if (!rc)
1406 goto out_invalid_value;
1407 break;
1408 case Opt_sec: 1325 case Opt_sec:
1409 string = match_strdup(args); 1326 string = match_strdup(args);
1410 if (string == NULL) 1327 if (string == NULL)
@@ -1484,7 +1401,7 @@ static int nfs_parse_mount_options(char *raw,
1484 if (string == NULL) 1401 if (string == NULL)
1485 goto out_nomem; 1402 goto out_nomem;
1486 mnt->nfs_server.addrlen = 1403 mnt->nfs_server.addrlen =
1487 rpc_pton(mnt->net, string, strlen(string), 1404 rpc_pton(string, strlen(string),
1488 (struct sockaddr *) 1405 (struct sockaddr *)
1489 &mnt->nfs_server.address, 1406 &mnt->nfs_server.address,
1490 sizeof(mnt->nfs_server.address)); 1407 sizeof(mnt->nfs_server.address));
@@ -1506,7 +1423,7 @@ static int nfs_parse_mount_options(char *raw,
1506 if (string == NULL) 1423 if (string == NULL)
1507 goto out_nomem; 1424 goto out_nomem;
1508 mnt->mount_server.addrlen = 1425 mnt->mount_server.addrlen =
1509 rpc_pton(mnt->net, string, strlen(string), 1426 rpc_pton(string, strlen(string),
1510 (struct sockaddr *) 1427 (struct sockaddr *)
1511 &mnt->mount_server.address, 1428 &mnt->mount_server.address,
1512 sizeof(mnt->mount_server.address)); 1429 sizeof(mnt->mount_server.address));
@@ -1595,16 +1512,9 @@ static int nfs_parse_mount_options(char *raw,
1595 if (!sloppy && invalid_option) 1512 if (!sloppy && invalid_option)
1596 return 0; 1513 return 0;
1597 1514
1598 if (mnt->minorversion && mnt->version != 4)
1599 goto out_minorversion_mismatch;
1600
1601 if (mnt->options & NFS_OPTION_MIGRATION &&
1602 mnt->version != 4 && mnt->minorversion != 0)
1603 goto out_migration_misuse;
1604
1605 /* 1515 /*
1606 * verify that any proto=/mountproto= options match the address 1516 * verify that any proto=/mountproto= options match the address
1607 * families in the addr=/mountaddr= options. 1517 * familiies in the addr=/mountaddr= options.
1608 */ 1518 */
1609 if (protofamily != AF_UNSPEC && 1519 if (protofamily != AF_UNSPEC &&
1610 protofamily != mnt->nfs_server.address.ss_family) 1520 protofamily != mnt->nfs_server.address.ss_family)
@@ -1635,14 +1545,6 @@ out_invalid_address:
1635out_invalid_value: 1545out_invalid_value:
1636 printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p); 1546 printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
1637 return 0; 1547 return 0;
1638out_minorversion_mismatch:
1639 printk(KERN_INFO "NFS: mount option vers=%u does not support "
1640 "minorversion=%u\n", mnt->version, mnt->minorversion);
1641 return 0;
1642out_migration_misuse:
1643 printk(KERN_INFO
1644 "NFS: 'migration' not supported for this NFS version\n");
1645 return 0;
1646out_nomem: 1548out_nomem:
1647 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1549 printk(KERN_INFO "NFS: not enough memory to parse option\n");
1648 return 0; 1550 return 0;
@@ -1702,8 +1604,8 @@ static int nfs_walk_authlist(struct nfs_parsed_mount_data *args,
1702 * Use the remote server's MOUNT service to request the NFS file handle 1604 * Use the remote server's MOUNT service to request the NFS file handle
1703 * corresponding to the provided path. 1605 * corresponding to the provided path.
1704 */ 1606 */
1705static int nfs_request_mount(struct nfs_parsed_mount_data *args, 1607static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1706 struct nfs_fh *root_fh) 1608 struct nfs_fh *root_fh)
1707{ 1609{
1708 rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS]; 1610 rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
1709 unsigned int server_authlist_len = ARRAY_SIZE(server_authlist); 1611 unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
@@ -1716,7 +1618,6 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1716 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1618 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1717 .auth_flav_len = &server_authlist_len, 1619 .auth_flav_len = &server_authlist_len,
1718 .auth_flavs = server_authlist, 1620 .auth_flavs = server_authlist,
1719 .net = args->net,
1720 }; 1621 };
1721 int status; 1622 int status;
1722 1623
@@ -1766,28 +1667,6 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1766 return nfs_walk_authlist(args, &request); 1667 return nfs_walk_authlist(args, &request);
1767} 1668}
1768 1669
1769struct dentry *nfs_try_mount(int flags, const char *dev_name,
1770 struct nfs_mount_info *mount_info,
1771 struct nfs_subversion *nfs_mod)
1772{
1773 int status;
1774 struct nfs_server *server;
1775
1776 if (mount_info->parsed->need_mount) {
1777 status = nfs_request_mount(mount_info->parsed, mount_info->mntfh);
1778 if (status)
1779 return ERR_PTR(status);
1780 }
1781
1782 /* Get a volume representation */
1783 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1784 if (IS_ERR(server))
1785 return ERR_CAST(server);
1786
1787 return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
1788}
1789EXPORT_SYMBOL_GPL(nfs_try_mount);
1790
1791/* 1670/*
1792 * Split "dev_name" into "hostname:export_path". 1671 * Split "dev_name" into "hostname:export_path".
1793 * 1672 *
@@ -1876,10 +1755,10 @@ out_path:
1876 * + breaking back: trying proto=udp after proto=tcp, v2 after v3, 1755 * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
1877 * mountproto=tcp after mountproto=udp, and so on 1756 * mountproto=tcp after mountproto=udp, and so on
1878 */ 1757 */
1879static int nfs23_validate_mount_data(void *options, 1758static int nfs_validate_mount_data(void *options,
1880 struct nfs_parsed_mount_data *args, 1759 struct nfs_parsed_mount_data *args,
1881 struct nfs_fh *mntfh, 1760 struct nfs_fh *mntfh,
1882 const char *dev_name) 1761 const char *dev_name)
1883{ 1762{
1884 struct nfs_mount_data *data = (struct nfs_mount_data *)options; 1763 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1885 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 1764 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
@@ -1887,7 +1766,6 @@ static int nfs23_validate_mount_data(void *options,
1887 if (data == NULL) 1766 if (data == NULL)
1888 goto out_no_data; 1767 goto out_no_data;
1889 1768
1890 args->version = NFS_DEFAULT_VERSION;
1891 switch (data->version) { 1769 switch (data->version) {
1892 case 1: 1770 case 1:
1893 data->namlen = 0; 1771 data->namlen = 0;
@@ -1934,11 +1812,9 @@ static int nfs23_validate_mount_data(void *options,
1934 args->acregmax = data->acregmax; 1812 args->acregmax = data->acregmax;
1935 args->acdirmin = data->acdirmin; 1813 args->acdirmin = data->acdirmin;
1936 args->acdirmax = data->acdirmax; 1814 args->acdirmax = data->acdirmax;
1937 args->need_mount = false;
1938 1815
1939 memcpy(sap, &data->addr, sizeof(data->addr)); 1816 memcpy(sap, &data->addr, sizeof(data->addr));
1940 args->nfs_server.addrlen = sizeof(data->addr); 1817 args->nfs_server.addrlen = sizeof(data->addr);
1941 args->nfs_server.port = ntohs(data->addr.sin_port);
1942 if (!nfs_verify_server_address(sap)) 1818 if (!nfs_verify_server_address(sap))
1943 goto out_no_address; 1819 goto out_no_address;
1944 1820
@@ -1987,11 +1863,46 @@ static int nfs23_validate_mount_data(void *options,
1987 } 1863 }
1988 1864
1989 break; 1865 break;
1990 default: 1866 default: {
1991 return NFS_TEXT_DATA; 1867 int status;
1868
1869 if (nfs_parse_mount_options((char *)options, args) == 0)
1870 return -EINVAL;
1871
1872 if (!nfs_verify_server_address(sap))
1873 goto out_no_address;
1874
1875 if (args->version == 4)
1876#ifdef CONFIG_NFS_V4
1877 return nfs4_validate_text_mount_data(options,
1878 args, dev_name);
1879#else
1880 goto out_v4_not_compiled;
1881#endif
1882
1883 nfs_set_port(sap, &args->nfs_server.port, 0);
1884
1885 nfs_set_mount_transport_protocol(args);
1886
1887 status = nfs_parse_devname(dev_name,
1888 &args->nfs_server.hostname,
1889 PAGE_SIZE,
1890 &args->nfs_server.export_path,
1891 NFS_MAXPATHLEN);
1892 if (!status)
1893 status = nfs_try_mount(args, mntfh);
1894
1895 kfree(args->nfs_server.export_path);
1896 args->nfs_server.export_path = NULL;
1897
1898 if (status)
1899 return status;
1900
1901 break;
1902 }
1992 } 1903 }
1993 1904
1994#if !IS_ENABLED(CONFIG_NFS_V3) 1905#ifndef CONFIG_NFS_V3
1995 if (args->version == 3) 1906 if (args->version == 3)
1996 goto out_v3_not_compiled; 1907 goto out_v3_not_compiled;
1997#endif /* !CONFIG_NFS_V3 */ 1908#endif /* !CONFIG_NFS_V3 */
@@ -2011,12 +1922,18 @@ out_no_sec:
2011 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); 1922 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
2012 return -EINVAL; 1923 return -EINVAL;
2013 1924
2014#if !IS_ENABLED(CONFIG_NFS_V3) 1925#ifndef CONFIG_NFS_V3
2015out_v3_not_compiled: 1926out_v3_not_compiled:
2016 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n"); 1927 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
2017 return -EPROTONOSUPPORT; 1928 return -EPROTONOSUPPORT;
2018#endif /* !CONFIG_NFS_V3 */ 1929#endif /* !CONFIG_NFS_V3 */
2019 1930
1931#ifndef CONFIG_NFS_V4
1932out_v4_not_compiled:
1933 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
1934 return -EPROTONOSUPPORT;
1935#endif /* !CONFIG_NFS_V4 */
1936
2020out_nomem: 1937out_nomem:
2021 dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); 1938 dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
2022 return -ENOMEM; 1939 return -ENOMEM;
@@ -2030,82 +1947,6 @@ out_invalid_fh:
2030 return -EINVAL; 1947 return -EINVAL;
2031} 1948}
2032 1949
2033#if IS_ENABLED(CONFIG_NFS_V4)
2034static int nfs_validate_mount_data(struct file_system_type *fs_type,
2035 void *options,
2036 struct nfs_parsed_mount_data *args,
2037 struct nfs_fh *mntfh,
2038 const char *dev_name)
2039{
2040 if (fs_type == &nfs_fs_type)
2041 return nfs23_validate_mount_data(options, args, mntfh, dev_name);
2042 return nfs4_validate_mount_data(options, args, dev_name);
2043}
2044#else
2045static int nfs_validate_mount_data(struct file_system_type *fs_type,
2046 void *options,
2047 struct nfs_parsed_mount_data *args,
2048 struct nfs_fh *mntfh,
2049 const char *dev_name)
2050{
2051 return nfs23_validate_mount_data(options, args, mntfh, dev_name);
2052}
2053#endif
2054
2055static int nfs_validate_text_mount_data(void *options,
2056 struct nfs_parsed_mount_data *args,
2057 const char *dev_name)
2058{
2059 int port = 0;
2060 int max_namelen = PAGE_SIZE;
2061 int max_pathlen = NFS_MAXPATHLEN;
2062 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
2063
2064 if (nfs_parse_mount_options((char *)options, args) == 0)
2065 return -EINVAL;
2066
2067 if (!nfs_verify_server_address(sap))
2068 goto out_no_address;
2069
2070 if (args->version == 4) {
2071#if IS_ENABLED(CONFIG_NFS_V4)
2072 port = NFS_PORT;
2073 max_namelen = NFS4_MAXNAMLEN;
2074 max_pathlen = NFS4_MAXPATHLEN;
2075 nfs_validate_transport_protocol(args);
2076 nfs4_validate_mount_flags(args);
2077#else
2078 goto out_v4_not_compiled;
2079#endif /* CONFIG_NFS_V4 */
2080 } else
2081 nfs_set_mount_transport_protocol(args);
2082
2083 nfs_set_port(sap, &args->nfs_server.port, port);
2084
2085 if (args->auth_flavor_len > 1)
2086 goto out_bad_auth;
2087
2088 return nfs_parse_devname(dev_name,
2089 &args->nfs_server.hostname,
2090 max_namelen,
2091 &args->nfs_server.export_path,
2092 max_pathlen);
2093
2094#if !IS_ENABLED(CONFIG_NFS_V4)
2095out_v4_not_compiled:
2096 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
2097 return -EPROTONOSUPPORT;
2098#endif /* !CONFIG_NFS_V4 */
2099
2100out_no_address:
2101 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
2102 return -EINVAL;
2103
2104out_bad_auth:
2105 dfprintk(MOUNT, "NFS: Too many RPC auth flavours specified\n");
2106 return -EINVAL;
2107}
2108
2109static int 1950static int
2110nfs_compare_remount_data(struct nfs_server *nfss, 1951nfs_compare_remount_data(struct nfs_server *nfss,
2111 struct nfs_parsed_mount_data *data) 1952 struct nfs_parsed_mount_data *data)
@@ -2129,7 +1970,7 @@ nfs_compare_remount_data(struct nfs_server *nfss,
2129 return 0; 1970 return 0;
2130} 1971}
2131 1972
2132int 1973static int
2133nfs_remount(struct super_block *sb, int *flags, char *raw_data) 1974nfs_remount(struct super_block *sb, int *flags, char *raw_data)
2134{ 1975{
2135 int error; 1976 int error;
@@ -2190,12 +2031,11 @@ out:
2190 kfree(data); 2031 kfree(data);
2191 return error; 2032 return error;
2192} 2033}
2193EXPORT_SYMBOL_GPL(nfs_remount);
2194 2034
2195/* 2035/*
2196 * Initialise the common bits of the superblock 2036 * Initialise the common bits of the superblock
2197 */ 2037 */
2198inline void nfs_initialise_sb(struct super_block *sb) 2038static inline void nfs_initialise_sb(struct super_block *sb)
2199{ 2039{
2200 struct nfs_server *server = NFS_SB(sb); 2040 struct nfs_server *server = NFS_SB(sb);
2201 2041
@@ -2203,7 +2043,7 @@ inline void nfs_initialise_sb(struct super_block *sb)
2203 2043
2204 /* We probably want something more informative here */ 2044 /* We probably want something more informative here */
2205 snprintf(sb->s_id, sizeof(sb->s_id), 2045 snprintf(sb->s_id, sizeof(sb->s_id),
2206 "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev)); 2046 "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
2207 2047
2208 if (sb->s_blocksize == 0) 2048 if (sb->s_blocksize == 0)
2209 sb->s_blocksize = nfs_block_bits(server->wsize, 2049 sb->s_blocksize = nfs_block_bits(server->wsize,
@@ -2217,19 +2057,17 @@ inline void nfs_initialise_sb(struct super_block *sb)
2217/* 2057/*
2218 * Finish setting up an NFS2/3 superblock 2058 * Finish setting up an NFS2/3 superblock
2219 */ 2059 */
2220void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) 2060static void nfs_fill_super(struct super_block *sb,
2061 struct nfs_parsed_mount_data *data)
2221{ 2062{
2222 struct nfs_parsed_mount_data *data = mount_info->parsed;
2223 struct nfs_server *server = NFS_SB(sb); 2063 struct nfs_server *server = NFS_SB(sb);
2224 2064
2225 sb->s_blocksize_bits = 0; 2065 sb->s_blocksize_bits = 0;
2226 sb->s_blocksize = 0; 2066 sb->s_blocksize = 0;
2227 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; 2067 if (data->bsize)
2228 sb->s_op = server->nfs_client->cl_nfs_mod->sops;
2229 if (data && data->bsize)
2230 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); 2068 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
2231 2069
2232 if (server->nfs_client->rpc_ops->version != 2) { 2070 if (server->nfs_client->rpc_ops->version == 3) {
2233 /* The VFS shouldn't apply the umask to mode bits. We will do 2071 /* The VFS shouldn't apply the umask to mode bits. We will do
2234 * so ourselves when necessary. 2072 * so ourselves when necessary.
2235 */ 2073 */
@@ -2237,32 +2075,31 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2237 sb->s_time_gran = 1; 2075 sb->s_time_gran = 1;
2238 } 2076 }
2239 2077
2078 sb->s_op = &nfs_sops;
2240 nfs_initialise_sb(sb); 2079 nfs_initialise_sb(sb);
2241} 2080}
2242EXPORT_SYMBOL_GPL(nfs_fill_super);
2243 2081
2244/* 2082/*
2245 * Finish setting up a cloned NFS2/3/4 superblock 2083 * Finish setting up a cloned NFS2/3 superblock
2246 */ 2084 */
2247void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) 2085static void nfs_clone_super(struct super_block *sb,
2086 const struct super_block *old_sb)
2248{ 2087{
2249 const struct super_block *old_sb = mount_info->cloned->sb;
2250 struct nfs_server *server = NFS_SB(sb); 2088 struct nfs_server *server = NFS_SB(sb);
2251 2089
2252 sb->s_blocksize_bits = old_sb->s_blocksize_bits; 2090 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
2253 sb->s_blocksize = old_sb->s_blocksize; 2091 sb->s_blocksize = old_sb->s_blocksize;
2254 sb->s_maxbytes = old_sb->s_maxbytes; 2092 sb->s_maxbytes = old_sb->s_maxbytes;
2255 sb->s_xattr = old_sb->s_xattr;
2256 sb->s_op = old_sb->s_op;
2257 sb->s_time_gran = 1;
2258 2093
2259 if (server->nfs_client->rpc_ops->version != 2) { 2094 if (server->nfs_client->rpc_ops->version == 3) {
2260 /* The VFS shouldn't apply the umask to mode bits. We will do 2095 /* The VFS shouldn't apply the umask to mode bits. We will do
2261 * so ourselves when necessary. 2096 * so ourselves when necessary.
2262 */ 2097 */
2263 sb->s_flags |= MS_POSIXACL; 2098 sb->s_flags |= MS_POSIXACL;
2099 sb->s_time_gran = 1;
2264 } 2100 }
2265 2101
2102 sb->s_op = old_sb->s_op;
2266 nfs_initialise_sb(sb); 2103 nfs_initialise_sb(sb);
2267} 2104}
2268 2105
@@ -2370,83 +2207,52 @@ static int nfs_compare_super(struct super_block *sb, void *data)
2370 return nfs_compare_mount_options(sb, server, mntflags); 2207 return nfs_compare_mount_options(sb, server, mntflags);
2371} 2208}
2372 2209
2373#ifdef CONFIG_NFS_FSCACHE
2374static void nfs_get_cache_cookie(struct super_block *sb,
2375 struct nfs_parsed_mount_data *parsed,
2376 struct nfs_clone_mount *cloned)
2377{
2378 struct nfs_server *nfss = NFS_SB(sb);
2379 char *uniq = NULL;
2380 int ulen = 0;
2381
2382 nfss->fscache_key = NULL;
2383 nfss->fscache = NULL;
2384
2385 if (parsed) {
2386 if (!(parsed->options & NFS_OPTION_FSCACHE))
2387 return;
2388 if (parsed->fscache_uniq) {
2389 uniq = parsed->fscache_uniq;
2390 ulen = strlen(parsed->fscache_uniq);
2391 }
2392 } else if (cloned) {
2393 struct nfs_server *mnt_s = NFS_SB(cloned->sb);
2394 if (!(mnt_s->options & NFS_OPTION_FSCACHE))
2395 return;
2396 if (mnt_s->fscache_key) {
2397 uniq = mnt_s->fscache_key->key.uniquifier;
2398 ulen = mnt_s->fscache_key->key.uniq_len;
2399 };
2400 } else
2401 return;
2402
2403 nfs_fscache_get_super_cookie(sb, uniq, ulen);
2404}
2405#else
2406static void nfs_get_cache_cookie(struct super_block *sb,
2407 struct nfs_parsed_mount_data *parsed,
2408 struct nfs_clone_mount *cloned)
2409{
2410}
2411#endif
2412
2413static int nfs_bdi_register(struct nfs_server *server) 2210static int nfs_bdi_register(struct nfs_server *server)
2414{ 2211{
2415 return bdi_register_dev(&server->backing_dev_info, server->s_dev); 2212 return bdi_register_dev(&server->backing_dev_info, server->s_dev);
2416} 2213}
2417 2214
2418int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot, 2215static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2419 struct nfs_mount_info *mount_info) 2216 int flags, const char *dev_name, void *raw_data)
2420{
2421 return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
2422}
2423EXPORT_SYMBOL_GPL(nfs_set_sb_security);
2424
2425int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2426 struct nfs_mount_info *mount_info)
2427{
2428 /* clone any lsm security options from the parent to the new sb */
2429 security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
2430 if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
2431 return -ESTALE;
2432 return 0;
2433}
2434EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
2435
2436struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2437 int flags, const char *dev_name,
2438 struct nfs_mount_info *mount_info,
2439 struct nfs_subversion *nfs_mod)
2440{ 2217{
2218 struct nfs_server *server = NULL;
2441 struct super_block *s; 2219 struct super_block *s;
2220 struct nfs_parsed_mount_data *data;
2221 struct nfs_fh *mntfh;
2442 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2222 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2443 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 2223 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2444 struct nfs_sb_mountdata sb_mntdata = { 2224 struct nfs_sb_mountdata sb_mntdata = {
2445 .mntflags = flags, 2225 .mntflags = flags,
2446 .server = server,
2447 }; 2226 };
2448 int error; 2227 int error;
2449 2228
2229 data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
2230 mntfh = nfs_alloc_fhandle();
2231 if (data == NULL || mntfh == NULL)
2232 goto out;
2233
2234 /* Validate the mount data */
2235 error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
2236 if (error < 0) {
2237 mntroot = ERR_PTR(error);
2238 goto out;
2239 }
2240
2241#ifdef CONFIG_NFS_V4
2242 if (data->version == 4) {
2243 mntroot = nfs4_try_mount(flags, dev_name, data);
2244 goto out;
2245 }
2246#endif /* CONFIG_NFS_V4 */
2247
2248 /* Get a volume representation */
2249 server = nfs_create_server(data, mntfh);
2250 if (IS_ERR(server)) {
2251 mntroot = ERR_CAST(server);
2252 goto out;
2253 }
2254 sb_mntdata.server = server;
2255
2450 if (server->flags & NFS_MOUNT_UNSHARED) 2256 if (server->flags & NFS_MOUNT_UNSHARED)
2451 compare_super = NULL; 2257 compare_super = NULL;
2452 2258
@@ -2455,7 +2261,7 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2455 sb_mntdata.mntflags |= MS_SYNCHRONOUS; 2261 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2456 2262
2457 /* Get a superblock - note that we may end up sharing one that already exists */ 2263 /* Get a superblock - note that we may end up sharing one that already exists */
2458 s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); 2264 s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
2459 if (IS_ERR(s)) { 2265 if (IS_ERR(s)) {
2460 mntroot = ERR_CAST(s); 2266 mntroot = ERR_CAST(s);
2461 goto out_err_nosb; 2267 goto out_err_nosb;
@@ -2474,21 +2280,23 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2474 2280
2475 if (!s->s_root) { 2281 if (!s->s_root) {
2476 /* initial superblock/root creation */ 2282 /* initial superblock/root creation */
2477 mount_info->fill_super(s, mount_info); 2283 nfs_fill_super(s, data);
2478 nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned); 2284 nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
2479 } 2285 }
2480 2286
2481 mntroot = nfs_get_root(s, mount_info->mntfh, dev_name); 2287 mntroot = nfs_get_root(s, mntfh, dev_name);
2482 if (IS_ERR(mntroot)) 2288 if (IS_ERR(mntroot))
2483 goto error_splat_super; 2289 goto error_splat_super;
2484 2290
2485 error = mount_info->set_security(s, mntroot, mount_info); 2291 error = security_sb_set_mnt_opts(s, &data->lsm_opts);
2486 if (error) 2292 if (error)
2487 goto error_splat_root; 2293 goto error_splat_root;
2488 2294
2489 s->s_flags |= MS_ACTIVE; 2295 s->s_flags |= MS_ACTIVE;
2490 2296
2491out: 2297out:
2298 nfs_free_parsed_mount_data(data);
2299 nfs_free_fhandle(mntfh);
2492 return mntroot; 2300 return mntroot;
2493 2301
2494out_err_nosb: 2302out_err_nosb:
@@ -2505,65 +2313,22 @@ error_splat_bdi:
2505 deactivate_locked_super(s); 2313 deactivate_locked_super(s);
2506 goto out; 2314 goto out;
2507} 2315}
2508EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
2509
2510struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2511 int flags, const char *dev_name, void *raw_data)
2512{
2513 struct nfs_mount_info mount_info = {
2514 .fill_super = nfs_fill_super,
2515 .set_security = nfs_set_sb_security,
2516 };
2517 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2518 struct nfs_subversion *nfs_mod;
2519 int error;
2520
2521 mount_info.parsed = nfs_alloc_parsed_mount_data();
2522 mount_info.mntfh = nfs_alloc_fhandle();
2523 if (mount_info.parsed == NULL || mount_info.mntfh == NULL)
2524 goto out;
2525
2526 /* Validate the mount data */
2527 error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mount_info.mntfh, dev_name);
2528 if (error == NFS_TEXT_DATA)
2529 error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name);
2530 if (error < 0) {
2531 mntroot = ERR_PTR(error);
2532 goto out;
2533 }
2534
2535 nfs_mod = get_nfs_version(mount_info.parsed->version);
2536 if (IS_ERR(nfs_mod)) {
2537 mntroot = ERR_CAST(nfs_mod);
2538 goto out;
2539 }
2540
2541 mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
2542
2543 put_nfs_version(nfs_mod);
2544out:
2545 nfs_free_parsed_mount_data(mount_info.parsed);
2546 nfs_free_fhandle(mount_info.mntfh);
2547 return mntroot;
2548}
2549EXPORT_SYMBOL_GPL(nfs_fs_mount);
2550 2316
2551/* 2317/*
2552 * Ensure that we unregister the bdi before kill_anon_super 2318 * Ensure that we unregister the bdi before kill_anon_super
2553 * releases the device name 2319 * releases the device name
2554 */ 2320 */
2555void nfs_put_super(struct super_block *s) 2321static void nfs_put_super(struct super_block *s)
2556{ 2322{
2557 struct nfs_server *server = NFS_SB(s); 2323 struct nfs_server *server = NFS_SB(s);
2558 2324
2559 bdi_unregister(&server->backing_dev_info); 2325 bdi_unregister(&server->backing_dev_info);
2560} 2326}
2561EXPORT_SYMBOL_GPL(nfs_put_super);
2562 2327
2563/* 2328/*
2564 * Destroy an NFS2/3 superblock 2329 * Destroy an NFS2/3 superblock
2565 */ 2330 */
2566void nfs_kill_super(struct super_block *s) 2331static void nfs_kill_super(struct super_block *s)
2567{ 2332{
2568 struct nfs_server *server = NFS_SB(s); 2333 struct nfs_server *server = NFS_SB(s);
2569 2334
@@ -2571,48 +2336,134 @@ void nfs_kill_super(struct super_block *s)
2571 nfs_fscache_release_super_cookie(s); 2336 nfs_fscache_release_super_cookie(s);
2572 nfs_free_server(server); 2337 nfs_free_server(server);
2573} 2338}
2574EXPORT_SYMBOL_GPL(nfs_kill_super);
2575 2339
2576/* 2340/*
2577 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change) 2341 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
2578 */ 2342 */
2579static struct dentry * 2343static struct dentry *
2580nfs_xdev_mount(struct file_system_type *fs_type, int flags, 2344nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2581 const char *dev_name, void *raw_data) 2345 const char *dev_name, void *raw_data)
2582{ 2346{
2583 struct nfs_clone_mount *data = raw_data; 2347 struct nfs_clone_mount *data = raw_data;
2584 struct nfs_mount_info mount_info = { 2348 struct super_block *s;
2585 .fill_super = nfs_clone_super,
2586 .set_security = nfs_clone_sb_security,
2587 .cloned = data,
2588 };
2589 struct nfs_server *server; 2349 struct nfs_server *server;
2590 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2350 struct dentry *mntroot;
2591 struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; 2351 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2352 struct nfs_sb_mountdata sb_mntdata = {
2353 .mntflags = flags,
2354 };
2592 int error; 2355 int error;
2593 2356
2594 dprintk("--> nfs_xdev_mount_common()\n"); 2357 dprintk("--> nfs_xdev_mount()\n");
2595
2596 mount_info.mntfh = mount_info.cloned->fh;
2597 2358
2598 /* create a new volume representation */ 2359 /* create a new volume representation */
2599 server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); 2360 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
2600 if (IS_ERR(server)) { 2361 if (IS_ERR(server)) {
2601 error = PTR_ERR(server); 2362 error = PTR_ERR(server);
2602 goto out_err; 2363 goto out_err_noserver;
2603 } 2364 }
2365 sb_mntdata.server = server;
2604 2366
2605 mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod); 2367 if (server->flags & NFS_MOUNT_UNSHARED)
2606 dprintk("<-- nfs_xdev_mount_common() = 0\n"); 2368 compare_super = NULL;
2607out: 2369
2370 /* -o noac implies -o sync */
2371 if (server->flags & NFS_MOUNT_NOAC)
2372 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2373
2374 /* Get a superblock - note that we may end up sharing one that already exists */
2375 s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
2376 if (IS_ERR(s)) {
2377 error = PTR_ERR(s);
2378 goto out_err_nosb;
2379 }
2380
2381 if (s->s_fs_info != server) {
2382 nfs_free_server(server);
2383 server = NULL;
2384 } else {
2385 error = nfs_bdi_register(server);
2386 if (error)
2387 goto error_splat_bdi;
2388 }
2389
2390 if (!s->s_root) {
2391 /* initial superblock/root creation */
2392 nfs_clone_super(s, data->sb);
2393 nfs_fscache_get_super_cookie(s, NULL, data);
2394 }
2395
2396 mntroot = nfs_get_root(s, data->fh, dev_name);
2397 if (IS_ERR(mntroot)) {
2398 error = PTR_ERR(mntroot);
2399 goto error_splat_super;
2400 }
2401 if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
2402 dput(mntroot);
2403 error = -ESTALE;
2404 goto error_splat_super;
2405 }
2406
2407 s->s_flags |= MS_ACTIVE;
2408
2409 /* clone any lsm security options from the parent to the new sb */
2410 security_sb_clone_mnt_opts(data->sb, s);
2411
2412 dprintk("<-- nfs_xdev_mount() = 0\n");
2608 return mntroot; 2413 return mntroot;
2609 2414
2610out_err: 2415out_err_nosb:
2611 dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error); 2416 nfs_free_server(server);
2612 goto out; 2417out_err_noserver:
2418 dprintk("<-- nfs_xdev_mount() = %d [error]\n", error);
2419 return ERR_PTR(error);
2420
2421error_splat_super:
2422 if (server && !s->s_root)
2423 bdi_unregister(&server->backing_dev_info);
2424error_splat_bdi:
2425 deactivate_locked_super(s);
2426 dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error);
2427 return ERR_PTR(error);
2428}
2429
2430#ifdef CONFIG_NFS_V4
2431
2432/*
2433 * Finish setting up a cloned NFS4 superblock
2434 */
2435static void nfs4_clone_super(struct super_block *sb,
2436 const struct super_block *old_sb)
2437{
2438 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
2439 sb->s_blocksize = old_sb->s_blocksize;
2440 sb->s_maxbytes = old_sb->s_maxbytes;
2441 sb->s_time_gran = 1;
2442 sb->s_op = old_sb->s_op;
2443 /*
2444 * The VFS shouldn't apply the umask to mode bits. We will do
2445 * so ourselves when necessary.
2446 */
2447 sb->s_flags |= MS_POSIXACL;
2448 sb->s_xattr = old_sb->s_xattr;
2449 nfs_initialise_sb(sb);
2613} 2450}
2614 2451
2615#if IS_ENABLED(CONFIG_NFS_V4) 2452/*
2453 * Set up an NFS4 superblock
2454 */
2455static void nfs4_fill_super(struct super_block *sb)
2456{
2457 sb->s_time_gran = 1;
2458 sb->s_op = &nfs4_sops;
2459 /*
2460 * The VFS shouldn't apply the umask to mode bits. We will do
2461 * so ourselves when necessary.
2462 */
2463 sb->s_flags |= MS_POSIXACL;
2464 sb->s_xattr = nfs4_xattr_handlers;
2465 nfs_initialise_sb(sb);
2466}
2616 2467
2617static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) 2468static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2618{ 2469{
@@ -2620,6 +2471,43 @@ static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2620 NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); 2471 NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL);
2621} 2472}
2622 2473
2474static int nfs4_validate_text_mount_data(void *options,
2475 struct nfs_parsed_mount_data *args,
2476 const char *dev_name)
2477{
2478 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
2479
2480 nfs_set_port(sap, &args->nfs_server.port, NFS_PORT);
2481
2482 nfs_validate_transport_protocol(args);
2483
2484 nfs4_validate_mount_flags(args);
2485
2486 if (args->version != 4) {
2487 dfprintk(MOUNT,
2488 "NFS4: Illegal mount version\n");
2489 return -EINVAL;
2490 }
2491
2492 if (args->auth_flavor_len > 1) {
2493 dfprintk(MOUNT,
2494 "NFS4: Too many RPC auth flavours specified\n");
2495 return -EINVAL;
2496 }
2497
2498 if (args->client_address == NULL) {
2499 dfprintk(MOUNT,
2500 "NFS4: mount program didn't pass callback address\n");
2501 return -EINVAL;
2502 }
2503
2504 return nfs_parse_devname(dev_name,
2505 &args->nfs_server.hostname,
2506 NFS4_MAXNAMLEN,
2507 &args->nfs_server.export_path,
2508 NFS4_MAXPATHLEN);
2509}
2510
2623/* 2511/*
2624 * Validate NFSv4 mount options 2512 * Validate NFSv4 mount options
2625 */ 2513 */
@@ -2634,8 +2522,6 @@ static int nfs4_validate_mount_data(void *options,
2634 if (data == NULL) 2522 if (data == NULL)
2635 goto out_no_data; 2523 goto out_no_data;
2636 2524
2637 args->version = 4;
2638
2639 switch (data->version) { 2525 switch (data->version) {
2640 case 1: 2526 case 1:
2641 if (data->host_addrlen > sizeof(args->nfs_server.address)) 2527 if (data->host_addrlen > sizeof(args->nfs_server.address))
@@ -2647,7 +2533,6 @@ static int nfs4_validate_mount_data(void *options,
2647 return -EFAULT; 2533 return -EFAULT;
2648 if (!nfs_verify_server_address(sap)) 2534 if (!nfs_verify_server_address(sap))
2649 goto out_no_address; 2535 goto out_no_address;
2650 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2651 2536
2652 if (data->auth_flavourlen) { 2537 if (data->auth_flavourlen) {
2653 if (data->auth_flavourlen > 1) 2538 if (data->auth_flavourlen > 1)
@@ -2693,7 +2578,13 @@ static int nfs4_validate_mount_data(void *options,
2693 2578
2694 break; 2579 break;
2695 default: 2580 default:
2696 return NFS_TEXT_DATA; 2581 if (nfs_parse_mount_options((char *)options, args) == 0)
2582 return -EINVAL;
2583
2584 if (!nfs_verify_server_address(sap))
2585 return -EINVAL;
2586
2587 return nfs4_validate_text_mount_data(options, args, dev_name);
2697 } 2588 }
2698 2589
2699 return 0; 2590 return 0;
@@ -2713,62 +2604,503 @@ out_no_address:
2713} 2604}
2714 2605
2715/* 2606/*
2716 * NFS v4 module parameters need to stay in the 2607 * Get the superblock for the NFS4 root partition
2717 * NFS client for backwards compatibility
2718 */ 2608 */
2719unsigned int nfs_callback_set_tcpport; 2609static struct dentry *
2720unsigned short nfs_callback_tcpport; 2610nfs4_remote_mount(struct file_system_type *fs_type, int flags,
2721/* Default cache timeout is 10 minutes */ 2611 const char *dev_name, void *raw_data)
2722unsigned int nfs_idmap_cache_timeout = 600;
2723/* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
2724bool nfs4_disable_idmapping = true;
2725unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
2726unsigned short send_implementation_id = 1;
2727char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
2728
2729EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
2730EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
2731EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
2732EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
2733EXPORT_SYMBOL_GPL(max_session_slots);
2734EXPORT_SYMBOL_GPL(send_implementation_id);
2735EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
2736
2737#define NFS_CALLBACK_MAXPORTNR (65535U)
2738
2739static int param_set_portnr(const char *val, const struct kernel_param *kp)
2740{ 2612{
2741 unsigned long num; 2613 struct nfs_parsed_mount_data *data = raw_data;
2742 int ret; 2614 struct super_block *s;
2615 struct nfs_server *server;
2616 struct nfs_fh *mntfh;
2617 struct dentry *mntroot;
2618 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2619 struct nfs_sb_mountdata sb_mntdata = {
2620 .mntflags = flags,
2621 };
2622 int error = -ENOMEM;
2743 2623
2744 if (!val) 2624 mntfh = nfs_alloc_fhandle();
2745 return -EINVAL; 2625 if (data == NULL || mntfh == NULL)
2746 ret = kstrtoul(val, 0, &num); 2626 goto out;
2747 if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR) 2627
2748 return -EINVAL; 2628 /* Get a volume representation */
2749 *((unsigned int *)kp->arg) = num; 2629 server = nfs4_create_server(data, mntfh);
2750 return 0; 2630 if (IS_ERR(server)) {
2631 error = PTR_ERR(server);
2632 goto out;
2633 }
2634 sb_mntdata.server = server;
2635
2636 if (server->flags & NFS4_MOUNT_UNSHARED)
2637 compare_super = NULL;
2638
2639 /* -o noac implies -o sync */
2640 if (server->flags & NFS_MOUNT_NOAC)
2641 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2642
2643 /* Get a superblock - note that we may end up sharing one that already exists */
2644 s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
2645 if (IS_ERR(s)) {
2646 error = PTR_ERR(s);
2647 goto out_free;
2648 }
2649
2650 if (s->s_fs_info != server) {
2651 nfs_free_server(server);
2652 server = NULL;
2653 } else {
2654 error = nfs_bdi_register(server);
2655 if (error)
2656 goto error_splat_bdi;
2657 }
2658
2659 if (!s->s_root) {
2660 /* initial superblock/root creation */
2661 nfs4_fill_super(s);
2662 nfs_fscache_get_super_cookie(
2663 s, data ? data->fscache_uniq : NULL, NULL);
2664 }
2665
2666 mntroot = nfs4_get_root(s, mntfh, dev_name);
2667 if (IS_ERR(mntroot)) {
2668 error = PTR_ERR(mntroot);
2669 goto error_splat_super;
2670 }
2671
2672 error = security_sb_set_mnt_opts(s, &data->lsm_opts);
2673 if (error)
2674 goto error_splat_root;
2675
2676 s->s_flags |= MS_ACTIVE;
2677
2678 nfs_free_fhandle(mntfh);
2679 return mntroot;
2680
2681out:
2682 nfs_free_fhandle(mntfh);
2683 return ERR_PTR(error);
2684
2685out_free:
2686 nfs_free_server(server);
2687 goto out;
2688
2689error_splat_root:
2690 dput(mntroot);
2691error_splat_super:
2692 if (server && !s->s_root)
2693 bdi_unregister(&server->backing_dev_info);
2694error_splat_bdi:
2695 deactivate_locked_super(s);
2696 goto out;
2751} 2697}
2752static struct kernel_param_ops param_ops_portnr = { 2698
2753 .set = param_set_portnr, 2699static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,
2754 .get = param_get_uint, 2700 int flags, void *data, const char *hostname)
2701{
2702 struct vfsmount *root_mnt;
2703 char *root_devname;
2704 size_t len;
2705
2706 len = strlen(hostname) + 3;
2707 root_devname = kmalloc(len, GFP_KERNEL);
2708 if (root_devname == NULL)
2709 return ERR_PTR(-ENOMEM);
2710 snprintf(root_devname, len, "%s:/", hostname);
2711 root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
2712 kfree(root_devname);
2713 return root_mnt;
2714}
2715
2716struct nfs_referral_count {
2717 struct list_head list;
2718 const struct task_struct *task;
2719 unsigned int referral_count;
2755}; 2720};
2756#define param_check_portnr(name, p) __param_check(name, p, unsigned int); 2721
2757 2722static LIST_HEAD(nfs_referral_count_list);
2758module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); 2723static DEFINE_SPINLOCK(nfs_referral_count_list_lock);
2759module_param(nfs_idmap_cache_timeout, int, 0644); 2724
2760module_param(nfs4_disable_idmapping, bool, 0644); 2725static struct nfs_referral_count *nfs_find_referral_count(void)
2761module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier, 2726{
2762 NFS4_CLIENT_ID_UNIQ_LEN, 0600); 2727 struct nfs_referral_count *p;
2763MODULE_PARM_DESC(nfs4_disable_idmapping, 2728
2764 "Turn off NFSv4 idmapping when using 'sec=sys'"); 2729 list_for_each_entry(p, &nfs_referral_count_list, list) {
2765module_param(max_session_slots, ushort, 0644); 2730 if (p->task == current)
2766MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 " 2731 return p;
2767 "requests the client will negotiate"); 2732 }
2768module_param(send_implementation_id, ushort, 0644); 2733 return NULL;
2769MODULE_PARM_DESC(send_implementation_id, 2734}
2770 "Send implementation ID with NFSv4.1 exchange_id"); 2735
2771MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string"); 2736#define NFS_MAX_NESTED_REFERRALS 2
2772MODULE_ALIAS("nfs4"); 2737
2738static int nfs_referral_loop_protect(void)
2739{
2740 struct nfs_referral_count *p, *new;
2741 int ret = -ENOMEM;
2742
2743 new = kmalloc(sizeof(*new), GFP_KERNEL);
2744 if (!new)
2745 goto out;
2746 new->task = current;
2747 new->referral_count = 1;
2748
2749 ret = 0;
2750 spin_lock(&nfs_referral_count_list_lock);
2751 p = nfs_find_referral_count();
2752 if (p != NULL) {
2753 if (p->referral_count >= NFS_MAX_NESTED_REFERRALS)
2754 ret = -ELOOP;
2755 else
2756 p->referral_count++;
2757 } else {
2758 list_add(&new->list, &nfs_referral_count_list);
2759 new = NULL;
2760 }
2761 spin_unlock(&nfs_referral_count_list_lock);
2762 kfree(new);
2763out:
2764 return ret;
2765}
2766
2767static void nfs_referral_loop_unprotect(void)
2768{
2769 struct nfs_referral_count *p;
2770
2771 spin_lock(&nfs_referral_count_list_lock);
2772 p = nfs_find_referral_count();
2773 p->referral_count--;
2774 if (p->referral_count == 0)
2775 list_del(&p->list);
2776 else
2777 p = NULL;
2778 spin_unlock(&nfs_referral_count_list_lock);
2779 kfree(p);
2780}
2781
2782static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
2783 const char *export_path)
2784{
2785 struct mnt_namespace *ns_private;
2786 struct super_block *s;
2787 struct dentry *dentry;
2788 struct path path;
2789 int ret;
2790
2791 ns_private = create_mnt_ns(root_mnt);
2792 ret = PTR_ERR(ns_private);
2793 if (IS_ERR(ns_private))
2794 goto out_mntput;
2795
2796 ret = nfs_referral_loop_protect();
2797 if (ret != 0)
2798 goto out_put_mnt_ns;
2799
2800 ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
2801 export_path, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
2802
2803 nfs_referral_loop_unprotect();
2804 put_mnt_ns(ns_private);
2805
2806 if (ret != 0)
2807 goto out_err;
2808
2809 s = path.mnt->mnt_sb;
2810 atomic_inc(&s->s_active);
2811 dentry = dget(path.dentry);
2812
2813 path_put(&path);
2814 down_write(&s->s_umount);
2815 return dentry;
2816out_put_mnt_ns:
2817 put_mnt_ns(ns_private);
2818out_mntput:
2819 mntput(root_mnt);
2820out_err:
2821 return ERR_PTR(ret);
2822}
2823
2824static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
2825 struct nfs_parsed_mount_data *data)
2826{
2827 char *export_path;
2828 struct vfsmount *root_mnt;
2829 struct dentry *res;
2830
2831 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
2832
2833 export_path = data->nfs_server.export_path;
2834 data->nfs_server.export_path = "/";
2835 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
2836 data->nfs_server.hostname);
2837 data->nfs_server.export_path = export_path;
2838
2839 res = ERR_CAST(root_mnt);
2840 if (!IS_ERR(root_mnt))
2841 res = nfs_follow_remote_path(root_mnt, export_path);
2842
2843 dfprintk(MOUNT, "<-- nfs4_try_mount() = %ld%s\n",
2844 IS_ERR(res) ? PTR_ERR(res) : 0,
2845 IS_ERR(res) ? " [error]" : "");
2846 return res;
2847}
2848
2849/*
2850 * Get the superblock for an NFS4 mountpoint
2851 */
2852static struct dentry *nfs4_mount(struct file_system_type *fs_type,
2853 int flags, const char *dev_name, void *raw_data)
2854{
2855 struct nfs_parsed_mount_data *data;
2856 int error = -ENOMEM;
2857 struct dentry *res = ERR_PTR(-ENOMEM);
2858
2859 data = nfs_alloc_parsed_mount_data(4);
2860 if (data == NULL)
2861 goto out;
2862
2863 /* Validate the mount data */
2864 error = nfs4_validate_mount_data(raw_data, data, dev_name);
2865 if (error < 0) {
2866 res = ERR_PTR(error);
2867 goto out;
2868 }
2869
2870 res = nfs4_try_mount(flags, dev_name, data);
2871 if (IS_ERR(res))
2872 error = PTR_ERR(res);
2873
2874out:
2875 nfs_free_parsed_mount_data(data);
2876 dprintk("<-- nfs4_mount() = %d%s\n", error,
2877 error != 0 ? " [error]" : "");
2878 return res;
2879}
2880
2881static void nfs4_kill_super(struct super_block *sb)
2882{
2883 struct nfs_server *server = NFS_SB(sb);
2884
2885 dprintk("--> %s\n", __func__);
2886 nfs_super_return_all_delegations(sb);
2887 kill_anon_super(sb);
2888 nfs_fscache_release_super_cookie(sb);
2889 nfs_free_server(server);
2890 dprintk("<-- %s\n", __func__);
2891}
2892
2893/*
2894 * Clone an NFS4 server record on xdev traversal (FSID-change)
2895 */
2896static struct dentry *
2897nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
2898 const char *dev_name, void *raw_data)
2899{
2900 struct nfs_clone_mount *data = raw_data;
2901 struct super_block *s;
2902 struct nfs_server *server;
2903 struct dentry *mntroot;
2904 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2905 struct nfs_sb_mountdata sb_mntdata = {
2906 .mntflags = flags,
2907 };
2908 int error;
2909
2910 dprintk("--> nfs4_xdev_mount()\n");
2911
2912 /* create a new volume representation */
2913 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
2914 if (IS_ERR(server)) {
2915 error = PTR_ERR(server);
2916 goto out_err_noserver;
2917 }
2918 sb_mntdata.server = server;
2919
2920 if (server->flags & NFS4_MOUNT_UNSHARED)
2921 compare_super = NULL;
2922
2923 /* -o noac implies -o sync */
2924 if (server->flags & NFS_MOUNT_NOAC)
2925 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2926
2927 /* Get a superblock - note that we may end up sharing one that already exists */
2928 s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
2929 if (IS_ERR(s)) {
2930 error = PTR_ERR(s);
2931 goto out_err_nosb;
2932 }
2933
2934 if (s->s_fs_info != server) {
2935 nfs_free_server(server);
2936 server = NULL;
2937 } else {
2938 error = nfs_bdi_register(server);
2939 if (error)
2940 goto error_splat_bdi;
2941 }
2942
2943 if (!s->s_root) {
2944 /* initial superblock/root creation */
2945 nfs4_clone_super(s, data->sb);
2946 nfs_fscache_get_super_cookie(s, NULL, data);
2947 }
2948
2949 mntroot = nfs4_get_root(s, data->fh, dev_name);
2950 if (IS_ERR(mntroot)) {
2951 error = PTR_ERR(mntroot);
2952 goto error_splat_super;
2953 }
2954 if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
2955 dput(mntroot);
2956 error = -ESTALE;
2957 goto error_splat_super;
2958 }
2959
2960 s->s_flags |= MS_ACTIVE;
2961
2962 security_sb_clone_mnt_opts(data->sb, s);
2963
2964 dprintk("<-- nfs4_xdev_mount() = 0\n");
2965 return mntroot;
2966
2967out_err_nosb:
2968 nfs_free_server(server);
2969out_err_noserver:
2970 dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error);
2971 return ERR_PTR(error);
2972
2973error_splat_super:
2974 if (server && !s->s_root)
2975 bdi_unregister(&server->backing_dev_info);
2976error_splat_bdi:
2977 deactivate_locked_super(s);
2978 dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error);
2979 return ERR_PTR(error);
2980}
2981
2982static struct dentry *
2983nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
2984 const char *dev_name, void *raw_data)
2985{
2986 struct nfs_clone_mount *data = raw_data;
2987 struct super_block *s;
2988 struct nfs_server *server;
2989 struct dentry *mntroot;
2990 struct nfs_fh *mntfh;
2991 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2992 struct nfs_sb_mountdata sb_mntdata = {
2993 .mntflags = flags,
2994 };
2995 int error = -ENOMEM;
2996
2997 dprintk("--> nfs4_referral_get_sb()\n");
2998
2999 mntfh = nfs_alloc_fhandle();
3000 if (mntfh == NULL)
3001 goto out_err_nofh;
3002
3003 /* create a new volume representation */
3004 server = nfs4_create_referral_server(data, mntfh);
3005 if (IS_ERR(server)) {
3006 error = PTR_ERR(server);
3007 goto out_err_noserver;
3008 }
3009 sb_mntdata.server = server;
3010
3011 if (server->flags & NFS4_MOUNT_UNSHARED)
3012 compare_super = NULL;
3013
3014 /* -o noac implies -o sync */
3015 if (server->flags & NFS_MOUNT_NOAC)
3016 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
3017
3018 /* Get a superblock - note that we may end up sharing one that already exists */
3019 s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
3020 if (IS_ERR(s)) {
3021 error = PTR_ERR(s);
3022 goto out_err_nosb;
3023 }
3024
3025 if (s->s_fs_info != server) {
3026 nfs_free_server(server);
3027 server = NULL;
3028 } else {
3029 error = nfs_bdi_register(server);
3030 if (error)
3031 goto error_splat_bdi;
3032 }
3033
3034 if (!s->s_root) {
3035 /* initial superblock/root creation */
3036 nfs4_fill_super(s);
3037 nfs_fscache_get_super_cookie(s, NULL, data);
3038 }
3039
3040 mntroot = nfs4_get_root(s, mntfh, dev_name);
3041 if (IS_ERR(mntroot)) {
3042 error = PTR_ERR(mntroot);
3043 goto error_splat_super;
3044 }
3045 if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
3046 dput(mntroot);
3047 error = -ESTALE;
3048 goto error_splat_super;
3049 }
3050
3051 s->s_flags |= MS_ACTIVE;
3052
3053 security_sb_clone_mnt_opts(data->sb, s);
3054
3055 nfs_free_fhandle(mntfh);
3056 dprintk("<-- nfs4_referral_get_sb() = 0\n");
3057 return mntroot;
3058
3059out_err_nosb:
3060 nfs_free_server(server);
3061out_err_noserver:
3062 nfs_free_fhandle(mntfh);
3063out_err_nofh:
3064 dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
3065 return ERR_PTR(error);
3066
3067error_splat_super:
3068 if (server && !s->s_root)
3069 bdi_unregister(&server->backing_dev_info);
3070error_splat_bdi:
3071 deactivate_locked_super(s);
3072 nfs_free_fhandle(mntfh);
3073 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
3074 return ERR_PTR(error);
3075}
3076
3077/*
3078 * Create an NFS4 server record on referral traversal
3079 */
3080static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
3081 int flags, const char *dev_name, void *raw_data)
3082{
3083 struct nfs_clone_mount *data = raw_data;
3084 char *export_path;
3085 struct vfsmount *root_mnt;
3086 struct dentry *res;
3087
3088 dprintk("--> nfs4_referral_mount()\n");
3089
3090 export_path = data->mnt_path;
3091 data->mnt_path = "/";
3092
3093 root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type,
3094 flags, data, data->hostname);
3095 data->mnt_path = export_path;
3096
3097 res = ERR_CAST(root_mnt);
3098 if (!IS_ERR(root_mnt))
3099 res = nfs_follow_remote_path(root_mnt, export_path);
3100 dprintk("<-- nfs4_referral_mount() = %ld%s\n",
3101 IS_ERR(res) ? PTR_ERR(res) : 0,
3102 IS_ERR(res) ? " [error]" : "");
3103 return res;
3104}
2773 3105
2774#endif /* CONFIG_NFS_V4 */ 3106#endif /* CONFIG_NFS_V4 */