aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-05-11 23:45:40 +0100
committerDavid Howells <dhowells@redhat.com>2018-05-14 15:15:18 +0100
commita86b06d1ccd218a6a50d6a3a88fbd2abcd0eaa94 (patch)
treea295d0ab6cb82624fc319e86dea9b28da4691edf /fs
parentafs: Add a tracepoint to record callbacks from unlisted servers (diff)
downloadlinux-dev-a86b06d1ccd218a6a50d6a3a88fbd2abcd0eaa94.tar.xz
linux-dev-a86b06d1ccd218a6a50d6a3a88fbd2abcd0eaa94.zip
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')
-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)
* 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);
}
@@ -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("");
}
@@ -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;
@@ -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);
}
@@ -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("");
@@ -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("");
@@ -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);
}
@@ -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;
@@ -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);
}
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)
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,