Commit 58890c06691462ca29900d1116b28c7a3e131252
Exists in
master
and in
20 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull Ceph fixes from Sage Weil: "Two of Alex's patches deal with a race when reseting server connections for open RBD images, one demotes some non-fatal BUGs to WARNs, and my patch fixes a protocol feature bit failure path." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: libceph: fix protocol feature mismatch failure path libceph: WARN, don't BUG on unexpected connection states libceph: always reset osds when kicking libceph: move linger requests sooner in kick_requests()
Showing 2 changed files Side-by-side Diff
net/ceph/messenger.c
... | ... | @@ -506,6 +506,7 @@ |
506 | 506 | { |
507 | 507 | /* reset connection, out_queue, msg_ and connect_seq */ |
508 | 508 | /* discard existing out_queue and msg_seq */ |
509 | + dout("reset_connection %p\n", con); | |
509 | 510 | ceph_msg_remove_list(&con->out_queue); |
510 | 511 | ceph_msg_remove_list(&con->out_sent); |
511 | 512 | |
... | ... | @@ -561,7 +562,7 @@ |
561 | 562 | mutex_lock(&con->mutex); |
562 | 563 | dout("con_open %p %s\n", con, ceph_pr_addr(&addr->in_addr)); |
563 | 564 | |
564 | - BUG_ON(con->state != CON_STATE_CLOSED); | |
565 | + WARN_ON(con->state != CON_STATE_CLOSED); | |
565 | 566 | con->state = CON_STATE_PREOPEN; |
566 | 567 | |
567 | 568 | con->peer_name.type = (__u8) entity_type; |
... | ... | @@ -1506,13 +1507,6 @@ |
1506 | 1507 | return 0; |
1507 | 1508 | } |
1508 | 1509 | |
1509 | -static void fail_protocol(struct ceph_connection *con) | |
1510 | -{ | |
1511 | - reset_connection(con); | |
1512 | - BUG_ON(con->state != CON_STATE_NEGOTIATING); | |
1513 | - con->state = CON_STATE_CLOSED; | |
1514 | -} | |
1515 | - | |
1516 | 1510 | static int process_connect(struct ceph_connection *con) |
1517 | 1511 | { |
1518 | 1512 | u64 sup_feat = con->msgr->supported_features; |
... | ... | @@ -1530,7 +1524,7 @@ |
1530 | 1524 | ceph_pr_addr(&con->peer_addr.in_addr), |
1531 | 1525 | sup_feat, server_feat, server_feat & ~sup_feat); |
1532 | 1526 | con->error_msg = "missing required protocol features"; |
1533 | - fail_protocol(con); | |
1527 | + reset_connection(con); | |
1534 | 1528 | return -1; |
1535 | 1529 | |
1536 | 1530 | case CEPH_MSGR_TAG_BADPROTOVER: |
... | ... | @@ -1541,7 +1535,7 @@ |
1541 | 1535 | le32_to_cpu(con->out_connect.protocol_version), |
1542 | 1536 | le32_to_cpu(con->in_reply.protocol_version)); |
1543 | 1537 | con->error_msg = "protocol version mismatch"; |
1544 | - fail_protocol(con); | |
1538 | + reset_connection(con); | |
1545 | 1539 | return -1; |
1546 | 1540 | |
1547 | 1541 | case CEPH_MSGR_TAG_BADAUTHORIZER: |
1548 | 1542 | |
... | ... | @@ -1631,11 +1625,11 @@ |
1631 | 1625 | ceph_pr_addr(&con->peer_addr.in_addr), |
1632 | 1626 | req_feat, server_feat, req_feat & ~server_feat); |
1633 | 1627 | con->error_msg = "missing required protocol features"; |
1634 | - fail_protocol(con); | |
1628 | + reset_connection(con); | |
1635 | 1629 | return -1; |
1636 | 1630 | } |
1637 | 1631 | |
1638 | - BUG_ON(con->state != CON_STATE_NEGOTIATING); | |
1632 | + WARN_ON(con->state != CON_STATE_NEGOTIATING); | |
1639 | 1633 | con->state = CON_STATE_OPEN; |
1640 | 1634 | |
1641 | 1635 | con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); |
... | ... | @@ -2132,7 +2126,6 @@ |
2132 | 2126 | if (ret < 0) |
2133 | 2127 | goto out; |
2134 | 2128 | |
2135 | - BUG_ON(con->state != CON_STATE_CONNECTING); | |
2136 | 2129 | con->state = CON_STATE_NEGOTIATING; |
2137 | 2130 | |
2138 | 2131 | /* |
... | ... | @@ -2160,7 +2153,7 @@ |
2160 | 2153 | goto more; |
2161 | 2154 | } |
2162 | 2155 | |
2163 | - BUG_ON(con->state != CON_STATE_OPEN); | |
2156 | + WARN_ON(con->state != CON_STATE_OPEN); | |
2164 | 2157 | |
2165 | 2158 | if (con->in_base_pos < 0) { |
2166 | 2159 | /* |
... | ... | @@ -2382,7 +2375,7 @@ |
2382 | 2375 | dout("fault %p state %lu to peer %s\n", |
2383 | 2376 | con, con->state, ceph_pr_addr(&con->peer_addr.in_addr)); |
2384 | 2377 | |
2385 | - BUG_ON(con->state != CON_STATE_CONNECTING && | |
2378 | + WARN_ON(con->state != CON_STATE_CONNECTING && | |
2386 | 2379 | con->state != CON_STATE_NEGOTIATING && |
2387 | 2380 | con->state != CON_STATE_OPEN); |
2388 | 2381 |
net/ceph/osd_client.c
... | ... | @@ -1270,7 +1270,7 @@ |
1270 | 1270 | * Requeue requests whose mapping to an OSD has changed. If requests map to |
1271 | 1271 | * no osd, request a new map. |
1272 | 1272 | * |
1273 | - * Caller should hold map_sem for read and request_mutex. | |
1273 | + * Caller should hold map_sem for read. | |
1274 | 1274 | */ |
1275 | 1275 | static void kick_requests(struct ceph_osd_client *osdc, int force_resend) |
1276 | 1276 | { |
... | ... | @@ -1284,6 +1284,24 @@ |
1284 | 1284 | for (p = rb_first(&osdc->requests); p; ) { |
1285 | 1285 | req = rb_entry(p, struct ceph_osd_request, r_node); |
1286 | 1286 | p = rb_next(p); |
1287 | + | |
1288 | + /* | |
1289 | + * For linger requests that have not yet been | |
1290 | + * registered, move them to the linger list; they'll | |
1291 | + * be sent to the osd in the loop below. Unregister | |
1292 | + * the request before re-registering it as a linger | |
1293 | + * request to ensure the __map_request() below | |
1294 | + * will decide it needs to be sent. | |
1295 | + */ | |
1296 | + if (req->r_linger && list_empty(&req->r_linger_item)) { | |
1297 | + dout("%p tid %llu restart on osd%d\n", | |
1298 | + req, req->r_tid, | |
1299 | + req->r_osd ? req->r_osd->o_osd : -1); | |
1300 | + __unregister_request(osdc, req); | |
1301 | + __register_linger_request(osdc, req); | |
1302 | + continue; | |
1303 | + } | |
1304 | + | |
1287 | 1305 | err = __map_request(osdc, req, force_resend); |
1288 | 1306 | if (err < 0) |
1289 | 1307 | continue; /* error */ |
... | ... | @@ -1298,17 +1316,6 @@ |
1298 | 1316 | req->r_flags |= CEPH_OSD_FLAG_RETRY; |
1299 | 1317 | } |
1300 | 1318 | } |
1301 | - if (req->r_linger && list_empty(&req->r_linger_item)) { | |
1302 | - /* | |
1303 | - * register as a linger so that we will | |
1304 | - * re-submit below and get a new tid | |
1305 | - */ | |
1306 | - dout("%p tid %llu restart on osd%d\n", | |
1307 | - req, req->r_tid, | |
1308 | - req->r_osd ? req->r_osd->o_osd : -1); | |
1309 | - __register_linger_request(osdc, req); | |
1310 | - __unregister_request(osdc, req); | |
1311 | - } | |
1312 | 1319 | } |
1313 | 1320 | |
1314 | 1321 | list_for_each_entry_safe(req, nreq, &osdc->req_linger, |
... | ... | @@ -1316,6 +1323,7 @@ |
1316 | 1323 | dout("linger req=%p req->r_osd=%p\n", req, req->r_osd); |
1317 | 1324 | |
1318 | 1325 | err = __map_request(osdc, req, force_resend); |
1326 | + dout("__map_request returned %d\n", err); | |
1319 | 1327 | if (err == 0) |
1320 | 1328 | continue; /* no change and no osd was specified */ |
1321 | 1329 | if (err < 0) |
... | ... | @@ -1337,6 +1345,7 @@ |
1337 | 1345 | dout("%d requests for down osds, need new map\n", needmap); |
1338 | 1346 | ceph_monc_request_next_osdmap(&osdc->client->monc); |
1339 | 1347 | } |
1348 | + reset_changed_osds(osdc); | |
1340 | 1349 | } |
1341 | 1350 | |
1342 | 1351 | |
... | ... | @@ -1393,7 +1402,6 @@ |
1393 | 1402 | osdc->osdmap = newmap; |
1394 | 1403 | } |
1395 | 1404 | kick_requests(osdc, 0); |
1396 | - reset_changed_osds(osdc); | |
1397 | 1405 | } else { |
1398 | 1406 | dout("ignoring incremental map %u len %d\n", |
1399 | 1407 | epoch, maplen); |