aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/client.c13
-rw-r--r--fs/nfs/fscache.c25
-rw-r--r--fs/nfs/fscache.h6
-rw-r--r--fs/nfs/super.c76
-rw-r--r--include/linux/sunrpc/xdr.h5
-rw-r--r--net/sunrpc/rpc_pipe.c3
-rw-r--r--net/sunrpc/xprtsock.c9
7 files changed, 89 insertions, 48 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 152025358dad..63976c0ccc25 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -648,8 +648,6 @@ static int nfs_start_lockd(struct nfs_server *server)
648 .hostname = clp->cl_hostname, 648 .hostname = clp->cl_hostname,
649 .address = (struct sockaddr *)&clp->cl_addr, 649 .address = (struct sockaddr *)&clp->cl_addr,
650 .addrlen = clp->cl_addrlen, 650 .addrlen = clp->cl_addrlen,
651 .protocol = server->flags & NFS_MOUNT_TCP ?
652 IPPROTO_TCP : IPPROTO_UDP,
653 .nfs_version = clp->rpc_ops->version, 651 .nfs_version = clp->rpc_ops->version,
654 .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? 652 .noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
655 1 : 0, 653 1 : 0,
@@ -660,6 +658,14 @@ static int nfs_start_lockd(struct nfs_server *server)
660 if (server->flags & NFS_MOUNT_NONLM) 658 if (server->flags & NFS_MOUNT_NONLM)
661 return 0; 659 return 0;
662 660
661 switch (clp->cl_proto) {
662 default:
663 nlm_init.protocol = IPPROTO_TCP;
664 break;
665 case XPRT_TRANSPORT_UDP:
666 nlm_init.protocol = IPPROTO_UDP;
667 }
668
663 host = nlmclnt_init(&nlm_init); 669 host = nlmclnt_init(&nlm_init);
664 if (IS_ERR(host)) 670 if (IS_ERR(host))
665 return PTR_ERR(host); 671 return PTR_ERR(host);
@@ -787,7 +793,7 @@ static int nfs_init_server(struct nfs_server *server,
787 dprintk("--> nfs_init_server()\n"); 793 dprintk("--> nfs_init_server()\n");
788 794
789#ifdef CONFIG_NFS_V3 795#ifdef CONFIG_NFS_V3
790 if (data->flags & NFS_MOUNT_VER3) 796 if (data->version == 3)
791 cl_init.rpc_ops = &nfs_v3_clientops; 797 cl_init.rpc_ops = &nfs_v3_clientops;
792#endif 798#endif
793 799
@@ -964,6 +970,7 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve
964 target->acdirmin = source->acdirmin; 970 target->acdirmin = source->acdirmin;
965 target->acdirmax = source->acdirmax; 971 target->acdirmax = source->acdirmax;
966 target->caps = source->caps; 972 target->caps = source->caps;
973 target->options = source->options;
967} 974}
968 975
969/* 976/*
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 379be678cb7e..70fad69eb959 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -58,17 +58,34 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp)
58/* 58/*
59 * Get the cache cookie for an NFS superblock. We have to handle 59 * Get the cache cookie for an NFS superblock. We have to handle
60 * uniquification here because the cache doesn't do it for us. 60 * uniquification here because the cache doesn't do it for us.
61 *
62 * The default uniquifier is just an empty string, but it may be overridden
63 * either by the 'fsc=xxx' option to mount, or by inheriting it from the parent
64 * superblock across an automount point of some nature.
61 */ 65 */
62void nfs_fscache_get_super_cookie(struct super_block *sb, 66void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq,
63 struct nfs_parsed_mount_data *data) 67 struct nfs_clone_mount *mntdata)
64{ 68{
65 struct nfs_fscache_key *key, *xkey; 69 struct nfs_fscache_key *key, *xkey;
66 struct nfs_server *nfss = NFS_SB(sb); 70 struct nfs_server *nfss = NFS_SB(sb);
67 struct rb_node **p, *parent; 71 struct rb_node **p, *parent;
68 const char *uniq = data->fscache_uniq ?: "";
69 int diff, ulen; 72 int diff, ulen;
70 73
71 ulen = strlen(uniq); 74 if (uniq) {
75 ulen = strlen(uniq);
76 } else if (mntdata) {
77 struct nfs_server *mnt_s = NFS_SB(mntdata->sb);
78 if (mnt_s->fscache_key) {
79 uniq = mnt_s->fscache_key->key.uniquifier;
80 ulen = mnt_s->fscache_key->key.uniq_len;
81 }
82 }
83
84 if (!uniq) {
85 uniq = "";
86 ulen = 1;
87 }
88
72 key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL); 89 key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
73 if (!key) 90 if (!key)
74 return; 91 return;
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index 6e809bb0ff08..b9c572d0679f 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -74,7 +74,8 @@ extern void nfs_fscache_get_client_cookie(struct nfs_client *);
74extern void nfs_fscache_release_client_cookie(struct nfs_client *); 74extern void nfs_fscache_release_client_cookie(struct nfs_client *);
75 75
76extern void nfs_fscache_get_super_cookie(struct super_block *, 76extern void nfs_fscache_get_super_cookie(struct super_block *,
77 struct nfs_parsed_mount_data *); 77 const char *,
78 struct nfs_clone_mount *);
78extern void nfs_fscache_release_super_cookie(struct super_block *); 79extern void nfs_fscache_release_super_cookie(struct super_block *);
79 80
80extern void nfs_fscache_init_inode_cookie(struct inode *); 81extern void nfs_fscache_init_inode_cookie(struct inode *);
@@ -173,7 +174,8 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
173 174
174static inline void nfs_fscache_get_super_cookie( 175static inline void nfs_fscache_get_super_cookie(
175 struct super_block *sb, 176 struct super_block *sb,
176 struct nfs_parsed_mount_data *data) 177 const char *uniq,
178 struct nfs_clone_mount *mntdata)
177{ 179{
178} 180}
179static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} 181static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f1cc0587cfef..810770f96816 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -728,6 +728,27 @@ static void nfs_umount_begin(struct super_block *sb)
728 unlock_kernel(); 728 unlock_kernel();
729} 729}
730 730
731static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags)
732{
733 struct nfs_parsed_mount_data *data;
734
735 data = kzalloc(sizeof(*data), GFP_KERNEL);
736 if (data) {
737 data->flags = flags;
738 data->rsize = NFS_MAX_FILE_IO_SIZE;
739 data->wsize = NFS_MAX_FILE_IO_SIZE;
740 data->acregmin = NFS_DEF_ACREGMIN;
741 data->acregmax = NFS_DEF_ACREGMAX;
742 data->acdirmin = NFS_DEF_ACDIRMIN;
743 data->acdirmax = NFS_DEF_ACDIRMAX;
744 data->nfs_server.port = NFS_UNSPEC_PORT;
745 data->auth_flavors[0] = RPC_AUTH_UNIX;
746 data->auth_flavor_len = 1;
747 data->minorversion = 0;
748 }
749 return data;
750}
751
731/* 752/*
732 * Sanity-check a server address provided by the mount command. 753 * Sanity-check a server address provided by the mount command.
733 * 754 *
@@ -1430,10 +1451,13 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1430 int status; 1451 int status;
1431 1452
1432 if (args->mount_server.version == 0) { 1453 if (args->mount_server.version == 0) {
1433 if (args->flags & NFS_MOUNT_VER3) 1454 switch (args->version) {
1434 args->mount_server.version = NFS_MNT3_VERSION; 1455 default:
1435 else 1456 args->mount_server.version = NFS_MNT3_VERSION;
1436 args->mount_server.version = NFS_MNT_VERSION; 1457 break;
1458 case 2:
1459 args->mount_server.version = NFS_MNT_VERSION;
1460 }
1437 } 1461 }
1438 request.version = args->mount_server.version; 1462 request.version = args->mount_server.version;
1439 1463
@@ -1634,20 +1658,6 @@ static int nfs_validate_mount_data(void *options,
1634 if (data == NULL) 1658 if (data == NULL)
1635 goto out_no_data; 1659 goto out_no_data;
1636 1660
1637 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
1638 args->rsize = NFS_MAX_FILE_IO_SIZE;
1639 args->wsize = NFS_MAX_FILE_IO_SIZE;
1640 args->acregmin = NFS_DEF_ACREGMIN;
1641 args->acregmax = NFS_DEF_ACREGMAX;
1642 args->acdirmin = NFS_DEF_ACDIRMIN;
1643 args->acdirmax = NFS_DEF_ACDIRMAX;
1644 args->mount_server.port = NFS_UNSPEC_PORT;
1645 args->nfs_server.port = NFS_UNSPEC_PORT;
1646 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1647 args->auth_flavors[0] = RPC_AUTH_UNIX;
1648 args->auth_flavor_len = 1;
1649 args->minorversion = 0;
1650
1651 switch (data->version) { 1661 switch (data->version) {
1652 case 1: 1662 case 1:
1653 data->namlen = 0; 1663 data->namlen = 0;
@@ -1778,7 +1788,7 @@ static int nfs_validate_mount_data(void *options,
1778 } 1788 }
1779 1789
1780#ifndef CONFIG_NFS_V3 1790#ifndef CONFIG_NFS_V3
1781 if (args->flags & NFS_MOUNT_VER3) 1791 if (args->version == 3)
1782 goto out_v3_not_compiled; 1792 goto out_v3_not_compiled;
1783#endif /* !CONFIG_NFS_V3 */ 1793#endif /* !CONFIG_NFS_V3 */
1784 1794
@@ -1936,7 +1946,7 @@ static void nfs_fill_super(struct super_block *sb,
1936 if (data->bsize) 1946 if (data->bsize)
1937 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); 1947 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
1938 1948
1939 if (server->flags & NFS_MOUNT_VER3) { 1949 if (server->nfs_client->rpc_ops->version == 3) {
1940 /* The VFS shouldn't apply the umask to mode bits. We will do 1950 /* The VFS shouldn't apply the umask to mode bits. We will do
1941 * so ourselves when necessary. 1951 * so ourselves when necessary.
1942 */ 1952 */
@@ -1960,7 +1970,7 @@ static void nfs_clone_super(struct super_block *sb,
1960 sb->s_blocksize = old_sb->s_blocksize; 1970 sb->s_blocksize = old_sb->s_blocksize;
1961 sb->s_maxbytes = old_sb->s_maxbytes; 1971 sb->s_maxbytes = old_sb->s_maxbytes;
1962 1972
1963 if (server->flags & NFS_MOUNT_VER3) { 1973 if (server->nfs_client->rpc_ops->version == 3) {
1964 /* The VFS shouldn't apply the umask to mode bits. We will do 1974 /* The VFS shouldn't apply the umask to mode bits. We will do
1965 * so ourselves when necessary. 1975 * so ourselves when necessary.
1966 */ 1976 */
@@ -2094,7 +2104,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
2094 }; 2104 };
2095 int error = -ENOMEM; 2105 int error = -ENOMEM;
2096 2106
2097 data = kzalloc(sizeof(*data), GFP_KERNEL); 2107 data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
2098 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); 2108 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
2099 if (data == NULL || mntfh == NULL) 2109 if (data == NULL || mntfh == NULL)
2100 goto out_free_fh; 2110 goto out_free_fh;
@@ -2144,7 +2154,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
2144 if (!s->s_root) { 2154 if (!s->s_root) {
2145 /* initial superblock/root creation */ 2155 /* initial superblock/root creation */
2146 nfs_fill_super(s, data); 2156 nfs_fill_super(s, data);
2147 nfs_fscache_get_super_cookie(s, data); 2157 nfs_fscache_get_super_cookie(
2158 s, data ? data->fscache_uniq : NULL, NULL);
2148 } 2159 }
2149 2160
2150 mntroot = nfs_get_root(s, mntfh); 2161 mntroot = nfs_get_root(s, mntfh);
@@ -2245,6 +2256,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
2245 if (!s->s_root) { 2256 if (!s->s_root) {
2246 /* initial superblock/root creation */ 2257 /* initial superblock/root creation */
2247 nfs_clone_super(s, data->sb); 2258 nfs_clone_super(s, data->sb);
2259 nfs_fscache_get_super_cookie(s, NULL, data);
2248 } 2260 }
2249 2261
2250 mntroot = nfs_get_root(s, data->fh); 2262 mntroot = nfs_get_root(s, data->fh);
@@ -2362,18 +2374,7 @@ static int nfs4_validate_mount_data(void *options,
2362 if (data == NULL) 2374 if (data == NULL)
2363 goto out_no_data; 2375 goto out_no_data;
2364 2376
2365 args->rsize = NFS_MAX_FILE_IO_SIZE;
2366 args->wsize = NFS_MAX_FILE_IO_SIZE;
2367 args->acregmin = NFS_DEF_ACREGMIN;
2368 args->acregmax = NFS_DEF_ACREGMAX;
2369 args->acdirmin = NFS_DEF_ACDIRMIN;
2370 args->acdirmax = NFS_DEF_ACDIRMAX;
2371 args->nfs_server.port = NFS_UNSPEC_PORT;
2372 args->auth_flavors[0] = RPC_AUTH_UNIX;
2373 args->auth_flavor_len = 1;
2374 args->version = 4; 2377 args->version = 4;
2375 args->minorversion = 0;
2376
2377 switch (data->version) { 2378 switch (data->version) {
2378 case 1: 2379 case 1:
2379 if (data->host_addrlen > sizeof(args->nfs_server.address)) 2380 if (data->host_addrlen > sizeof(args->nfs_server.address))
@@ -2508,7 +2509,8 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
2508 if (!s->s_root) { 2509 if (!s->s_root) {
2509 /* initial superblock/root creation */ 2510 /* initial superblock/root creation */
2510 nfs4_fill_super(s); 2511 nfs4_fill_super(s);
2511 nfs_fscache_get_super_cookie(s, data); 2512 nfs_fscache_get_super_cookie(
2513 s, data ? data->fscache_uniq : NULL, NULL);
2512 } 2514 }
2513 2515
2514 mntroot = nfs4_get_root(s, mntfh); 2516 mntroot = nfs4_get_root(s, mntfh);
@@ -2656,7 +2658,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
2656 struct nfs_parsed_mount_data *data; 2658 struct nfs_parsed_mount_data *data;
2657 int error = -ENOMEM; 2659 int error = -ENOMEM;
2658 2660
2659 data = kzalloc(sizeof(*data), GFP_KERNEL); 2661 data = nfs_alloc_parsed_mount_data(0);
2660 if (data == NULL) 2662 if (data == NULL)
2661 goto out_free_data; 2663 goto out_free_data;
2662 2664
@@ -2741,6 +2743,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
2741 if (!s->s_root) { 2743 if (!s->s_root) {
2742 /* initial superblock/root creation */ 2744 /* initial superblock/root creation */
2743 nfs4_clone_super(s, data->sb); 2745 nfs4_clone_super(s, data->sb);
2746 nfs_fscache_get_super_cookie(s, NULL, data);
2744 } 2747 }
2745 2748
2746 mntroot = nfs4_get_root(s, data->fh); 2749 mntroot = nfs4_get_root(s, data->fh);
@@ -2822,6 +2825,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
2822 if (!s->s_root) { 2825 if (!s->s_root) {
2823 /* initial superblock/root creation */ 2826 /* initial superblock/root creation */
2824 nfs4_fill_super(s); 2827 nfs4_fill_super(s);
2828 nfs_fscache_get_super_cookie(s, NULL, data);
2825 } 2829 }
2826 2830
2827 mntroot = nfs4_get_root(s, &mntfh); 2831 mntroot = nfs4_get_root(s, &mntfh);
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 7da466ba4b0d..f5cc0898bc53 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -11,6 +11,7 @@
11 11
12#include <linux/uio.h> 12#include <linux/uio.h>
13#include <asm/byteorder.h> 13#include <asm/byteorder.h>
14#include <asm/unaligned.h>
14#include <linux/scatterlist.h> 15#include <linux/scatterlist.h>
15 16
16/* 17/*
@@ -117,14 +118,14 @@ static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int le
117static inline __be32 * 118static inline __be32 *
118xdr_encode_hyper(__be32 *p, __u64 val) 119xdr_encode_hyper(__be32 *p, __u64 val)
119{ 120{
120 *(__be64 *)p = cpu_to_be64(val); 121 put_unaligned_be64(val, p);
121 return p + 2; 122 return p + 2;
122} 123}
123 124
124static inline __be32 * 125static inline __be32 *
125xdr_decode_hyper(__be32 *p, __u64 *valp) 126xdr_decode_hyper(__be32 *p, __u64 *valp)
126{ 127{
127 *valp = be64_to_cpup((__be64 *)p); 128 *valp = get_unaligned_be64(p);
128 return p + 2; 129 return p + 2;
129} 130}
130 131
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 858a443f418f..49278f830367 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -860,7 +860,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
860 860
861/** 861/**
862 * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs 862 * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs
863 * @path: path from the rpc_pipefs root to the new directory 863 * @dentry: dentry from the rpc_pipefs root to the new directory
864 * @name: &struct qstr for the name
864 * @rpc_client: rpc client to associate with this directory 865 * @rpc_client: rpc client to associate with this directory
865 * 866 *
866 * This creates a directory at the given @path associated with 867 * This creates a directory at the given @path associated with
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index bee415465754..37c5475ba258 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -773,6 +773,7 @@ static void xs_close(struct rpc_xprt *xprt)
773 dprintk("RPC: xs_close xprt %p\n", xprt); 773 dprintk("RPC: xs_close xprt %p\n", xprt);
774 774
775 xs_reset_transport(transport); 775 xs_reset_transport(transport);
776 xprt->reestablish_timeout = 0;
776 777
777 smp_mb__before_clear_bit(); 778 smp_mb__before_clear_bit();
778 clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); 779 clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
@@ -1264,6 +1265,12 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
1264 if (xprt->shutdown) 1265 if (xprt->shutdown)
1265 goto out; 1266 goto out;
1266 1267
1268 /* Any data means we had a useful conversation, so
1269 * the we don't need to delay the next reconnect
1270 */
1271 if (xprt->reestablish_timeout)
1272 xprt->reestablish_timeout = 0;
1273
1267 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ 1274 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
1268 rd_desc.arg.data = xprt; 1275 rd_desc.arg.data = xprt;
1269 do { 1276 do {
@@ -2034,6 +2041,8 @@ static void xs_connect(struct rpc_task *task)
2034 &transport->connect_worker, 2041 &transport->connect_worker,
2035 xprt->reestablish_timeout); 2042 xprt->reestablish_timeout);
2036 xprt->reestablish_timeout <<= 1; 2043 xprt->reestablish_timeout <<= 1;
2044 if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
2045 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
2037 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) 2046 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
2038 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; 2047 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
2039 } else { 2048 } else {