aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-05-11 18:45:40 -0400
committerDavid Howells <dhowells@redhat.com>2018-05-14 10:15:18 -0400
commita86b06d1ccd218a6a50d6a3a88fbd2abcd0eaa94 (patch)
treea295d0ab6cb82624fc319e86dea9b28da4691edf /fs/afs
parent3709a399c15e4273d9a94b123374f12e5664318c (diff)
afs: Fix the handling of an unfound server in CM operations
If the client cache manager operations that need the server record (CB.Callback, CB.InitCallBackState, and CB.InitCallBackState3) can't find the server record, they abort the call from the file server with RX_CALL_DEAD when they should return okay. Fixes: c35eccb1f614 ("[AFS]: Implement the CB.InitCallBackState3 operation.") Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/cmservice.c34
-rw-r--r--fs/afs/rxrpc.c5
2 files changed, 12 insertions, 27 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 9f13375f49b8..b44491410af3 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -143,8 +143,8 @@ static void afs_cm_destructor(struct afs_call *call)
143 * received. The step number here must match the final number in 143 * received. The step number here must match the final number in
144 * afs_deliver_cb_callback(). 144 * afs_deliver_cb_callback().
145 */ 145 */
146 if (call->unmarshall == 5) { 146 if (call->cm_server && call->unmarshall == 5) {
147 ASSERT(call->cm_server && call->count && call->request); 147 ASSERT(call->count && call->request);
148 afs_break_callbacks(call->cm_server, call->count, call->request); 148 afs_break_callbacks(call->cm_server, call->count, call->request);
149 } 149 }
150 150
@@ -168,7 +168,8 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
168 * yet */ 168 * yet */
169 afs_send_empty_reply(call); 169 afs_send_empty_reply(call);
170 170
171 afs_break_callbacks(call->cm_server, call->count, call->request); 171 if (call->cm_server)
172 afs_break_callbacks(call->cm_server, call->count, call->request);
172 afs_put_call(call); 173 afs_put_call(call);
173 _leave(""); 174 _leave("");
174} 175}
@@ -180,7 +181,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
180{ 181{
181 struct afs_callback_break *cb; 182 struct afs_callback_break *cb;
182 struct sockaddr_rxrpc srx; 183 struct sockaddr_rxrpc srx;
183 struct afs_server *server;
184 __be32 *bp; 184 __be32 *bp;
185 int ret, loop; 185 int ret, loop;
186 186
@@ -286,12 +286,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 286 /* we'll need the file server record as that tells us which set of
287 * vnodes to operate upon */ 287 * vnodes to operate upon */
288 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 288 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
289 server = afs_find_server(call->net, &srx); 289 call->cm_server = afs_find_server(call->net, &srx);
290 if (!server) { 290 if (!call->cm_server)
291 trace_afs_cm_no_server(call, &srx); 291 trace_afs_cm_no_server(call, &srx);
292 return -ENOTCONN;
293 }
294 call->cm_server = server;
295 292
296 return afs_queue_call_work(call); 293 return afs_queue_call_work(call);
297} 294}
@@ -305,7 +302,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
305 302
306 _enter("{%p}", call->cm_server); 303 _enter("{%p}", call->cm_server);
307 304
308 afs_init_callback_state(call->cm_server); 305 if (call->cm_server)
306 afs_init_callback_state(call->cm_server);
309 afs_send_empty_reply(call); 307 afs_send_empty_reply(call);
310 afs_put_call(call); 308 afs_put_call(call);
311 _leave(""); 309 _leave("");
@@ -317,7 +315,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
317static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 315static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
318{ 316{
319 struct sockaddr_rxrpc srx; 317 struct sockaddr_rxrpc srx;
320 struct afs_server *server;
321 int ret; 318 int ret;
322 319
323 _enter(""); 320 _enter("");
@@ -330,12 +327,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
330 327
331 /* we'll need the file server record as that tells us which set of 328 /* we'll need the file server record as that tells us which set of
332 * vnodes to operate upon */ 329 * vnodes to operate upon */
333 server = afs_find_server(call->net, &srx); 330 call->cm_server = afs_find_server(call->net, &srx);
334 if (!server) { 331 if (!call->cm_server)
335 trace_afs_cm_no_server(call, &srx); 332 trace_afs_cm_no_server(call, &srx);
336 return -ENOTCONN;
337 }
338 call->cm_server = server;
339 333
340 return afs_queue_call_work(call); 334 return afs_queue_call_work(call);
341} 335}
@@ -345,7 +339,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
345 */ 339 */
346static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) 340static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
347{ 341{
348 struct afs_server *server;
349 struct afs_uuid *r; 342 struct afs_uuid *r;
350 unsigned loop; 343 unsigned loop;
351 __be32 *b; 344 __be32 *b;
@@ -402,13 +395,10 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
402 /* we'll need the file server record as that tells us which set of 395 /* we'll need the file server record as that tells us which set of
403 * vnodes to operate upon */ 396 * vnodes to operate upon */
404 rcu_read_lock(); 397 rcu_read_lock();
405 server = afs_find_server_by_uuid(call->net, call->request); 398 call->cm_server = afs_find_server_by_uuid(call->net, call->request);
406 rcu_read_unlock(); 399 rcu_read_unlock();
407 if (!server) { 400 if (!call->cm_server)
408 trace_afs_cm_no_server_u(call, call->request); 401 trace_afs_cm_no_server_u(call, call->request);
409 return -ENOTCONN;
410 }
411 call->cm_server = server;
412 402
413 return afs_queue_call_work(call); 403 return afs_queue_call_work(call);
414} 404}
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 1f6235a6e9ae..d0eee5d32c94 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -497,11 +497,6 @@ static void afs_deliver_to_call(struct afs_call *call)
497 case -ECONNABORTED: 497 case -ECONNABORTED:
498 ASSERTCMP(state, ==, AFS_CALL_COMPLETE); 498 ASSERTCMP(state, ==, AFS_CALL_COMPLETE);
499 goto done; 499 goto done;
500 case -ENOTCONN:
501 abort_code = RX_CALL_DEAD;
502 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
503 abort_code, ret, "KNC");
504 goto local_abort;
505 case -ENOTSUPP: 500 case -ENOTSUPP:
506 abort_code = RXGEN_OPCODE; 501 abort_code = RXGEN_OPCODE;
507 rxrpc_kernel_abort_call(call->net->socket, call->rxcall, 502 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,