aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-02-19 13:25:57 -0500
committerAlex Elder <elder@inktank.com>2013-02-25 16:37:28 -0500
commit93209264203987cdd2c69d34df6eaa2cd184e283 (patch)
tree88dd732371a1e3d5be90ca0fa15472bef59a1e42
parentf20a39fd6e6356b4cf3c1650c4dc6c66c99d8bae (diff)
libceph: separate non-locked fault handling
An error occurring on a ceph connection is treated as a fault, causing the connection to be reset. The initial part of this fault handling has to be done while holding the connection mutex, but it must then be dropped for the last part. Separate the part of this fault handling that executes without the lock into its own function, con_fault_finish(). Move the call to this new function, as well as call that drops the connection mutex, into ceph_fault(). Rename that function con_fault() to reflect that it's only handling the connection part of the fault handling. The motivation for this was a warning from sparse about the locking being done here. Rearranging things this way keeps all the mutex manipulation within ceph_fault(), and this stops sparse from complaining. This partially resolves: http://tracker.ceph.com/issues/4184 Reported-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--net/ceph/messenger.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 9a29d8a4bad7..c3b9060d4844 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -166,7 +166,7 @@ static struct lock_class_key socket_class;
166 166
167static void queue_con(struct ceph_connection *con); 167static void queue_con(struct ceph_connection *con);
168static void con_work(struct work_struct *); 168static void con_work(struct work_struct *);
169static void ceph_fault(struct ceph_connection *con); 169static void con_fault(struct ceph_connection *con);
170 170
171/* 171/*
172 * Nicely render a sockaddr as a string. An array of formatted 172 * Nicely render a sockaddr as a string. An array of formatted
@@ -2363,6 +2363,23 @@ static bool con_backoff(struct ceph_connection *con)
2363 return true; 2363 return true;
2364} 2364}
2365 2365
2366/* Finish fault handling; con->mutex must *not* be held here */
2367
2368static void con_fault_finish(struct ceph_connection *con)
2369{
2370 /*
2371 * in case we faulted due to authentication, invalidate our
2372 * current tickets so that we can get new ones.
2373 */
2374 if (con->auth_retry && con->ops->invalidate_authorizer) {
2375 dout("calling invalidate_authorizer()\n");
2376 con->ops->invalidate_authorizer(con);
2377 }
2378
2379 if (con->ops->fault)
2380 con->ops->fault(con);
2381}
2382
2366/* 2383/*
2367 * Do some work on a connection. Drop a connection ref when we're done. 2384 * Do some work on a connection. Drop a connection ref when we're done.
2368 */ 2385 */
@@ -2419,7 +2436,9 @@ done_unlocked:
2419 return; 2436 return;
2420 2437
2421fault: 2438fault:
2422 ceph_fault(con); /* error/fault path */ 2439 con_fault(con);
2440 mutex_unlock(&con->mutex);
2441 con_fault_finish(con);
2423 goto done_unlocked; 2442 goto done_unlocked;
2424} 2443}
2425 2444
@@ -2428,8 +2447,7 @@ fault:
2428 * Generic error/fault handler. A retry mechanism is used with 2447 * Generic error/fault handler. A retry mechanism is used with
2429 * exponential backoff 2448 * exponential backoff
2430 */ 2449 */
2431static void ceph_fault(struct ceph_connection *con) 2450static void con_fault(struct ceph_connection *con)
2432 __releases(con->mutex)
2433{ 2451{
2434 pr_warning("%s%lld %s %s\n", ENTITY_NAME(con->peer_name), 2452 pr_warning("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
2435 ceph_pr_addr(&con->peer_addr.in_addr), con->error_msg); 2453 ceph_pr_addr(&con->peer_addr.in_addr), con->error_msg);
@@ -2445,7 +2463,7 @@ static void ceph_fault(struct ceph_connection *con)
2445 if (con_flag_test(con, CON_FLAG_LOSSYTX)) { 2463 if (con_flag_test(con, CON_FLAG_LOSSYTX)) {
2446 dout("fault on LOSSYTX channel, marking CLOSED\n"); 2464 dout("fault on LOSSYTX channel, marking CLOSED\n");
2447 con->state = CON_STATE_CLOSED; 2465 con->state = CON_STATE_CLOSED;
2448 goto out_unlock; 2466 return;
2449 } 2467 }
2450 2468
2451 if (con->in_msg) { 2469 if (con->in_msg) {
@@ -2476,20 +2494,6 @@ static void ceph_fault(struct ceph_connection *con)
2476 con_flag_set(con, CON_FLAG_BACKOFF); 2494 con_flag_set(con, CON_FLAG_BACKOFF);
2477 queue_con(con); 2495 queue_con(con);
2478 } 2496 }
2479
2480out_unlock:
2481 mutex_unlock(&con->mutex);
2482 /*
2483 * in case we faulted due to authentication, invalidate our
2484 * current tickets so that we can get new ones.
2485 */
2486 if (con->auth_retry && con->ops->invalidate_authorizer) {
2487 dout("calling invalidate_authorizer()\n");
2488 con->ops->invalidate_authorizer(con);
2489 }
2490
2491 if (con->ops->fault)
2492 con->ops->fault(con);
2493} 2497}
2494 2498
2495 2499