Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

Pull ceph fixes from Sage Weil:
"There is an RBD fix for a crash due to the immutable bio changes, an
error path fix, and a locking fix in the recent redirect support"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
libceph: do not dereference a NULL bio pointer
libceph: take map_sem for read in handle_reply()
libceph: factor out logic from ceph_osdc_start_request()
libceph: fix error handling in ceph_osdc_init()

+60 -32
+6 -2
net/ceph/messenger.c
··· 840 840 841 841 if (!cursor->bvec_iter.bi_size) { 842 842 bio = bio->bi_next; 843 - cursor->bvec_iter = bio->bi_iter; 843 + cursor->bio = bio; 844 + if (bio) 845 + cursor->bvec_iter = bio->bi_iter; 846 + else 847 + memset(&cursor->bvec_iter, 0, 848 + sizeof(cursor->bvec_iter)); 844 849 } 845 - cursor->bio = bio; 846 850 847 851 if (!cursor->last_piece) { 848 852 BUG_ON(!cursor->resid);
+54 -30
net/ceph/osd_client.c
··· 1427 1427 } 1428 1428 1429 1429 /* 1430 + * Caller should hold map_sem for read and request_mutex. 1431 + */ 1432 + static int __ceph_osdc_start_request(struct ceph_osd_client *osdc, 1433 + struct ceph_osd_request *req, 1434 + bool nofail) 1435 + { 1436 + int rc; 1437 + 1438 + __register_request(osdc, req); 1439 + req->r_sent = 0; 1440 + req->r_got_reply = 0; 1441 + rc = __map_request(osdc, req, 0); 1442 + if (rc < 0) { 1443 + if (nofail) { 1444 + dout("osdc_start_request failed map, " 1445 + " will retry %lld\n", req->r_tid); 1446 + rc = 0; 1447 + } else { 1448 + __unregister_request(osdc, req); 1449 + } 1450 + return rc; 1451 + } 1452 + 1453 + if (req->r_osd == NULL) { 1454 + dout("send_request %p no up osds in pg\n", req); 1455 + ceph_monc_request_next_osdmap(&osdc->client->monc); 1456 + } else { 1457 + __send_queued(osdc); 1458 + } 1459 + 1460 + return 0; 1461 + } 1462 + 1463 + /* 1430 1464 * Timeout callback, called every N seconds when 1 or more osd 1431 1465 * requests has been active for more than N seconds. When this 1432 1466 * happens, we ping all OSDs with requests who have timed out to ··· 1687 1653 osdmap_epoch = ceph_decode_32(&p); 1688 1654 1689 1655 /* lookup */ 1656 + down_read(&osdc->map_sem); 1690 1657 mutex_lock(&osdc->request_mutex); 1691 1658 req = __lookup_request(osdc, tid); 1692 1659 if (req == NULL) { ··· 1744 1709 dout("redirect pool %lld\n", redir.oloc.pool); 1745 1710 1746 1711 __unregister_request(osdc, req); 1747 - mutex_unlock(&osdc->request_mutex); 1748 1712 1749 1713 req->r_target_oloc = redir.oloc; /* struct */ 1750 1714 ··· 1755 1721 * successfully. In the future we might want to follow 1756 1722 * original request's nofail setting here. 1757 1723 */ 1758 - err = ceph_osdc_start_request(osdc, req, true); 1724 + err = __ceph_osdc_start_request(osdc, req, true); 1759 1725 BUG_ON(err); 1760 1726 1761 - goto done; 1727 + goto out_unlock; 1762 1728 } 1763 1729 1764 1730 already_completed = req->r_got_reply; ··· 1776 1742 req->r_got_reply = 1; 1777 1743 } else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) { 1778 1744 dout("handle_reply tid %llu dup ack\n", tid); 1779 - mutex_unlock(&osdc->request_mutex); 1780 - goto done; 1745 + goto out_unlock; 1781 1746 } 1782 1747 1783 1748 dout("handle_reply tid %llu flags %d\n", tid, flags); ··· 1791 1758 __unregister_request(osdc, req); 1792 1759 1793 1760 mutex_unlock(&osdc->request_mutex); 1761 + up_read(&osdc->map_sem); 1794 1762 1795 1763 if (!already_completed) { 1796 1764 if (req->r_unsafe_callback && ··· 1809 1775 complete_request(req); 1810 1776 } 1811 1777 1812 - done: 1778 + out: 1813 1779 dout("req=%p req->r_linger=%d\n", req, req->r_linger); 1814 1780 ceph_osdc_put_request(req); 1815 1781 return; 1782 + out_unlock: 1783 + mutex_unlock(&osdc->request_mutex); 1784 + up_read(&osdc->map_sem); 1785 + goto out; 1816 1786 1817 1787 bad_put: 1818 1788 req->r_result = -EIO; ··· 1829 1791 ceph_osdc_put_request(req); 1830 1792 bad_mutex: 1831 1793 mutex_unlock(&osdc->request_mutex); 1794 + up_read(&osdc->map_sem); 1832 1795 bad: 1833 1796 pr_err("corrupt osd_op_reply got %d %d\n", 1834 1797 (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len)); ··· 2390 2351 struct ceph_osd_request *req, 2391 2352 bool nofail) 2392 2353 { 2393 - int rc = 0; 2354 + int rc; 2394 2355 2395 2356 down_read(&osdc->map_sem); 2396 2357 mutex_lock(&osdc->request_mutex); 2397 - __register_request(osdc, req); 2398 - req->r_sent = 0; 2399 - req->r_got_reply = 0; 2400 - rc = __map_request(osdc, req, 0); 2401 - if (rc < 0) { 2402 - if (nofail) { 2403 - dout("osdc_start_request failed map, " 2404 - " will retry %lld\n", req->r_tid); 2405 - rc = 0; 2406 - } else { 2407 - __unregister_request(osdc, req); 2408 - } 2409 - goto out_unlock; 2410 - } 2411 - if (req->r_osd == NULL) { 2412 - dout("send_request %p no up osds in pg\n", req); 2413 - ceph_monc_request_next_osdmap(&osdc->client->monc); 2414 - } else { 2415 - __send_queued(osdc); 2416 - } 2417 - rc = 0; 2418 - out_unlock: 2358 + 2359 + rc = __ceph_osdc_start_request(osdc, req, nofail); 2360 + 2419 2361 mutex_unlock(&osdc->request_mutex); 2420 2362 up_read(&osdc->map_sem); 2363 + 2421 2364 return rc; 2422 2365 } 2423 2366 EXPORT_SYMBOL(ceph_osdc_start_request); ··· 2525 2504 err = -ENOMEM; 2526 2505 osdc->notify_wq = create_singlethread_workqueue("ceph-watch-notify"); 2527 2506 if (!osdc->notify_wq) 2528 - goto out_msgpool; 2507 + goto out_msgpool_reply; 2508 + 2529 2509 return 0; 2530 2510 2511 + out_msgpool_reply: 2512 + ceph_msgpool_destroy(&osdc->msgpool_op_reply); 2531 2513 out_msgpool: 2532 2514 ceph_msgpool_destroy(&osdc->msgpool_op); 2533 2515 out_mempool: