diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-12-20 16:03:59 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-30 02:05:59 -0500 |
commit | 331702337f2b2e7cef40366ee207a25604df4671 (patch) | |
tree | 72b2a1942cc7e7d0b08a119f10fb2a299f550550 | |
parent | 7a3e3e18e40848b6f01d44407ce86b91b8535fbd (diff) |
NFS: Support per-mountpoint timeout parameters.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/client.c | 82 | ||||
-rw-r--r-- | fs/nfs/super.c | 4 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 2 |
3 files changed, 49 insertions, 39 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 59a6dccab548..03d9bed7849a 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -415,18 +415,16 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, | |||
415 | * Create an RPC client handle | 415 | * Create an RPC client handle |
416 | */ | 416 | */ |
417 | static int nfs_create_rpc_client(struct nfs_client *clp, int proto, | 417 | static int nfs_create_rpc_client(struct nfs_client *clp, int proto, |
418 | unsigned int timeo, | 418 | const struct rpc_timeout *timeparms, |
419 | unsigned int retrans, | 419 | rpc_authflavor_t flavor, |
420 | rpc_authflavor_t flavor, | 420 | int flags) |
421 | int flags) | ||
422 | { | 421 | { |
423 | struct rpc_timeout timeparms; | ||
424 | struct rpc_clnt *clnt = NULL; | 422 | struct rpc_clnt *clnt = NULL; |
425 | struct rpc_create_args args = { | 423 | struct rpc_create_args args = { |
426 | .protocol = proto, | 424 | .protocol = proto, |
427 | .address = (struct sockaddr *)&clp->cl_addr, | 425 | .address = (struct sockaddr *)&clp->cl_addr, |
428 | .addrsize = clp->cl_addrlen, | 426 | .addrsize = clp->cl_addrlen, |
429 | .timeout = &timeparms, | 427 | .timeout = timeparms, |
430 | .servername = clp->cl_hostname, | 428 | .servername = clp->cl_hostname, |
431 | .program = &nfs_program, | 429 | .program = &nfs_program, |
432 | .version = clp->rpc_ops->version, | 430 | .version = clp->rpc_ops->version, |
@@ -437,10 +435,6 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto, | |||
437 | if (!IS_ERR(clp->cl_rpcclient)) | 435 | if (!IS_ERR(clp->cl_rpcclient)) |
438 | return 0; | 436 | return 0; |
439 | 437 | ||
440 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); | ||
441 | clp->retrans_timeo = timeparms.to_initval; | ||
442 | clp->retrans_count = timeparms.to_retries; | ||
443 | |||
444 | clnt = rpc_create(&args); | 438 | clnt = rpc_create(&args); |
445 | if (IS_ERR(clnt)) { | 439 | if (IS_ERR(clnt)) { |
446 | dprintk("%s: cannot create RPC client. Error = %ld\n", | 440 | dprintk("%s: cannot create RPC client. Error = %ld\n", |
@@ -515,7 +509,9 @@ static inline void nfs_init_server_aclclient(struct nfs_server *server) | |||
515 | /* | 509 | /* |
516 | * Create a general RPC client | 510 | * Create a general RPC client |
517 | */ | 511 | */ |
518 | static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t pseudoflavour) | 512 | static int nfs_init_server_rpcclient(struct nfs_server *server, |
513 | const struct rpc_timeout *timeo, | ||
514 | rpc_authflavor_t pseudoflavour) | ||
519 | { | 515 | { |
520 | struct nfs_client *clp = server->nfs_client; | 516 | struct nfs_client *clp = server->nfs_client; |
521 | 517 | ||
@@ -525,6 +521,11 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t | |||
525 | return PTR_ERR(server->client); | 521 | return PTR_ERR(server->client); |
526 | } | 522 | } |
527 | 523 | ||
524 | memcpy(&server->client->cl_timeout_default, | ||
525 | timeo, | ||
526 | sizeof(server->client->cl_timeout_default)); | ||
527 | server->client->cl_timeout = &server->client->cl_timeout_default; | ||
528 | |||
528 | if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) { | 529 | if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) { |
529 | struct rpc_auth *auth; | 530 | struct rpc_auth *auth; |
530 | 531 | ||
@@ -549,6 +550,7 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t | |||
549 | * Initialise an NFS2 or NFS3 client | 550 | * Initialise an NFS2 or NFS3 client |
550 | */ | 551 | */ |
551 | static int nfs_init_client(struct nfs_client *clp, | 552 | static int nfs_init_client(struct nfs_client *clp, |
553 | const struct rpc_timeout *timeparms, | ||
552 | const struct nfs_parsed_mount_data *data) | 554 | const struct nfs_parsed_mount_data *data) |
553 | { | 555 | { |
554 | int error; | 556 | int error; |
@@ -564,7 +566,7 @@ static int nfs_init_client(struct nfs_client *clp, | |||
564 | * - RFC 2623, sec 2.3.2 | 566 | * - RFC 2623, sec 2.3.2 |
565 | */ | 567 | */ |
566 | error = nfs_create_rpc_client(clp, data->nfs_server.protocol, | 568 | error = nfs_create_rpc_client(clp, data->nfs_server.protocol, |
567 | data->timeo, data->retrans, RPC_AUTH_UNIX, 0); | 569 | timeparms, RPC_AUTH_UNIX, 0); |
568 | if (error < 0) | 570 | if (error < 0) |
569 | goto error; | 571 | goto error; |
570 | nfs_mark_client_ready(clp, NFS_CS_READY); | 572 | nfs_mark_client_ready(clp, NFS_CS_READY); |
@@ -588,6 +590,7 @@ static int nfs_init_server(struct nfs_server *server, | |||
588 | .addrlen = data->nfs_server.addrlen, | 590 | .addrlen = data->nfs_server.addrlen, |
589 | .rpc_ops = &nfs_v2_clientops, | 591 | .rpc_ops = &nfs_v2_clientops, |
590 | }; | 592 | }; |
593 | struct rpc_timeout timeparms; | ||
591 | struct nfs_client *clp; | 594 | struct nfs_client *clp; |
592 | int error; | 595 | int error; |
593 | 596 | ||
@@ -605,7 +608,9 @@ static int nfs_init_server(struct nfs_server *server, | |||
605 | return PTR_ERR(clp); | 608 | return PTR_ERR(clp); |
606 | } | 609 | } |
607 | 610 | ||
608 | error = nfs_init_client(clp, data); | 611 | nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, |
612 | data->timeo, data->retrans); | ||
613 | error = nfs_init_client(clp, &timeparms, data); | ||
609 | if (error < 0) | 614 | if (error < 0) |
610 | goto error; | 615 | goto error; |
611 | 616 | ||
@@ -629,7 +634,7 @@ static int nfs_init_server(struct nfs_server *server, | |||
629 | if (error < 0) | 634 | if (error < 0) |
630 | goto error; | 635 | goto error; |
631 | 636 | ||
632 | error = nfs_init_server_rpcclient(server, data->auth_flavors[0]); | 637 | error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); |
633 | if (error < 0) | 638 | if (error < 0) |
634 | goto error; | 639 | goto error; |
635 | 640 | ||
@@ -889,7 +894,8 @@ error: | |||
889 | * Initialise an NFS4 client record | 894 | * Initialise an NFS4 client record |
890 | */ | 895 | */ |
891 | static int nfs4_init_client(struct nfs_client *clp, | 896 | static int nfs4_init_client(struct nfs_client *clp, |
892 | int proto, int timeo, int retrans, | 897 | int proto, |
898 | const struct rpc_timeout *timeparms, | ||
893 | const char *ip_addr, | 899 | const char *ip_addr, |
894 | rpc_authflavor_t authflavour) | 900 | rpc_authflavor_t authflavour) |
895 | { | 901 | { |
@@ -904,7 +910,7 @@ static int nfs4_init_client(struct nfs_client *clp, | |||
904 | /* Check NFS protocol revision and initialize RPC op vector */ | 910 | /* Check NFS protocol revision and initialize RPC op vector */ |
905 | clp->rpc_ops = &nfs_v4_clientops; | 911 | clp->rpc_ops = &nfs_v4_clientops; |
906 | 912 | ||
907 | error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour, | 913 | error = nfs_create_rpc_client(clp, proto, timeparms, authflavour, |
908 | RPC_CLNT_CREATE_DISCRTRY); | 914 | RPC_CLNT_CREATE_DISCRTRY); |
909 | if (error < 0) | 915 | if (error < 0) |
910 | goto error; | 916 | goto error; |
@@ -936,7 +942,7 @@ static int nfs4_set_client(struct nfs_server *server, | |||
936 | const size_t addrlen, | 942 | const size_t addrlen, |
937 | const char *ip_addr, | 943 | const char *ip_addr, |
938 | rpc_authflavor_t authflavour, | 944 | rpc_authflavor_t authflavour, |
939 | int proto, int timeo, int retrans) | 945 | int proto, const struct rpc_timeout *timeparms) |
940 | { | 946 | { |
941 | struct nfs_client_initdata cl_init = { | 947 | struct nfs_client_initdata cl_init = { |
942 | .hostname = hostname, | 948 | .hostname = hostname, |
@@ -955,7 +961,7 @@ static int nfs4_set_client(struct nfs_server *server, | |||
955 | error = PTR_ERR(clp); | 961 | error = PTR_ERR(clp); |
956 | goto error; | 962 | goto error; |
957 | } | 963 | } |
958 | error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour); | 964 | error = nfs4_init_client(clp, proto, timeparms, ip_addr, authflavour); |
959 | if (error < 0) | 965 | if (error < 0) |
960 | goto error_put; | 966 | goto error_put; |
961 | 967 | ||
@@ -976,10 +982,26 @@ error: | |||
976 | static int nfs4_init_server(struct nfs_server *server, | 982 | static int nfs4_init_server(struct nfs_server *server, |
977 | const struct nfs_parsed_mount_data *data) | 983 | const struct nfs_parsed_mount_data *data) |
978 | { | 984 | { |
985 | struct rpc_timeout timeparms; | ||
979 | int error; | 986 | int error; |
980 | 987 | ||
981 | dprintk("--> nfs4_init_server()\n"); | 988 | dprintk("--> nfs4_init_server()\n"); |
982 | 989 | ||
990 | nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, | ||
991 | data->timeo, data->retrans); | ||
992 | |||
993 | /* Get a client record */ | ||
994 | error = nfs4_set_client(server, | ||
995 | data->nfs_server.hostname, | ||
996 | (const struct sockaddr *)&data->nfs_server.address, | ||
997 | data->nfs_server.addrlen, | ||
998 | data->client_address, | ||
999 | data->auth_flavors[0], | ||
1000 | data->nfs_server.protocol, | ||
1001 | &timeparms); | ||
1002 | if (error < 0) | ||
1003 | goto error; | ||
1004 | |||
983 | /* Initialise the client representation from the mount data */ | 1005 | /* Initialise the client representation from the mount data */ |
984 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; | 1006 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; |
985 | server->caps |= NFS_CAP_ATOMIC_OPEN; | 1007 | server->caps |= NFS_CAP_ATOMIC_OPEN; |
@@ -994,8 +1016,9 @@ static int nfs4_init_server(struct nfs_server *server, | |||
994 | server->acdirmin = data->acdirmin * HZ; | 1016 | server->acdirmin = data->acdirmin * HZ; |
995 | server->acdirmax = data->acdirmax * HZ; | 1017 | server->acdirmax = data->acdirmax * HZ; |
996 | 1018 | ||
997 | error = nfs_init_server_rpcclient(server, data->auth_flavors[0]); | 1019 | error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); |
998 | 1020 | ||
1021 | error: | ||
999 | /* Done */ | 1022 | /* Done */ |
1000 | dprintk("<-- nfs4_init_server() = %d\n", error); | 1023 | dprintk("<-- nfs4_init_server() = %d\n", error); |
1001 | return error; | 1024 | return error; |
@@ -1018,18 +1041,6 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, | |||
1018 | if (!server) | 1041 | if (!server) |
1019 | return ERR_PTR(-ENOMEM); | 1042 | return ERR_PTR(-ENOMEM); |
1020 | 1043 | ||
1021 | /* Get a client record */ | ||
1022 | error = nfs4_set_client(server, | ||
1023 | data->nfs_server.hostname, | ||
1024 | (struct sockaddr *)&data->nfs_server.address, | ||
1025 | data->nfs_server.addrlen, | ||
1026 | data->client_address, | ||
1027 | data->auth_flavors[0], | ||
1028 | data->nfs_server.protocol, | ||
1029 | data->timeo, data->retrans); | ||
1030 | if (error < 0) | ||
1031 | goto error; | ||
1032 | |||
1033 | /* set up the general RPC client */ | 1044 | /* set up the general RPC client */ |
1034 | error = nfs4_init_server(server, data); | 1045 | error = nfs4_init_server(server, data); |
1035 | if (error < 0) | 1046 | if (error < 0) |
@@ -1103,8 +1114,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1103 | parent_client->cl_ipaddr, | 1114 | parent_client->cl_ipaddr, |
1104 | data->authflavor, | 1115 | data->authflavor, |
1105 | parent_server->client->cl_xprt->prot, | 1116 | parent_server->client->cl_xprt->prot, |
1106 | parent_client->retrans_timeo, | 1117 | parent_server->client->cl_timeout); |
1107 | parent_client->retrans_count); | ||
1108 | if (error < 0) | 1118 | if (error < 0) |
1109 | goto error; | 1119 | goto error; |
1110 | 1120 | ||
@@ -1112,7 +1122,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1112 | nfs_server_copy_userdata(server, parent_server); | 1122 | nfs_server_copy_userdata(server, parent_server); |
1113 | server->caps |= NFS_CAP_ATOMIC_OPEN; | 1123 | server->caps |= NFS_CAP_ATOMIC_OPEN; |
1114 | 1124 | ||
1115 | error = nfs_init_server_rpcclient(server, data->authflavor); | 1125 | error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); |
1116 | if (error < 0) | 1126 | if (error < 0) |
1117 | goto error; | 1127 | goto error; |
1118 | 1128 | ||
@@ -1181,7 +1191,9 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, | |||
1181 | 1191 | ||
1182 | server->fsid = fattr->fsid; | 1192 | server->fsid = fattr->fsid; |
1183 | 1193 | ||
1184 | error = nfs_init_server_rpcclient(server, source->client->cl_auth->au_flavor); | 1194 | error = nfs_init_server_rpcclient(server, |
1195 | source->client->cl_timeout, | ||
1196 | source->client->cl_auth->au_flavor); | ||
1185 | if (error < 0) | 1197 | if (error < 0) |
1186 | goto out_free_server; | 1198 | goto out_free_server; |
1187 | if (!IS_ERR(source->client_acl)) | 1199 | if (!IS_ERR(source->client_acl)) |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3cbe32f3e88b..0d1bc61d0b68 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -479,8 +479,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
479 | } | 479 | } |
480 | seq_printf(m, ",proto=%s", | 480 | seq_printf(m, ",proto=%s", |
481 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); | 481 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); |
482 | seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ); | 482 | seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ); |
483 | seq_printf(m, ",retrans=%u", clp->retrans_count); | 483 | seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries); |
484 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); | 484 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); |
485 | } | 485 | } |
486 | 486 | ||
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 912cfe84ea86..d15c9487b8f1 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -29,8 +29,6 @@ struct nfs_client { | |||
29 | 29 | ||
30 | struct rpc_clnt * cl_rpcclient; | 30 | struct rpc_clnt * cl_rpcclient; |
31 | const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ | 31 | const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ |
32 | unsigned long retrans_timeo; /* retransmit timeout */ | ||
33 | unsigned int retrans_count; /* number of retransmit tries */ | ||
34 | 32 | ||
35 | #ifdef CONFIG_NFS_V4 | 33 | #ifdef CONFIG_NFS_V4 |
36 | u64 cl_clientid; /* constant */ | 34 | u64 cl_clientid; /* constant */ |