diff options
-rw-r--r-- | fs/nfs/callback.c | 65 | ||||
-rw-r--r-- | fs/nfs/callback.h | 2 | ||||
-rw-r--r-- | fs/nfs/client.c | 21 |
3 files changed, 54 insertions, 34 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index a886e692ddd0..4b1313eda6f5 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -59,7 +59,7 @@ module_param_call(callback_tcpport, param_set_port, param_get_int, | |||
59 | * This is the callback kernel thread. | 59 | * This is the callback kernel thread. |
60 | */ | 60 | */ |
61 | static int | 61 | static int |
62 | nfs_callback_svc(void *vrqstp) | 62 | nfs4_callback_svc(void *vrqstp) |
63 | { | 63 | { |
64 | int err, preverr = 0; | 64 | int err, preverr = 0; |
65 | struct svc_rqst *rqstp = vrqstp; | 65 | struct svc_rqst *rqstp = vrqstp; |
@@ -97,20 +97,12 @@ nfs_callback_svc(void *vrqstp) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * Bring up the callback thread if it is not already up. | 100 | * Prepare to bring up the NFSv4 callback service |
101 | */ | 101 | */ |
102 | int nfs_callback_up(void) | 102 | struct svc_rqst * |
103 | nfs4_callback_up(struct svc_serv *serv) | ||
103 | { | 104 | { |
104 | struct svc_serv *serv = NULL; | 105 | int ret; |
105 | int ret = 0; | ||
106 | |||
107 | mutex_lock(&nfs_callback_mutex); | ||
108 | if (nfs_callback_info.users++ || nfs_callback_info.task != NULL) | ||
109 | goto out; | ||
110 | serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); | ||
111 | ret = -ENOMEM; | ||
112 | if (!serv) | ||
113 | goto out_err; | ||
114 | 106 | ||
115 | ret = svc_create_xprt(serv, "tcp", PF_INET, | 107 | ret = svc_create_xprt(serv, "tcp", PF_INET, |
116 | nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); | 108 | nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); |
@@ -131,18 +123,53 @@ int nfs_callback_up(void) | |||
131 | goto out_err; | 123 | goto out_err; |
132 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | 124 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ |
133 | 125 | ||
134 | nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); | 126 | return svc_prepare_thread(serv, &serv->sv_pools[0]); |
135 | if (IS_ERR(nfs_callback_info.rqst)) { | 127 | |
136 | ret = PTR_ERR(nfs_callback_info.rqst); | 128 | out_err: |
137 | nfs_callback_info.rqst = NULL; | 129 | if (ret == 0) |
130 | ret = -ENOMEM; | ||
131 | return ERR_PTR(ret); | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Bring up the callback thread if it is not already up. | ||
136 | */ | ||
137 | int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) | ||
138 | { | ||
139 | struct svc_serv *serv = NULL; | ||
140 | struct svc_rqst *rqstp; | ||
141 | int (*callback_svc)(void *vrqstp); | ||
142 | char svc_name[12]; | ||
143 | int ret = 0; | ||
144 | |||
145 | mutex_lock(&nfs_callback_mutex); | ||
146 | if (nfs_callback_info.users++ || nfs_callback_info.task != NULL) | ||
147 | goto out; | ||
148 | serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); | ||
149 | if (!serv) { | ||
150 | ret = -ENOMEM; | ||
151 | goto out_err; | ||
152 | } | ||
153 | |||
154 | if (!minorversion) { | ||
155 | rqstp = nfs4_callback_up(serv); | ||
156 | callback_svc = nfs4_callback_svc; | ||
157 | } else { | ||
158 | BUG(); /* for now */ | ||
159 | } | ||
160 | |||
161 | if (IS_ERR(rqstp)) { | ||
162 | ret = PTR_ERR(rqstp); | ||
138 | goto out_err; | 163 | goto out_err; |
139 | } | 164 | } |
140 | 165 | ||
141 | svc_sock_update_bufs(serv); | 166 | svc_sock_update_bufs(serv); |
142 | 167 | ||
143 | nfs_callback_info.task = kthread_run(nfs_callback_svc, | 168 | sprintf(svc_name, "nfsv4.%u-svc", minorversion); |
169 | nfs_callback_info.rqst = rqstp; | ||
170 | nfs_callback_info.task = kthread_run(callback_svc, | ||
144 | nfs_callback_info.rqst, | 171 | nfs_callback_info.rqst, |
145 | "nfsv4-svc"); | 172 | svc_name); |
146 | if (IS_ERR(nfs_callback_info.task)) { | 173 | if (IS_ERR(nfs_callback_info.task)) { |
147 | ret = PTR_ERR(nfs_callback_info.task); | 174 | ret = PTR_ERR(nfs_callback_info.task); |
148 | svc_exit_thread(nfs_callback_info.rqst); | 175 | svc_exit_thread(nfs_callback_info.rqst); |
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index e110e286a262..9b907f408b8d 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -63,7 +63,7 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat | |||
63 | extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy); | 63 | extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy); |
64 | 64 | ||
65 | #ifdef CONFIG_NFS_V4 | 65 | #ifdef CONFIG_NFS_V4 |
66 | extern int nfs_callback_up(void); | 66 | extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); |
67 | extern void nfs_callback_down(void); | 67 | extern void nfs_callback_down(void); |
68 | #else | 68 | #else |
69 | #define nfs_callback_up() (0) | 69 | #define nfs_callback_up() (0) |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d9657d455730..df2b40d1883d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -47,9 +47,6 @@ | |||
47 | #include "internal.h" | 47 | #include "internal.h" |
48 | #include "fscache.h" | 48 | #include "fscache.h" |
49 | 49 | ||
50 | static int nfs4_init_callback(struct nfs_client *); | ||
51 | static void nfs4_destroy_callback(struct nfs_client *); | ||
52 | |||
53 | #define NFSDBG_FACILITY NFSDBG_CLIENT | 50 | #define NFSDBG_FACILITY NFSDBG_CLIENT |
54 | 51 | ||
55 | static DEFINE_SPINLOCK(nfs_client_lock); | 52 | static DEFINE_SPINLOCK(nfs_client_lock); |
@@ -124,9 +121,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ | |||
124 | 121 | ||
125 | clp->rpc_ops = cl_init->rpc_ops; | 122 | clp->rpc_ops = cl_init->rpc_ops; |
126 | 123 | ||
127 | if (nfs4_init_callback(clp) < 0) | ||
128 | goto error_2; | ||
129 | |||
130 | atomic_set(&clp->cl_count, 1); | 124 | atomic_set(&clp->cl_count, 1); |
131 | clp->cl_cons_state = NFS_CS_INITING; | 125 | clp->cl_cons_state = NFS_CS_INITING; |
132 | 126 | ||
@@ -136,7 +130,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ | |||
136 | if (cl_init->hostname) { | 130 | if (cl_init->hostname) { |
137 | clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL); | 131 | clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL); |
138 | if (!clp->cl_hostname) | 132 | if (!clp->cl_hostname) |
139 | goto error_3; | 133 | goto error_cleanup; |
140 | } | 134 | } |
141 | 135 | ||
142 | INIT_LIST_HEAD(&clp->cl_superblocks); | 136 | INIT_LIST_HEAD(&clp->cl_superblocks); |
@@ -161,9 +155,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ | |||
161 | 155 | ||
162 | return clp; | 156 | return clp; |
163 | 157 | ||
164 | error_3: | 158 | error_cleanup: |
165 | nfs4_destroy_callback(clp); | ||
166 | error_2: | ||
167 | kfree(clp); | 159 | kfree(clp); |
168 | error_0: | 160 | error_0: |
169 | return NULL; | 161 | return NULL; |
@@ -207,6 +199,8 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp) | |||
207 | 199 | ||
208 | clp->cl_call_sync = _nfs4_call_sync; | 200 | clp->cl_call_sync = _nfs4_call_sync; |
209 | #endif /* CONFIG_NFS_V4_1 */ | 201 | #endif /* CONFIG_NFS_V4_1 */ |
202 | |||
203 | nfs4_destroy_callback(clp); | ||
210 | } | 204 | } |
211 | 205 | ||
212 | /* | 206 | /* |
@@ -225,8 +219,6 @@ static void nfs_free_client(struct nfs_client *clp) | |||
225 | if (!IS_ERR(clp->cl_rpcclient)) | 219 | if (!IS_ERR(clp->cl_rpcclient)) |
226 | rpc_shutdown_client(clp->cl_rpcclient); | 220 | rpc_shutdown_client(clp->cl_rpcclient); |
227 | 221 | ||
228 | nfs4_destroy_callback(clp); | ||
229 | |||
230 | if (clp->cl_machine_cred != NULL) | 222 | if (clp->cl_machine_cred != NULL) |
231 | put_rpccred(clp->cl_machine_cred); | 223 | put_rpccred(clp->cl_machine_cred); |
232 | 224 | ||
@@ -1104,7 +1096,8 @@ static int nfs4_init_callback(struct nfs_client *clp) | |||
1104 | int error; | 1096 | int error; |
1105 | 1097 | ||
1106 | if (clp->rpc_ops->version == 4) { | 1098 | if (clp->rpc_ops->version == 4) { |
1107 | error = nfs_callback_up(); | 1099 | error = nfs_callback_up(clp->cl_minorversion, |
1100 | clp->cl_rpcclient->cl_xprt); | ||
1108 | if (error < 0) { | 1101 | if (error < 0) { |
1109 | dprintk("%s: failed to start callback. Error = %d\n", | 1102 | dprintk("%s: failed to start callback. Error = %d\n", |
1110 | __func__, error); | 1103 | __func__, error); |
@@ -1139,7 +1132,7 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp) | |||
1139 | } | 1132 | } |
1140 | #endif /* CONFIG_NFS_V4_1 */ | 1133 | #endif /* CONFIG_NFS_V4_1 */ |
1141 | 1134 | ||
1142 | return 0; | 1135 | return nfs4_init_callback(clp); |
1143 | } | 1136 | } |
1144 | 1137 | ||
1145 | /* | 1138 | /* |