aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index d25b5257b7a1..0870d0d4efc0 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -48,6 +48,7 @@
48#include "iostat.h" 48#include "iostat.h"
49#include "internal.h" 49#include "internal.h"
50#include "fscache.h" 50#include "fscache.h"
51#include "pnfs.h"
51 52
52#define NFSDBG_FACILITY NFSDBG_CLIENT 53#define NFSDBG_FACILITY NFSDBG_CLIENT
53 54
@@ -150,11 +151,14 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
150 clp->cl_boot_time = CURRENT_TIME; 151 clp->cl_boot_time = CURRENT_TIME;
151 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 152 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
152 clp->cl_minorversion = cl_init->minorversion; 153 clp->cl_minorversion = cl_init->minorversion;
154 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
153#endif 155#endif
154 cred = rpc_lookup_machine_cred(); 156 cred = rpc_lookup_machine_cred();
155 if (!IS_ERR(cred)) 157 if (!IS_ERR(cred))
156 clp->cl_machine_cred = cred; 158 clp->cl_machine_cred = cred;
157 159#if defined(CONFIG_NFS_V4_1)
160 INIT_LIST_HEAD(&clp->cl_layouts);
161#endif
158 nfs_fscache_get_client_cookie(clp); 162 nfs_fscache_get_client_cookie(clp);
159 163
160 return clp; 164 return clp;
@@ -178,7 +182,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
178 clp->cl_session = NULL; 182 clp->cl_session = NULL;
179 } 183 }
180 184
181 clp->cl_call_sync = _nfs4_call_sync; 185 clp->cl_mvops = nfs_v4_minor_ops[0];
182#endif /* CONFIG_NFS_V4_1 */ 186#endif /* CONFIG_NFS_V4_1 */
183} 187}
184 188
@@ -188,7 +192,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
188static void nfs4_destroy_callback(struct nfs_client *clp) 192static void nfs4_destroy_callback(struct nfs_client *clp)
189{ 193{
190 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) 194 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
191 nfs_callback_down(clp->cl_minorversion); 195 nfs_callback_down(clp->cl_mvops->minor_version);
192} 196}
193 197
194static void nfs4_shutdown_client(struct nfs_client *clp) 198static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -251,6 +255,7 @@ void nfs_put_client(struct nfs_client *clp)
251 nfs_free_client(clp); 255 nfs_free_client(clp);
252 } 256 }
253} 257}
258EXPORT_SYMBOL_GPL(nfs_put_client);
254 259
255#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 260#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
256/* 261/*
@@ -274,7 +279,7 @@ static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
274 sin1->sin6_scope_id != sin2->sin6_scope_id) 279 sin1->sin6_scope_id != sin2->sin6_scope_id)
275 return 0; 280 return 0;
276 281
277 return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr); 282 return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
278} 283}
279#else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */ 284#else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
280static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, 285static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
@@ -600,6 +605,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
600{ 605{
601 struct rpc_clnt *clnt = NULL; 606 struct rpc_clnt *clnt = NULL;
602 struct rpc_create_args args = { 607 struct rpc_create_args args = {
608 .net = &init_net,
603 .protocol = clp->cl_proto, 609 .protocol = clp->cl_proto,
604 .address = (struct sockaddr *)&clp->cl_addr, 610 .address = (struct sockaddr *)&clp->cl_addr,
605 .addrsize = clp->cl_addrlen, 611 .addrsize = clp->cl_addrlen,
@@ -634,7 +640,8 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
634 */ 640 */
635static void nfs_destroy_server(struct nfs_server *server) 641static void nfs_destroy_server(struct nfs_server *server)
636{ 642{
637 if (!(server->flags & NFS_MOUNT_NONLM)) 643 if (!(server->flags & NFS_MOUNT_LOCAL_FLOCK) ||
644 !(server->flags & NFS_MOUNT_LOCAL_FCNTL))
638 nlmclnt_done(server->nlm_host); 645 nlmclnt_done(server->nlm_host);
639} 646}
640 647
@@ -656,7 +663,8 @@ static int nfs_start_lockd(struct nfs_server *server)
656 663
657 if (nlm_init.nfs_version > 3) 664 if (nlm_init.nfs_version > 3)
658 return 0; 665 return 0;
659 if (server->flags & NFS_MOUNT_NONLM) 666 if ((server->flags & NFS_MOUNT_LOCAL_FLOCK) &&
667 (server->flags & NFS_MOUNT_LOCAL_FCNTL))
660 return 0; 668 return 0;
661 669
662 switch (clp->cl_proto) { 670 switch (clp->cl_proto) {
@@ -897,11 +905,13 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
897 if (server->wsize > NFS_MAX_FILE_IO_SIZE) 905 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
898 server->wsize = NFS_MAX_FILE_IO_SIZE; 906 server->wsize = NFS_MAX_FILE_IO_SIZE;
899 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 907 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
908 set_pnfs_layoutdriver(server, fsinfo->layouttype);
909
900 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); 910 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
901 911
902 server->dtsize = nfs_block_size(fsinfo->dtpref, NULL); 912 server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
903 if (server->dtsize > PAGE_CACHE_SIZE) 913 if (server->dtsize > PAGE_CACHE_SIZE * NFS_MAX_READDIR_PAGES)
904 server->dtsize = PAGE_CACHE_SIZE; 914 server->dtsize = PAGE_CACHE_SIZE * NFS_MAX_READDIR_PAGES;
905 if (server->dtsize > server->rsize) 915 if (server->dtsize > server->rsize)
906 server->dtsize = server->rsize; 916 server->dtsize = server->rsize;
907 917
@@ -912,6 +922,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
912 922
913 server->maxfilesize = fsinfo->maxfilesize; 923 server->maxfilesize = fsinfo->maxfilesize;
914 924
925 server->time_delta = fsinfo->time_delta;
926
915 /* We're airborne Set socket buffersize */ 927 /* We're airborne Set socket buffersize */
916 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); 928 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
917} 929}
@@ -934,6 +946,7 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
934 } 946 }
935 947
936 fsinfo.fattr = fattr; 948 fsinfo.fattr = fattr;
949 fsinfo.layouttype = 0;
937 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); 950 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
938 if (error < 0) 951 if (error < 0)
939 goto out_error; 952 goto out_error;
@@ -1016,6 +1029,7 @@ void nfs_free_server(struct nfs_server *server)
1016{ 1029{
1017 dprintk("--> nfs_free_server()\n"); 1030 dprintk("--> nfs_free_server()\n");
1018 1031
1032 unset_pnfs_layoutdriver(server);
1019 spin_lock(&nfs_client_lock); 1033 spin_lock(&nfs_client_lock);
1020 list_del(&server->client_link); 1034 list_del(&server->client_link);
1021 list_del(&server->master_link); 1035 list_del(&server->master_link);
@@ -1126,7 +1140,7 @@ static int nfs4_init_callback(struct nfs_client *clp)
1126 return error; 1140 return error;
1127 } 1141 }
1128 1142
1129 error = nfs_callback_up(clp->cl_minorversion, 1143 error = nfs_callback_up(clp->cl_mvops->minor_version,
1130 clp->cl_rpcclient->cl_xprt); 1144 clp->cl_rpcclient->cl_xprt);
1131 if (error < 0) { 1145 if (error < 0) {
1132 dprintk("%s: failed to start callback. Error = %d\n", 1146 dprintk("%s: failed to start callback. Error = %d\n",
@@ -1143,10 +1157,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
1143 */ 1157 */
1144static int nfs4_init_client_minor_version(struct nfs_client *clp) 1158static int nfs4_init_client_minor_version(struct nfs_client *clp)
1145{ 1159{
1146 clp->cl_call_sync = _nfs4_call_sync;
1147
1148#if defined(CONFIG_NFS_V4_1) 1160#if defined(CONFIG_NFS_V4_1)
1149 if (clp->cl_minorversion) { 1161 if (clp->cl_mvops->minor_version) {
1150 struct nfs4_session *session = NULL; 1162 struct nfs4_session *session = NULL;
1151 /* 1163 /*
1152 * Create the session and mark it expired. 1164 * Create the session and mark it expired.
@@ -1158,7 +1170,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
1158 return -ENOMEM; 1170 return -ENOMEM;
1159 1171
1160 clp->cl_session = session; 1172 clp->cl_session = session;
1161 clp->cl_call_sync = _nfs4_call_sync_session; 1173 /*
1174 * The create session reply races with the server back
1175 * channel probe. Mark the client NFS_CS_SESSION_INITING
1176 * so that the client back channel can find the
1177 * nfs_client struct
1178 */
1179 clp->cl_cons_state = NFS_CS_SESSION_INITING;
1162 } 1180 }
1163#endif /* CONFIG_NFS_V4_1 */ 1181#endif /* CONFIG_NFS_V4_1 */
1164 1182
@@ -1351,8 +1369,9 @@ static int nfs4_init_server(struct nfs_server *server,
1351 1369
1352 /* Initialise the client representation from the mount data */ 1370 /* Initialise the client representation from the mount data */
1353 server->flags = data->flags; 1371 server->flags = data->flags;
1354 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR| 1372 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|NFS_CAP_POSIX_LOCK;
1355 NFS_CAP_POSIX_LOCK; 1373 if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
1374 server->caps |= NFS_CAP_READDIRPLUS;
1356 server->options = data->options; 1375 server->options = data->options;
1357 1376
1358 /* Get a client record */ 1377 /* Get a client record */
@@ -1454,7 +1473,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1454 data->authflavor, 1473 data->authflavor,
1455 parent_server->client->cl_xprt->prot, 1474 parent_server->client->cl_xprt->prot,
1456 parent_server->client->cl_timeout, 1475 parent_server->client->cl_timeout,
1457 parent_client->cl_minorversion); 1476 parent_client->cl_mvops->minor_version);
1458 if (error < 0) 1477 if (error < 0)
1459 goto error; 1478 goto error;
1460 1479