aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c613
1 files changed, 168 insertions, 445 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 8b2a2977b720..d2c7f5db0847 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -64,11 +64,12 @@
64#include "internal.h" 64#include "internal.h"
65#include "fscache.h" 65#include "fscache.h"
66#include "pnfs.h" 66#include "pnfs.h"
67#include "nfs.h"
67 68
68#define NFSDBG_FACILITY NFSDBG_VFS 69#define NFSDBG_FACILITY NFSDBG_VFS
69#define NFS_TEXT_DATA 1 70#define NFS_TEXT_DATA 1
70 71
71#ifdef CONFIG_NFS_V3 72#if IS_ENABLED(CONFIG_NFS_V3)
72#define NFS_DEFAULT_VERSION 3 73#define NFS_DEFAULT_VERSION 3
73#else 74#else
74#define NFS_DEFAULT_VERSION 2 75#define NFS_DEFAULT_VERSION 2
@@ -278,37 +279,17 @@ static match_table_t nfs_vers_tokens = {
278 { Opt_vers_err, NULL } 279 { Opt_vers_err, NULL }
279}; 280};
280 281
281struct nfs_mount_info {
282 void (*fill_super)(struct super_block *, struct nfs_mount_info *);
283 int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
284 struct nfs_parsed_mount_data *parsed;
285 struct nfs_clone_mount *cloned;
286 struct nfs_fh *mntfh;
287};
288
289static void nfs_umount_begin(struct super_block *);
290static int nfs_statfs(struct dentry *, struct kstatfs *);
291static int nfs_show_options(struct seq_file *, struct dentry *);
292static int nfs_show_devname(struct seq_file *, struct dentry *);
293static int nfs_show_path(struct seq_file *, struct dentry *);
294static int nfs_show_stats(struct seq_file *, struct dentry *);
295static struct dentry *nfs_fs_mount_common(struct file_system_type *,
296 struct nfs_server *, int, const char *, struct nfs_mount_info *);
297static struct dentry *nfs_fs_mount(struct file_system_type *,
298 int, const char *, void *);
299static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, 282static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
300 int flags, const char *dev_name, void *raw_data); 283 int flags, const char *dev_name, void *raw_data);
301static void nfs_put_super(struct super_block *);
302static void nfs_kill_super(struct super_block *);
303static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
304 284
305static struct file_system_type nfs_fs_type = { 285struct file_system_type nfs_fs_type = {
306 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
307 .name = "nfs", 287 .name = "nfs",
308 .mount = nfs_fs_mount, 288 .mount = nfs_fs_mount,
309 .kill_sb = nfs_kill_super, 289 .kill_sb = nfs_kill_super,
310 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 290 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
311}; 291};
292EXPORT_SYMBOL_GPL(nfs_fs_type);
312 293
313struct file_system_type nfs_xdev_fs_type = { 294struct file_system_type nfs_xdev_fs_type = {
314 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
@@ -318,7 +299,7 @@ struct file_system_type nfs_xdev_fs_type = {
318 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 299 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
319}; 300};
320 301
321static const struct super_operations nfs_sops = { 302const struct super_operations nfs_sops = {
322 .alloc_inode = nfs_alloc_inode, 303 .alloc_inode = nfs_alloc_inode,
323 .destroy_inode = nfs_destroy_inode, 304 .destroy_inode = nfs_destroy_inode,
324 .write_inode = nfs_write_inode, 305 .write_inode = nfs_write_inode,
@@ -332,77 +313,40 @@ static const struct super_operations nfs_sops = {
332 .show_stats = nfs_show_stats, 313 .show_stats = nfs_show_stats,
333 .remount_fs = nfs_remount, 314 .remount_fs = nfs_remount,
334}; 315};
316EXPORT_SYMBOL_GPL(nfs_sops);
335 317
336#ifdef CONFIG_NFS_V4 318#if IS_ENABLED(CONFIG_NFS_V4)
337static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); 319static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
338static int nfs4_validate_mount_data(void *options, 320static int nfs4_validate_mount_data(void *options,
339 struct nfs_parsed_mount_data *args, const char *dev_name); 321 struct nfs_parsed_mount_data *args, const char *dev_name);
340static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
341 struct nfs_mount_info *mount_info);
342static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
343 int flags, const char *dev_name, void *raw_data);
344static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
345 int flags, const char *dev_name, void *raw_data);
346static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
347 int flags, const char *dev_name, void *raw_data);
348static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
349 int flags, const char *dev_name, void *raw_data);
350static void nfs4_kill_super(struct super_block *sb);
351
352static struct file_system_type nfs4_fs_type = {
353 .owner = THIS_MODULE,
354 .name = "nfs4",
355 .mount = nfs_fs_mount,
356 .kill_sb = nfs4_kill_super,
357 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
358};
359 322
360static struct file_system_type nfs4_remote_fs_type = { 323struct file_system_type nfs4_fs_type = {
361 .owner = THIS_MODULE, 324 .owner = THIS_MODULE,
362 .name = "nfs4", 325 .name = "nfs4",
363 .mount = nfs4_remote_mount, 326 .mount = nfs_fs_mount,
364 .kill_sb = nfs4_kill_super, 327 .kill_sb = nfs_kill_super,
365 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
366};
367
368struct file_system_type nfs4_xdev_fs_type = {
369 .owner = THIS_MODULE,
370 .name = "nfs4",
371 .mount = nfs4_xdev_mount,
372 .kill_sb = nfs4_kill_super,
373 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 328 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
374}; 329};
330EXPORT_SYMBOL_GPL(nfs4_fs_type);
375 331
376static struct file_system_type nfs4_remote_referral_fs_type = { 332static int __init register_nfs4_fs(void)
377 .owner = THIS_MODULE, 333{
378 .name = "nfs4", 334 return register_filesystem(&nfs4_fs_type);
379 .mount = nfs4_remote_referral_mount, 335}
380 .kill_sb = nfs4_kill_super,
381 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
382};
383 336
384struct file_system_type nfs4_referral_fs_type = { 337static void unregister_nfs4_fs(void)
385 .owner = THIS_MODULE, 338{
386 .name = "nfs4", 339 unregister_filesystem(&nfs4_fs_type);
387 .mount = nfs4_referral_mount, 340}
388 .kill_sb = nfs4_kill_super, 341#else
389 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 342static int __init register_nfs4_fs(void)
390}; 343{
344 return 0;
345}
391 346
392static const struct super_operations nfs4_sops = { 347static void unregister_nfs4_fs(void)
393 .alloc_inode = nfs_alloc_inode, 348{
394 .destroy_inode = nfs_destroy_inode, 349}
395 .write_inode = nfs_write_inode,
396 .put_super = nfs_put_super,
397 .statfs = nfs_statfs,
398 .evict_inode = nfs4_evict_inode,
399 .umount_begin = nfs_umount_begin,
400 .show_options = nfs_show_options,
401 .show_devname = nfs_show_devname,
402 .show_path = nfs_show_path,
403 .show_stats = nfs_show_stats,
404 .remount_fs = nfs_remount,
405};
406#endif 350#endif
407 351
408static struct shrinker acl_shrinker = { 352static struct shrinker acl_shrinker = {
@@ -421,21 +365,18 @@ int __init register_nfs_fs(void)
421 if (ret < 0) 365 if (ret < 0)
422 goto error_0; 366 goto error_0;
423 367
424 ret = nfs_register_sysctl(); 368 ret = register_nfs4_fs();
425 if (ret < 0) 369 if (ret < 0)
426 goto error_1; 370 goto error_1;
427#ifdef CONFIG_NFS_V4 371
428 ret = register_filesystem(&nfs4_fs_type); 372 ret = nfs_register_sysctl();
429 if (ret < 0) 373 if (ret < 0)
430 goto error_2; 374 goto error_2;
431#endif
432 register_shrinker(&acl_shrinker); 375 register_shrinker(&acl_shrinker);
433 return 0; 376 return 0;
434 377
435#ifdef CONFIG_NFS_V4
436error_2: 378error_2:
437 nfs_unregister_sysctl(); 379 unregister_nfs4_fs();
438#endif
439error_1: 380error_1:
440 unregister_filesystem(&nfs_fs_type); 381 unregister_filesystem(&nfs_fs_type);
441error_0: 382error_0:
@@ -448,10 +389,8 @@ error_0:
448void __exit unregister_nfs_fs(void) 389void __exit unregister_nfs_fs(void)
449{ 390{
450 unregister_shrinker(&acl_shrinker); 391 unregister_shrinker(&acl_shrinker);
451#ifdef CONFIG_NFS_V4
452 unregister_filesystem(&nfs4_fs_type);
453#endif
454 nfs_unregister_sysctl(); 392 nfs_unregister_sysctl();
393 unregister_nfs4_fs();
455 unregister_filesystem(&nfs_fs_type); 394 unregister_filesystem(&nfs_fs_type);
456} 395}
457 396
@@ -462,6 +401,7 @@ void nfs_sb_active(struct super_block *sb)
462 if (atomic_inc_return(&server->active) == 1) 401 if (atomic_inc_return(&server->active) == 1)
463 atomic_inc(&sb->s_active); 402 atomic_inc(&sb->s_active);
464} 403}
404EXPORT_SYMBOL_GPL(nfs_sb_active);
465 405
466void nfs_sb_deactive(struct super_block *sb) 406void nfs_sb_deactive(struct super_block *sb)
467{ 407{
@@ -470,11 +410,12 @@ void nfs_sb_deactive(struct super_block *sb)
470 if (atomic_dec_and_test(&server->active)) 410 if (atomic_dec_and_test(&server->active))
471 deactivate_super(sb); 411 deactivate_super(sb);
472} 412}
413EXPORT_SYMBOL_GPL(nfs_sb_deactive);
473 414
474/* 415/*
475 * Deliver file system statistics to userspace 416 * Deliver file system statistics to userspace
476 */ 417 */
477static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) 418int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
478{ 419{
479 struct nfs_server *server = NFS_SB(dentry->d_sb); 420 struct nfs_server *server = NFS_SB(dentry->d_sb);
480 unsigned char blockbits; 421 unsigned char blockbits;
@@ -535,6 +476,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
535 dprintk("%s: statfs error = %d\n", __func__, -error); 476 dprintk("%s: statfs error = %d\n", __func__, -error);
536 return error; 477 return error;
537} 478}
479EXPORT_SYMBOL_GPL(nfs_statfs);
538 480
539/* 481/*
540 * Map the security flavour number to a name 482 * Map the security flavour number to a name
@@ -640,7 +582,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
640 nfs_show_mountd_netid(m, nfss, showdefaults); 582 nfs_show_mountd_netid(m, nfss, showdefaults);
641} 583}
642 584
643#ifdef CONFIG_NFS_V4 585#if IS_ENABLED(CONFIG_NFS_V4)
644static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, 586static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
645 int showdefaults) 587 int showdefaults)
646{ 588{
@@ -757,7 +699,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
757/* 699/*
758 * Describe the mount options on this VFS mountpoint 700 * Describe the mount options on this VFS mountpoint
759 */ 701 */
760static int nfs_show_options(struct seq_file *m, struct dentry *root) 702int nfs_show_options(struct seq_file *m, struct dentry *root)
761{ 703{
762 struct nfs_server *nfss = NFS_SB(root->d_sb); 704 struct nfs_server *nfss = NFS_SB(root->d_sb);
763 705
@@ -771,8 +713,9 @@ static int nfs_show_options(struct seq_file *m, struct dentry *root)
771 713
772 return 0; 714 return 0;
773} 715}
716EXPORT_SYMBOL_GPL(nfs_show_options);
774 717
775#ifdef CONFIG_NFS_V4 718#if IS_ENABLED(CONFIG_NFS_V4)
776#ifdef CONFIG_NFS_V4_1 719#ifdef CONFIG_NFS_V4_1
777static void show_sessions(struct seq_file *m, struct nfs_server *server) 720static void show_sessions(struct seq_file *m, struct nfs_server *server)
778{ 721{
@@ -805,7 +748,7 @@ static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
805 } 748 }
806} 749}
807#else 750#else
808#ifdef CONFIG_NFS_V4 751#if IS_ENABLED(CONFIG_NFS_V4)
809static void show_pnfs(struct seq_file *m, struct nfs_server *server) 752static void show_pnfs(struct seq_file *m, struct nfs_server *server)
810{ 753{
811} 754}
@@ -815,7 +758,7 @@ static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
815} 758}
816#endif 759#endif
817 760
818static int nfs_show_devname(struct seq_file *m, struct dentry *root) 761int nfs_show_devname(struct seq_file *m, struct dentry *root)
819{ 762{
820 char *page = (char *) __get_free_page(GFP_KERNEL); 763 char *page = (char *) __get_free_page(GFP_KERNEL);
821 char *devname, *dummy; 764 char *devname, *dummy;
@@ -830,17 +773,19 @@ static int nfs_show_devname(struct seq_file *m, struct dentry *root)
830 free_page((unsigned long)page); 773 free_page((unsigned long)page);
831 return err; 774 return err;
832} 775}
776EXPORT_SYMBOL_GPL(nfs_show_devname);
833 777
834static int nfs_show_path(struct seq_file *m, struct dentry *dentry) 778int nfs_show_path(struct seq_file *m, struct dentry *dentry)
835{ 779{
836 seq_puts(m, "/"); 780 seq_puts(m, "/");
837 return 0; 781 return 0;
838} 782}
783EXPORT_SYMBOL_GPL(nfs_show_path);
839 784
840/* 785/*
841 * Present statistical information for this VFS mountpoint 786 * Present statistical information for this VFS mountpoint
842 */ 787 */
843static int nfs_show_stats(struct seq_file *m, struct dentry *root) 788int nfs_show_stats(struct seq_file *m, struct dentry *root)
844{ 789{
845 int i, cpu; 790 int i, cpu;
846 struct nfs_server *nfss = NFS_SB(root->d_sb); 791 struct nfs_server *nfss = NFS_SB(root->d_sb);
@@ -870,7 +815,7 @@ static int nfs_show_stats(struct seq_file *m, struct dentry *root)
870 seq_printf(m, ",bsize=%u", nfss->bsize); 815 seq_printf(m, ",bsize=%u", nfss->bsize);
871 seq_printf(m, ",namlen=%u", nfss->namelen); 816 seq_printf(m, ",namlen=%u", nfss->namelen);
872 817
873#ifdef CONFIG_NFS_V4 818#if IS_ENABLED(CONFIG_NFS_V4)
874 if (nfss->nfs_client->rpc_ops->version == 4) { 819 if (nfss->nfs_client->rpc_ops->version == 4) {
875 seq_printf(m, "\n\tnfsv4:\t"); 820 seq_printf(m, "\n\tnfsv4:\t");
876 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); 821 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
@@ -928,12 +873,13 @@ static int nfs_show_stats(struct seq_file *m, struct dentry *root)
928 873
929 return 0; 874 return 0;
930} 875}
876EXPORT_SYMBOL_GPL(nfs_show_stats);
931 877
932/* 878/*
933 * Begin unmount by attempting to remove all automounted mountpoints we added 879 * Begin unmount by attempting to remove all automounted mountpoints we added
934 * in response to xdev traversals and referrals 880 * in response to xdev traversals and referrals
935 */ 881 */
936static void nfs_umount_begin(struct super_block *sb) 882void nfs_umount_begin(struct super_block *sb)
937{ 883{
938 struct nfs_server *server; 884 struct nfs_server *server;
939 struct rpc_clnt *rpc; 885 struct rpc_clnt *rpc;
@@ -947,6 +893,7 @@ static void nfs_umount_begin(struct super_block *sb)
947 if (!IS_ERR(rpc)) 893 if (!IS_ERR(rpc))
948 rpc_killall_tasks(rpc); 894 rpc_killall_tasks(rpc);
949} 895}
896EXPORT_SYMBOL_GPL(nfs_umount_begin);
950 897
951static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) 898static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
952{ 899{
@@ -1590,7 +1537,7 @@ static int nfs_parse_mount_options(char *raw,
1590 1537
1591 /* 1538 /*
1592 * verify that any proto=/mountproto= options match the address 1539 * verify that any proto=/mountproto= options match the address
1593 * familiies in the addr=/mountaddr= options. 1540 * families in the addr=/mountaddr= options.
1594 */ 1541 */
1595 if (protofamily != AF_UNSPEC && 1542 if (protofamily != AF_UNSPEC &&
1596 protofamily != mnt->nfs_server.address.ss_family) 1543 protofamily != mnt->nfs_server.address.ss_family)
@@ -1748,8 +1695,9 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1748 return nfs_walk_authlist(args, &request); 1695 return nfs_walk_authlist(args, &request);
1749} 1696}
1750 1697
1751static struct dentry *nfs_try_mount(int flags, const char *dev_name, 1698struct dentry *nfs_try_mount(int flags, const char *dev_name,
1752 struct nfs_mount_info *mount_info) 1699 struct nfs_mount_info *mount_info,
1700 struct nfs_subversion *nfs_mod)
1753{ 1701{
1754 int status; 1702 int status;
1755 struct nfs_server *server; 1703 struct nfs_server *server;
@@ -1761,12 +1709,13 @@ static struct dentry *nfs_try_mount(int flags, const char *dev_name,
1761 } 1709 }
1762 1710
1763 /* Get a volume representation */ 1711 /* Get a volume representation */
1764 server = nfs_create_server(mount_info->parsed, mount_info->mntfh); 1712 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1765 if (IS_ERR(server)) 1713 if (IS_ERR(server))
1766 return ERR_CAST(server); 1714 return ERR_CAST(server);
1767 1715
1768 return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mount_info); 1716 return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
1769} 1717}
1718EXPORT_SYMBOL_GPL(nfs_try_mount);
1770 1719
1771/* 1720/*
1772 * Split "dev_name" into "hostname:export_path". 1721 * Split "dev_name" into "hostname:export_path".
@@ -1918,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options,
1918 1867
1919 memcpy(sap, &data->addr, sizeof(data->addr)); 1868 memcpy(sap, &data->addr, sizeof(data->addr));
1920 args->nfs_server.addrlen = sizeof(data->addr); 1869 args->nfs_server.addrlen = sizeof(data->addr);
1870 args->nfs_server.port = ntohs(data->addr.sin_port);
1921 if (!nfs_verify_server_address(sap)) 1871 if (!nfs_verify_server_address(sap))
1922 goto out_no_address; 1872 goto out_no_address;
1923 1873
@@ -1970,7 +1920,7 @@ static int nfs23_validate_mount_data(void *options,
1970 return NFS_TEXT_DATA; 1920 return NFS_TEXT_DATA;
1971 } 1921 }
1972 1922
1973#ifndef CONFIG_NFS_V3 1923#if !IS_ENABLED(CONFIG_NFS_V3)
1974 if (args->version == 3) 1924 if (args->version == 3)
1975 goto out_v3_not_compiled; 1925 goto out_v3_not_compiled;
1976#endif /* !CONFIG_NFS_V3 */ 1926#endif /* !CONFIG_NFS_V3 */
@@ -1990,7 +1940,7 @@ out_no_sec:
1990 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); 1940 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
1991 return -EINVAL; 1941 return -EINVAL;
1992 1942
1993#ifndef CONFIG_NFS_V3 1943#if !IS_ENABLED(CONFIG_NFS_V3)
1994out_v3_not_compiled: 1944out_v3_not_compiled:
1995 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n"); 1945 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
1996 return -EPROTONOSUPPORT; 1946 return -EPROTONOSUPPORT;
@@ -2009,7 +1959,7 @@ out_invalid_fh:
2009 return -EINVAL; 1959 return -EINVAL;
2010} 1960}
2011 1961
2012#ifdef CONFIG_NFS_V4 1962#if IS_ENABLED(CONFIG_NFS_V4)
2013static int nfs_validate_mount_data(struct file_system_type *fs_type, 1963static int nfs_validate_mount_data(struct file_system_type *fs_type,
2014 void *options, 1964 void *options,
2015 struct nfs_parsed_mount_data *args, 1965 struct nfs_parsed_mount_data *args,
@@ -2047,7 +1997,7 @@ static int nfs_validate_text_mount_data(void *options,
2047 goto out_no_address; 1997 goto out_no_address;
2048 1998
2049 if (args->version == 4) { 1999 if (args->version == 4) {
2050#ifdef CONFIG_NFS_V4 2000#if IS_ENABLED(CONFIG_NFS_V4)
2051 port = NFS_PORT; 2001 port = NFS_PORT;
2052 max_namelen = NFS4_MAXNAMLEN; 2002 max_namelen = NFS4_MAXNAMLEN;
2053 max_pathlen = NFS4_MAXPATHLEN; 2003 max_pathlen = NFS4_MAXPATHLEN;
@@ -2070,7 +2020,7 @@ static int nfs_validate_text_mount_data(void *options,
2070 &args->nfs_server.export_path, 2020 &args->nfs_server.export_path,
2071 max_pathlen); 2021 max_pathlen);
2072 2022
2073#ifndef CONFIG_NFS_V4 2023#if !IS_ENABLED(CONFIG_NFS_V4)
2074out_v4_not_compiled: 2024out_v4_not_compiled:
2075 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 2025 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
2076 return -EPROTONOSUPPORT; 2026 return -EPROTONOSUPPORT;
@@ -2108,7 +2058,7 @@ nfs_compare_remount_data(struct nfs_server *nfss,
2108 return 0; 2058 return 0;
2109} 2059}
2110 2060
2111static int 2061int
2112nfs_remount(struct super_block *sb, int *flags, char *raw_data) 2062nfs_remount(struct super_block *sb, int *flags, char *raw_data)
2113{ 2063{
2114 int error; 2064 int error;
@@ -2169,11 +2119,12 @@ out:
2169 kfree(data); 2119 kfree(data);
2170 return error; 2120 return error;
2171} 2121}
2122EXPORT_SYMBOL_GPL(nfs_remount);
2172 2123
2173/* 2124/*
2174 * Initialise the common bits of the superblock 2125 * Initialise the common bits of the superblock
2175 */ 2126 */
2176static inline void nfs_initialise_sb(struct super_block *sb) 2127inline void nfs_initialise_sb(struct super_block *sb)
2177{ 2128{
2178 struct nfs_server *server = NFS_SB(sb); 2129 struct nfs_server *server = NFS_SB(sb);
2179 2130
@@ -2195,18 +2146,19 @@ static inline void nfs_initialise_sb(struct super_block *sb)
2195/* 2146/*
2196 * Finish setting up an NFS2/3 superblock 2147 * Finish setting up an NFS2/3 superblock
2197 */ 2148 */
2198static void nfs_fill_super(struct super_block *sb, 2149void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2199 struct nfs_mount_info *mount_info)
2200{ 2150{
2201 struct nfs_parsed_mount_data *data = mount_info->parsed; 2151 struct nfs_parsed_mount_data *data = mount_info->parsed;
2202 struct nfs_server *server = NFS_SB(sb); 2152 struct nfs_server *server = NFS_SB(sb);
2203 2153
2204 sb->s_blocksize_bits = 0; 2154 sb->s_blocksize_bits = 0;
2205 sb->s_blocksize = 0; 2155 sb->s_blocksize = 0;
2206 if (data->bsize) 2156 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
2157 sb->s_op = server->nfs_client->cl_nfs_mod->sops;
2158 if (data && data->bsize)
2207 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); 2159 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
2208 2160
2209 if (server->nfs_client->rpc_ops->version == 3) { 2161 if (server->nfs_client->rpc_ops->version != 2) {
2210 /* The VFS shouldn't apply the umask to mode bits. We will do 2162 /* The VFS shouldn't apply the umask to mode bits. We will do
2211 * so ourselves when necessary. 2163 * so ourselves when necessary.
2212 */ 2164 */
@@ -2214,15 +2166,14 @@ static void nfs_fill_super(struct super_block *sb,
2214 sb->s_time_gran = 1; 2166 sb->s_time_gran = 1;
2215 } 2167 }
2216 2168
2217 sb->s_op = &nfs_sops;
2218 nfs_initialise_sb(sb); 2169 nfs_initialise_sb(sb);
2219} 2170}
2171EXPORT_SYMBOL_GPL(nfs_fill_super);
2220 2172
2221/* 2173/*
2222 * Finish setting up a cloned NFS2/3 superblock 2174 * Finish setting up a cloned NFS2/3/4 superblock
2223 */ 2175 */
2224static void nfs_clone_super(struct super_block *sb, 2176void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2225 struct nfs_mount_info *mount_info)
2226{ 2177{
2227 const struct super_block *old_sb = mount_info->cloned->sb; 2178 const struct super_block *old_sb = mount_info->cloned->sb;
2228 struct nfs_server *server = NFS_SB(sb); 2179 struct nfs_server *server = NFS_SB(sb);
@@ -2230,16 +2181,17 @@ static void nfs_clone_super(struct super_block *sb,
2230 sb->s_blocksize_bits = old_sb->s_blocksize_bits; 2181 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
2231 sb->s_blocksize = old_sb->s_blocksize; 2182 sb->s_blocksize = old_sb->s_blocksize;
2232 sb->s_maxbytes = old_sb->s_maxbytes; 2183 sb->s_maxbytes = old_sb->s_maxbytes;
2184 sb->s_xattr = old_sb->s_xattr;
2185 sb->s_op = old_sb->s_op;
2186 sb->s_time_gran = 1;
2233 2187
2234 if (server->nfs_client->rpc_ops->version == 3) { 2188 if (server->nfs_client->rpc_ops->version != 2) {
2235 /* The VFS shouldn't apply the umask to mode bits. We will do 2189 /* The VFS shouldn't apply the umask to mode bits. We will do
2236 * so ourselves when necessary. 2190 * so ourselves when necessary.
2237 */ 2191 */
2238 sb->s_flags |= MS_POSIXACL; 2192 sb->s_flags |= MS_POSIXACL;
2239 sb->s_time_gran = 1;
2240 } 2193 }
2241 2194
2242 sb->s_op = old_sb->s_op;
2243 nfs_initialise_sb(sb); 2195 nfs_initialise_sb(sb);
2244} 2196}
2245 2197
@@ -2381,14 +2333,15 @@ static int nfs_bdi_register(struct nfs_server *server)
2381 return bdi_register_dev(&server->backing_dev_info, server->s_dev); 2333 return bdi_register_dev(&server->backing_dev_info, server->s_dev);
2382} 2334}
2383 2335
2384static int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot, 2336int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
2385 struct nfs_mount_info *mount_info) 2337 struct nfs_mount_info *mount_info)
2386{ 2338{
2387 return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts); 2339 return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
2388} 2340}
2341EXPORT_SYMBOL_GPL(nfs_set_sb_security);
2389 2342
2390static int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, 2343int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2391 struct nfs_mount_info *mount_info) 2344 struct nfs_mount_info *mount_info)
2392{ 2345{
2393 /* clone any lsm security options from the parent to the new sb */ 2346 /* clone any lsm security options from the parent to the new sb */
2394 security_sb_clone_mnt_opts(mount_info->cloned->sb, s); 2347 security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
@@ -2396,11 +2349,12 @@ static int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2396 return -ESTALE; 2349 return -ESTALE;
2397 return 0; 2350 return 0;
2398} 2351}
2352EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
2399 2353
2400static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type, 2354struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2401 struct nfs_server *server, 2355 int flags, const char *dev_name,
2402 int flags, const char *dev_name, 2356 struct nfs_mount_info *mount_info,
2403 struct nfs_mount_info *mount_info) 2357 struct nfs_subversion *nfs_mod)
2404{ 2358{
2405 struct super_block *s; 2359 struct super_block *s;
2406 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2360 struct dentry *mntroot = ERR_PTR(-ENOMEM);
@@ -2419,7 +2373,7 @@ static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
2419 sb_mntdata.mntflags |= MS_SYNCHRONOUS; 2373 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2420 2374
2421 /* Get a superblock - note that we may end up sharing one that already exists */ 2375 /* Get a superblock - note that we may end up sharing one that already exists */
2422 s = sget(fs_type, compare_super, nfs_set_super, flags, &sb_mntdata); 2376 s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
2423 if (IS_ERR(s)) { 2377 if (IS_ERR(s)) {
2424 mntroot = ERR_CAST(s); 2378 mntroot = ERR_CAST(s);
2425 goto out_err_nosb; 2379 goto out_err_nosb;
@@ -2469,8 +2423,9 @@ error_splat_bdi:
2469 deactivate_locked_super(s); 2423 deactivate_locked_super(s);
2470 goto out; 2424 goto out;
2471} 2425}
2426EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
2472 2427
2473static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, 2428struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2474 int flags, const char *dev_name, void *raw_data) 2429 int flags, const char *dev_name, void *raw_data)
2475{ 2430{
2476 struct nfs_mount_info mount_info = { 2431 struct nfs_mount_info mount_info = {
@@ -2478,6 +2433,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2478 .set_security = nfs_set_sb_security, 2433 .set_security = nfs_set_sb_security,
2479 }; 2434 };
2480 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2435 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2436 struct nfs_subversion *nfs_mod;
2481 int error; 2437 int error;
2482 2438
2483 mount_info.parsed = nfs_alloc_parsed_mount_data(); 2439 mount_info.parsed = nfs_alloc_parsed_mount_data();
@@ -2494,34 +2450,38 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2494 goto out; 2450 goto out;
2495 } 2451 }
2496 2452
2497#ifdef CONFIG_NFS_V4 2453 nfs_mod = get_nfs_version(mount_info.parsed->version);
2498 if (mount_info.parsed->version == 4) 2454 if (IS_ERR(nfs_mod)) {
2499 mntroot = nfs4_try_mount(flags, dev_name, &mount_info); 2455 mntroot = ERR_CAST(nfs_mod);
2500 else 2456 goto out;
2501#endif /* CONFIG_NFS_V4 */ 2457 }
2502 mntroot = nfs_try_mount(flags, dev_name, &mount_info); 2458
2459 mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
2503 2460
2461 put_nfs_version(nfs_mod);
2504out: 2462out:
2505 nfs_free_parsed_mount_data(mount_info.parsed); 2463 nfs_free_parsed_mount_data(mount_info.parsed);
2506 nfs_free_fhandle(mount_info.mntfh); 2464 nfs_free_fhandle(mount_info.mntfh);
2507 return mntroot; 2465 return mntroot;
2508} 2466}
2467EXPORT_SYMBOL_GPL(nfs_fs_mount);
2509 2468
2510/* 2469/*
2511 * Ensure that we unregister the bdi before kill_anon_super 2470 * Ensure that we unregister the bdi before kill_anon_super
2512 * releases the device name 2471 * releases the device name
2513 */ 2472 */
2514static void nfs_put_super(struct super_block *s) 2473void nfs_put_super(struct super_block *s)
2515{ 2474{
2516 struct nfs_server *server = NFS_SB(s); 2475 struct nfs_server *server = NFS_SB(s);
2517 2476
2518 bdi_unregister(&server->backing_dev_info); 2477 bdi_unregister(&server->backing_dev_info);
2519} 2478}
2479EXPORT_SYMBOL_GPL(nfs_put_super);
2520 2480
2521/* 2481/*
2522 * Destroy an NFS2/3 superblock 2482 * Destroy an NFS2/3 superblock
2523 */ 2483 */
2524static void nfs_kill_super(struct super_block *s) 2484void nfs_kill_super(struct super_block *s)
2525{ 2485{
2526 struct nfs_server *server = NFS_SB(s); 2486 struct nfs_server *server = NFS_SB(s);
2527 2487
@@ -2529,31 +2489,38 @@ static void nfs_kill_super(struct super_block *s)
2529 nfs_fscache_release_super_cookie(s); 2489 nfs_fscache_release_super_cookie(s);
2530 nfs_free_server(server); 2490 nfs_free_server(server);
2531} 2491}
2492EXPORT_SYMBOL_GPL(nfs_kill_super);
2532 2493
2533/* 2494/*
2534 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change) 2495 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
2535 */ 2496 */
2536static struct dentry * 2497struct dentry *
2537nfs_xdev_mount_common(struct file_system_type *fs_type, int flags, 2498nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2538 const char *dev_name, struct nfs_mount_info *mount_info) 2499 const char *dev_name, void *raw_data)
2539{ 2500{
2540 struct nfs_clone_mount *data = mount_info->cloned; 2501 struct nfs_clone_mount *data = raw_data;
2502 struct nfs_mount_info mount_info = {
2503 .fill_super = nfs_clone_super,
2504 .set_security = nfs_clone_sb_security,
2505 .cloned = data,
2506 };
2541 struct nfs_server *server; 2507 struct nfs_server *server;
2542 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2508 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2509 struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
2543 int error; 2510 int error;
2544 2511
2545 dprintk("--> nfs_xdev_mount_common()\n"); 2512 dprintk("--> nfs_xdev_mount_common()\n");
2546 2513
2547 mount_info->mntfh = data->fh; 2514 mount_info.mntfh = mount_info.cloned->fh;
2548 2515
2549 /* create a new volume representation */ 2516 /* create a new volume representation */
2550 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); 2517 server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
2551 if (IS_ERR(server)) { 2518 if (IS_ERR(server)) {
2552 error = PTR_ERR(server); 2519 error = PTR_ERR(server);
2553 goto out_err; 2520 goto out_err;
2554 } 2521 }
2555 2522
2556 mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info); 2523 mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod);
2557 dprintk("<-- nfs_xdev_mount_common() = 0\n"); 2524 dprintk("<-- nfs_xdev_mount_common() = 0\n");
2558out: 2525out:
2559 return mntroot; 2526 return mntroot;
@@ -2563,60 +2530,7 @@ out_err:
2563 goto out; 2530 goto out;
2564} 2531}
2565 2532
2566/* 2533#if IS_ENABLED(CONFIG_NFS_V4)
2567 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
2568 */
2569static struct dentry *
2570nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2571 const char *dev_name, void *raw_data)
2572{
2573 struct nfs_mount_info mount_info = {
2574 .fill_super = nfs_clone_super,
2575 .set_security = nfs_clone_sb_security,
2576 .cloned = raw_data,
2577 };
2578 return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
2579}
2580
2581#ifdef CONFIG_NFS_V4
2582
2583/*
2584 * Finish setting up a cloned NFS4 superblock
2585 */
2586static void nfs4_clone_super(struct super_block *sb,
2587 struct nfs_mount_info *mount_info)
2588{
2589 const struct super_block *old_sb = mount_info->cloned->sb;
2590 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
2591 sb->s_blocksize = old_sb->s_blocksize;
2592 sb->s_maxbytes = old_sb->s_maxbytes;
2593 sb->s_time_gran = 1;
2594 sb->s_op = old_sb->s_op;
2595 /*
2596 * The VFS shouldn't apply the umask to mode bits. We will do
2597 * so ourselves when necessary.
2598 */
2599 sb->s_flags |= MS_POSIXACL;
2600 sb->s_xattr = old_sb->s_xattr;
2601 nfs_initialise_sb(sb);
2602}
2603
2604/*
2605 * Set up an NFS4 superblock
2606 */
2607static void nfs4_fill_super(struct super_block *sb,
2608 struct nfs_mount_info *mount_info)
2609{
2610 sb->s_time_gran = 1;
2611 sb->s_op = &nfs4_sops;
2612 /*
2613 * The VFS shouldn't apply the umask to mode bits. We will do
2614 * so ourselves when necessary.
2615 */
2616 sb->s_flags |= MS_POSIXACL;
2617 sb->s_xattr = nfs4_xattr_handlers;
2618 nfs_initialise_sb(sb);
2619}
2620 2534
2621static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) 2535static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2622{ 2536{
@@ -2651,6 +2565,7 @@ static int nfs4_validate_mount_data(void *options,
2651 return -EFAULT; 2565 return -EFAULT;
2652 if (!nfs_verify_server_address(sap)) 2566 if (!nfs_verify_server_address(sap))
2653 goto out_no_address; 2567 goto out_no_address;
2568 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2654 2569
2655 if (data->auth_flavourlen) { 2570 if (data->auth_flavourlen) {
2656 if (data->auth_flavourlen > 1) 2571 if (data->auth_flavourlen > 1)
@@ -2716,249 +2631,57 @@ out_no_address:
2716} 2631}
2717 2632
2718/* 2633/*
2719 * Get the superblock for the NFS4 root partition 2634 * NFS v4 module parameters need to stay in the
2635 * NFS client for backwards compatibility
2720 */ 2636 */
2721static struct dentry * 2637unsigned int nfs_callback_set_tcpport;
2722nfs4_remote_mount(struct file_system_type *fs_type, int flags, 2638unsigned short nfs_callback_tcpport;
2723 const char *dev_name, void *info) 2639/* Default cache timeout is 10 minutes */
2724{ 2640unsigned int nfs_idmap_cache_timeout = 600;
2725 struct nfs_mount_info *mount_info = info; 2641/* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
2726 struct nfs_server *server; 2642bool nfs4_disable_idmapping = true;
2727 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2643unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
2728 2644unsigned short send_implementation_id = 1;
2729 mount_info->fill_super = nfs4_fill_super; 2645
2730 mount_info->set_security = nfs_set_sb_security; 2646EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
2731 2647EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
2732 /* Get a volume representation */ 2648EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
2733 server = nfs4_create_server(mount_info->parsed, mount_info->mntfh); 2649EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
2734 if (IS_ERR(server)) { 2650EXPORT_SYMBOL_GPL(max_session_slots);
2735 mntroot = ERR_CAST(server); 2651EXPORT_SYMBOL_GPL(send_implementation_id);
2736 goto out; 2652
2737 } 2653#define NFS_CALLBACK_MAXPORTNR (65535U)
2738 2654
2739 mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info); 2655static int param_set_portnr(const char *val, const struct kernel_param *kp)
2740 2656{
2741out: 2657 unsigned long num;
2742 return mntroot; 2658 int ret;
2743}
2744
2745static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,
2746 int flags, void *data, const char *hostname)
2747{
2748 struct vfsmount *root_mnt;
2749 char *root_devname;
2750 size_t len;
2751 2659
2752 len = strlen(hostname) + 5; 2660 if (!val)
2753 root_devname = kmalloc(len, GFP_KERNEL); 2661 return -EINVAL;
2754 if (root_devname == NULL) 2662 ret = strict_strtoul(val, 0, &num);
2755 return ERR_PTR(-ENOMEM); 2663 if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
2756 /* Does hostname needs to be enclosed in brackets? */ 2664 return -EINVAL;
2757 if (strchr(hostname, ':')) 2665 *((unsigned int *)kp->arg) = num;
2758 snprintf(root_devname, len, "[%s]:/", hostname); 2666 return 0;
2759 else
2760 snprintf(root_devname, len, "%s:/", hostname);
2761 root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
2762 kfree(root_devname);
2763 return root_mnt;
2764} 2667}
2765 2668static struct kernel_param_ops param_ops_portnr = {
2766struct nfs_referral_count { 2669 .set = param_set_portnr,
2767 struct list_head list; 2670 .get = param_get_uint,
2768 const struct task_struct *task;
2769 unsigned int referral_count;
2770}; 2671};
2771 2672#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
2772static LIST_HEAD(nfs_referral_count_list); 2673
2773static DEFINE_SPINLOCK(nfs_referral_count_list_lock); 2674module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
2774 2675module_param(nfs_idmap_cache_timeout, int, 0644);
2775static struct nfs_referral_count *nfs_find_referral_count(void) 2676module_param(nfs4_disable_idmapping, bool, 0644);
2776{ 2677MODULE_PARM_DESC(nfs4_disable_idmapping,
2777 struct nfs_referral_count *p; 2678 "Turn off NFSv4 idmapping when using 'sec=sys'");
2778 2679module_param(max_session_slots, ushort, 0644);
2779 list_for_each_entry(p, &nfs_referral_count_list, list) { 2680MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
2780 if (p->task == current) 2681 "requests the client will negotiate");
2781 return p; 2682module_param(send_implementation_id, ushort, 0644);
2782 } 2683MODULE_PARM_DESC(send_implementation_id,
2783 return NULL; 2684 "Send implementation ID with NFSv4.1 exchange_id");
2784} 2685MODULE_ALIAS("nfs4");
2785
2786#define NFS_MAX_NESTED_REFERRALS 2
2787
2788static int nfs_referral_loop_protect(void)
2789{
2790 struct nfs_referral_count *p, *new;
2791 int ret = -ENOMEM;
2792
2793 new = kmalloc(sizeof(*new), GFP_KERNEL);
2794 if (!new)
2795 goto out;
2796 new->task = current;
2797 new->referral_count = 1;
2798
2799 ret = 0;
2800 spin_lock(&nfs_referral_count_list_lock);
2801 p = nfs_find_referral_count();
2802 if (p != NULL) {
2803 if (p->referral_count >= NFS_MAX_NESTED_REFERRALS)
2804 ret = -ELOOP;
2805 else
2806 p->referral_count++;
2807 } else {
2808 list_add(&new->list, &nfs_referral_count_list);
2809 new = NULL;
2810 }
2811 spin_unlock(&nfs_referral_count_list_lock);
2812 kfree(new);
2813out:
2814 return ret;
2815}
2816
2817static void nfs_referral_loop_unprotect(void)
2818{
2819 struct nfs_referral_count *p;
2820
2821 spin_lock(&nfs_referral_count_list_lock);
2822 p = nfs_find_referral_count();
2823 p->referral_count--;
2824 if (p->referral_count == 0)
2825 list_del(&p->list);
2826 else
2827 p = NULL;
2828 spin_unlock(&nfs_referral_count_list_lock);
2829 kfree(p);
2830}
2831
2832static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
2833 const char *export_path)
2834{
2835 struct dentry *dentry;
2836 int err;
2837
2838 if (IS_ERR(root_mnt))
2839 return ERR_CAST(root_mnt);
2840
2841 err = nfs_referral_loop_protect();
2842 if (err) {
2843 mntput(root_mnt);
2844 return ERR_PTR(err);
2845 }
2846
2847 dentry = mount_subtree(root_mnt, export_path);
2848 nfs_referral_loop_unprotect();
2849
2850 return dentry;
2851}
2852
2853static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
2854 struct nfs_mount_info *mount_info)
2855{
2856 char *export_path;
2857 struct vfsmount *root_mnt;
2858 struct dentry *res;
2859 struct nfs_parsed_mount_data *data = mount_info->parsed;
2860
2861 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
2862
2863 mount_info->fill_super = nfs4_fill_super;
2864
2865 export_path = data->nfs_server.export_path;
2866 data->nfs_server.export_path = "/";
2867 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
2868 data->nfs_server.hostname);
2869 data->nfs_server.export_path = export_path;
2870
2871 res = nfs_follow_remote_path(root_mnt, export_path);
2872
2873 dfprintk(MOUNT, "<-- nfs4_try_mount() = %ld%s\n",
2874 IS_ERR(res) ? PTR_ERR(res) : 0,
2875 IS_ERR(res) ? " [error]" : "");
2876 return res;
2877}
2878
2879static void nfs4_kill_super(struct super_block *sb)
2880{
2881 struct nfs_server *server = NFS_SB(sb);
2882
2883 dprintk("--> %s\n", __func__);
2884 nfs_super_return_all_delegations(sb);
2885 kill_anon_super(sb);
2886 nfs_fscache_release_super_cookie(sb);
2887 nfs_free_server(server);
2888 dprintk("<-- %s\n", __func__);
2889}
2890
2891/*
2892 * Clone an NFS4 server record on xdev traversal (FSID-change)
2893 */
2894static struct dentry *
2895nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
2896 const char *dev_name, void *raw_data)
2897{
2898 struct nfs_mount_info mount_info = {
2899 .fill_super = nfs4_clone_super,
2900 .set_security = nfs_clone_sb_security,
2901 .cloned = raw_data,
2902 };
2903 return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
2904}
2905
2906static struct dentry *
2907nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
2908 const char *dev_name, void *raw_data)
2909{
2910 struct nfs_mount_info mount_info = {
2911 .fill_super = nfs4_fill_super,
2912 .set_security = nfs_clone_sb_security,
2913 .cloned = raw_data,
2914 };
2915 struct nfs_server *server;
2916 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2917
2918 dprintk("--> nfs4_referral_get_sb()\n");
2919
2920 mount_info.mntfh = nfs_alloc_fhandle();
2921 if (mount_info.cloned == NULL || mount_info.mntfh == NULL)
2922 goto out;
2923
2924 /* create a new volume representation */
2925 server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh);
2926 if (IS_ERR(server)) {
2927 mntroot = ERR_CAST(server);
2928 goto out;
2929 }
2930
2931 mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info);
2932out:
2933 nfs_free_fhandle(mount_info.mntfh);
2934 return mntroot;
2935}
2936
2937/*
2938 * Create an NFS4 server record on referral traversal
2939 */
2940static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
2941 int flags, const char *dev_name, void *raw_data)
2942{
2943 struct nfs_clone_mount *data = raw_data;
2944 char *export_path;
2945 struct vfsmount *root_mnt;
2946 struct dentry *res;
2947
2948 dprintk("--> nfs4_referral_mount()\n");
2949
2950 export_path = data->mnt_path;
2951 data->mnt_path = "/";
2952
2953 root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type,
2954 flags, data, data->hostname);
2955 data->mnt_path = export_path;
2956
2957 res = nfs_follow_remote_path(root_mnt, export_path);
2958 dprintk("<-- nfs4_referral_mount() = %ld%s\n",
2959 IS_ERR(res) ? PTR_ERR(res) : 0,
2960 IS_ERR(res) ? " [error]" : "");
2961 return res;
2962}
2963 2686
2964#endif /* CONFIG_NFS_V4 */ 2687#endif /* CONFIG_NFS_V4 */