diff options
Diffstat (limited to 'fs/afs/cmservice.c')
-rw-r--r-- | fs/afs/cmservice.c | 67 |
1 files changed, 21 insertions, 46 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 357de908df3a..c332c95a6940 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -133,21 +133,10 @@ bool afs_cm_incoming_call(struct afs_call *call) | |||
133 | } | 133 | } |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * clean up a cache manager call | 136 | * Clean up a cache manager call. |
137 | */ | 137 | */ |
138 | static void afs_cm_destructor(struct afs_call *call) | 138 | static void afs_cm_destructor(struct afs_call *call) |
139 | { | 139 | { |
140 | _enter(""); | ||
141 | |||
142 | /* Break the callbacks here so that we do it after the final ACK is | ||
143 | * received. The step number here must match the final number in | ||
144 | * afs_deliver_cb_callback(). | ||
145 | */ | ||
146 | if (call->unmarshall == 5) { | ||
147 | ASSERT(call->cm_server && call->count && call->request); | ||
148 | afs_break_callbacks(call->cm_server, call->count, call->request); | ||
149 | } | ||
150 | |||
151 | kfree(call->buffer); | 140 | kfree(call->buffer); |
152 | call->buffer = NULL; | 141 | call->buffer = NULL; |
153 | } | 142 | } |
@@ -161,14 +150,14 @@ static void SRXAFSCB_CallBack(struct work_struct *work) | |||
161 | 150 | ||
162 | _enter(""); | 151 | _enter(""); |
163 | 152 | ||
164 | /* be sure to send the reply *before* attempting to spam the AFS server | 153 | /* We need to break the callbacks before sending the reply as the |
165 | * with FSFetchStatus requests on the vnodes with broken callbacks lest | 154 | * server holds up change visibility till it receives our reply so as |
166 | * the AFS server get into a vicious cycle of trying to break further | 155 | * to maintain cache coherency. |
167 | * callbacks because it hadn't received completion of the CBCallBack op | 156 | */ |
168 | * yet */ | 157 | if (call->cm_server) |
169 | afs_send_empty_reply(call); | 158 | afs_break_callbacks(call->cm_server, call->count, call->request); |
170 | 159 | ||
171 | afs_break_callbacks(call->cm_server, call->count, call->request); | 160 | afs_send_empty_reply(call); |
172 | afs_put_call(call); | 161 | afs_put_call(call); |
173 | _leave(""); | 162 | _leave(""); |
174 | } | 163 | } |
@@ -180,7 +169,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
180 | { | 169 | { |
181 | struct afs_callback_break *cb; | 170 | struct afs_callback_break *cb; |
182 | struct sockaddr_rxrpc srx; | 171 | struct sockaddr_rxrpc srx; |
183 | struct afs_server *server; | ||
184 | __be32 *bp; | 172 | __be32 *bp; |
185 | int ret, loop; | 173 | int ret, loop; |
186 | 174 | ||
@@ -267,15 +255,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
267 | 255 | ||
268 | call->offset = 0; | 256 | call->offset = 0; |
269 | call->unmarshall++; | 257 | call->unmarshall++; |
270 | |||
271 | /* Record that the message was unmarshalled successfully so | ||
272 | * that the call destructor can know do the callback breaking | ||
273 | * work, even if the final ACK isn't received. | ||
274 | * | ||
275 | * If the step number changes, then afs_cm_destructor() must be | ||
276 | * updated also. | ||
277 | */ | ||
278 | call->unmarshall++; | ||
279 | case 5: | 258 | case 5: |
280 | break; | 259 | break; |
281 | } | 260 | } |
@@ -286,10 +265,9 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
286 | /* we'll need the file server record as that tells us which set of | 265 | /* we'll need the file server record as that tells us which set of |
287 | * vnodes to operate upon */ | 266 | * vnodes to operate upon */ |
288 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); | 267 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); |
289 | server = afs_find_server(call->net, &srx); | 268 | call->cm_server = afs_find_server(call->net, &srx); |
290 | if (!server) | 269 | if (!call->cm_server) |
291 | return -ENOTCONN; | 270 | trace_afs_cm_no_server(call, &srx); |
292 | call->cm_server = server; | ||
293 | 271 | ||
294 | return afs_queue_call_work(call); | 272 | return afs_queue_call_work(call); |
295 | } | 273 | } |
@@ -303,7 +281,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) | |||
303 | 281 | ||
304 | _enter("{%p}", call->cm_server); | 282 | _enter("{%p}", call->cm_server); |
305 | 283 | ||
306 | afs_init_callback_state(call->cm_server); | 284 | if (call->cm_server) |
285 | afs_init_callback_state(call->cm_server); | ||
307 | afs_send_empty_reply(call); | 286 | afs_send_empty_reply(call); |
308 | afs_put_call(call); | 287 | afs_put_call(call); |
309 | _leave(""); | 288 | _leave(""); |
@@ -315,7 +294,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) | |||
315 | static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | 294 | static int afs_deliver_cb_init_call_back_state(struct afs_call *call) |
316 | { | 295 | { |
317 | struct sockaddr_rxrpc srx; | 296 | struct sockaddr_rxrpc srx; |
318 | struct afs_server *server; | ||
319 | int ret; | 297 | int ret; |
320 | 298 | ||
321 | _enter(""); | 299 | _enter(""); |
@@ -328,10 +306,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | |||
328 | 306 | ||
329 | /* we'll need the file server record as that tells us which set of | 307 | /* we'll need the file server record as that tells us which set of |
330 | * vnodes to operate upon */ | 308 | * vnodes to operate upon */ |
331 | server = afs_find_server(call->net, &srx); | 309 | call->cm_server = afs_find_server(call->net, &srx); |
332 | if (!server) | 310 | if (!call->cm_server) |
333 | return -ENOTCONN; | 311 | trace_afs_cm_no_server(call, &srx); |
334 | call->cm_server = server; | ||
335 | 312 | ||
336 | return afs_queue_call_work(call); | 313 | return afs_queue_call_work(call); |
337 | } | 314 | } |
@@ -341,8 +318,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | |||
341 | */ | 318 | */ |
342 | static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) | 319 | static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) |
343 | { | 320 | { |
344 | struct sockaddr_rxrpc srx; | ||
345 | struct afs_server *server; | ||
346 | struct afs_uuid *r; | 321 | struct afs_uuid *r; |
347 | unsigned loop; | 322 | unsigned loop; |
348 | __be32 *b; | 323 | __be32 *b; |
@@ -398,11 +373,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) | |||
398 | 373 | ||
399 | /* we'll need the file server record as that tells us which set of | 374 | /* we'll need the file server record as that tells us which set of |
400 | * vnodes to operate upon */ | 375 | * vnodes to operate upon */ |
401 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); | 376 | rcu_read_lock(); |
402 | server = afs_find_server(call->net, &srx); | 377 | call->cm_server = afs_find_server_by_uuid(call->net, call->request); |
403 | if (!server) | 378 | rcu_read_unlock(); |
404 | return -ENOTCONN; | 379 | if (!call->cm_server) |
405 | call->cm_server = server; | 380 | trace_afs_cm_no_server_u(call, call->request); |
406 | 381 | ||
407 | return afs_queue_call_work(call); | 382 | return afs_queue_call_work(call); |
408 | } | 383 | } |