Skip to content

Commit

Permalink
afs: Fix the handling of an unfound server in CM operations
Browse files Browse the repository at this point in the history
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: c35eccb ("[AFS]: Implement the CB.InitCallBackState3 operation.")
Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed May 14, 2018
1 parent 3709a39 commit a86b06d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 27 deletions.
34 changes: 12 additions & 22 deletions fs/afs/cmservice.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ static void afs_cm_destructor(struct afs_call *call)
* received. The step number here must match the final number in
* afs_deliver_cb_callback().
*/
if (call->unmarshall == 5) {
ASSERT(call->cm_server && call->count && call->request);
if (call->cm_server && call->unmarshall == 5) {
ASSERT(call->count && call->request);
afs_break_callbacks(call->cm_server, call->count, call->request);
}

Expand All @@ -168,7 +168,8 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
* yet */
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);
_leave("");
}
Expand All @@ -180,7 +181,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
{
struct afs_callback_break *cb;
struct sockaddr_rxrpc srx;
struct afs_server *server;
__be32 *bp;
int ret, loop;

Expand Down Expand Up @@ -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
* vnodes to operate upon */
rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
server = afs_find_server(call->net, &srx);
if (!server) {
call->cm_server = afs_find_server(call->net, &srx);
if (!call->cm_server)
trace_afs_cm_no_server(call, &srx);
return -ENOTCONN;
}
call->cm_server = server;

return afs_queue_call_work(call);
}
Expand All @@ -305,7 +302,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)

_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_put_call(call);
_leave("");
Expand All @@ -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)
{
struct sockaddr_rxrpc srx;
struct afs_server *server;
int ret;

_enter("");
Expand All @@ -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
* vnodes to operate upon */
server = afs_find_server(call->net, &srx);
if (!server) {
call->cm_server = afs_find_server(call->net, &srx);
if (!call->cm_server)
trace_afs_cm_no_server(call, &srx);
return -ENOTCONN;
}
call->cm_server = server;

return afs_queue_call_work(call);
}
Expand All @@ -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)
{
struct afs_server *server;
struct afs_uuid *r;
unsigned loop;
__be32 *b;
Expand Down Expand Up @@ -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
* vnodes to operate upon */
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();
if (!server) {
if (!call->cm_server)
trace_afs_cm_no_server_u(call, call->request);
return -ENOTCONN;
}
call->cm_server = server;

return afs_queue_call_work(call);
}
Expand Down
5 changes: 0 additions & 5 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,6 @@ static void afs_deliver_to_call(struct afs_call *call)
case -ECONNABORTED:
ASSERTCMP(state, ==, AFS_CALL_COMPLETE);
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:
abort_code = RXGEN_OPCODE;
rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
Expand Down

0 comments on commit a86b06d

Please sign in to comment.