diff options
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r-- | fs/nfs/client.c | 51 |
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) | |||
188 | static void nfs4_destroy_callback(struct nfs_client *clp) | 192 | static 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 | ||
194 | static void nfs4_shutdown_client(struct nfs_client *clp) | 198 | static 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 | } |
258 | EXPORT_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) */ |
280 | static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, | 285 | static 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 | */ |
635 | static void nfs_destroy_server(struct nfs_server *server) | 641 | static 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 | */ |
1144 | static int nfs4_init_client_minor_version(struct nfs_client *clp) | 1158 | static 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 | ||