aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cmservice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/cmservice.c')
-rw-r--r--fs/afs/cmservice.c67
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 */
138static void afs_cm_destructor(struct afs_call *call) 138static 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)
315static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 294static 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 */
342static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) 319static 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}