Commit a86b06d1 authored by David Howells's avatar David Howells

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: c35eccb1 ("[AFS]: Implement the CB.InitCallBackState3 operation.")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 3709a399
...@@ -143,8 +143,8 @@ static void afs_cm_destructor(struct afs_call *call) ...@@ -143,8 +143,8 @@ static void afs_cm_destructor(struct afs_call *call)
* received. The step number here must match the final number in * received. The step number here must match the final number in
* afs_deliver_cb_callback(). * afs_deliver_cb_callback().
*/ */
if (call->unmarshall == 5) { if (call->cm_server && call->unmarshall == 5) {
ASSERT(call->cm_server && call->count && call->request); ASSERT(call->count && call->request);
afs_break_callbacks(call->cm_server, call->count, call->request); afs_break_callbacks(call->cm_server, call->count, call->request);
} }
...@@ -168,7 +168,8 @@ static void SRXAFSCB_CallBack(struct work_struct *work) ...@@ -168,7 +168,8 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
* yet */ * yet */
afs_send_empty_reply(call); afs_send_empty_reply(call);
afs_break_callbacks(call->cm_server, call->count, call->request); if (call->cm_server)
afs_break_callbacks(call->cm_server, call->count, call->request);
afs_put_call(call); afs_put_call(call);
_leave(""); _leave("");
} }
...@@ -180,7 +181,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) ...@@ -180,7 +181,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
{ {
struct afs_callback_break *cb; struct afs_callback_break *cb;
struct sockaddr_rxrpc srx; struct sockaddr_rxrpc srx;
struct afs_server *server;
__be32 *bp; __be32 *bp;
int ret, loop; int ret, loop;
...@@ -286,12 +286,9 @@ static int afs_deliver_cb_callback(struct afs_call *call) ...@@ -286,12 +286,9 @@ static int afs_deliver_cb_callback(struct afs_call *call)
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
server = afs_find_server(call->net, &srx); call->cm_server = afs_find_server(call->net, &srx);
if (!server) { if (!call->cm_server)
trace_afs_cm_no_server(call, &srx); trace_afs_cm_no_server(call, &srx);
return -ENOTCONN;
}
call->cm_server = server;
return afs_queue_call_work(call); return afs_queue_call_work(call);
} }
...@@ -305,7 +302,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) ...@@ -305,7 +302,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
_enter("{%p}", call->cm_server); _enter("{%p}", call->cm_server);
afs_init_callback_state(call->cm_server); if (call->cm_server)
afs_init_callback_state(call->cm_server);
afs_send_empty_reply(call); afs_send_empty_reply(call);
afs_put_call(call); afs_put_call(call);
_leave(""); _leave("");
...@@ -317,7 +315,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) ...@@ -317,7 +315,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
static int afs_deliver_cb_init_call_back_state(struct afs_call *call) static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
{ {
struct sockaddr_rxrpc srx; struct sockaddr_rxrpc srx;
struct afs_server *server;
int ret; int ret;
_enter(""); _enter("");
...@@ -330,12 +327,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) ...@@ -330,12 +327,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
server = afs_find_server(call->net, &srx); call->cm_server = afs_find_server(call->net, &srx);
if (!server) { if (!call->cm_server)
trace_afs_cm_no_server(call, &srx); trace_afs_cm_no_server(call, &srx);
return -ENOTCONN;
}
call->cm_server = server;
return afs_queue_call_work(call); return afs_queue_call_work(call);
} }
...@@ -345,7 +339,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) ...@@ -345,7 +339,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
*/ */
static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
{ {
struct afs_server *server;
struct afs_uuid *r; struct afs_uuid *r;
unsigned loop; unsigned loop;
__be32 *b; __be32 *b;
...@@ -402,13 +395,10 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) ...@@ -402,13 +395,10 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
rcu_read_lock(); rcu_read_lock();
server = afs_find_server_by_uuid(call->net, call->request); call->cm_server = afs_find_server_by_uuid(call->net, call->request);
rcu_read_unlock(); rcu_read_unlock();
if (!server) { if (!call->cm_server)
trace_afs_cm_no_server_u(call, call->request); trace_afs_cm_no_server_u(call, call->request);
return -ENOTCONN;
}
call->cm_server = server;
return afs_queue_call_work(call); return afs_queue_call_work(call);
} }
......
...@@ -497,11 +497,6 @@ static void afs_deliver_to_call(struct afs_call *call) ...@@ -497,11 +497,6 @@ static void afs_deliver_to_call(struct afs_call *call)
case -ECONNABORTED: case -ECONNABORTED:
ASSERTCMP(state, ==, AFS_CALL_COMPLETE); ASSERTCMP(state, ==, AFS_CALL_COMPLETE);
goto done; goto done;
case -ENOTCONN:
abort_code = RX_CALL_DEAD;
rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
abort_code, ret, "KNC");
goto local_abort;
case -ENOTSUPP: case -ENOTSUPP:
abort_code = RXGEN_OPCODE; abort_code = RXGEN_OPCODE;
rxrpc_kernel_abort_call(call->net->socket, call->rxcall, rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment