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 are a couple of fixes from Yan for bad pointer dereferences in
the messenger code and when fiddling with page->private after page
migration, a fix from Alex for a use-after-free in the osd client
code, and a couple fixes for the message refcounting and shutdown
ordering."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
libceph: flush msgr queue during mon_client shutdown
rbd: Clear ceph_msg->bio_iter for retransmitted message
libceph: use con get/put ops from osd_client
libceph: osd_client: don't drop reply reference too early
ceph: check PG_Private flag before accessing page->private

+30 -22
+12 -9
fs/ceph/addr.c
··· 54 54 (CONGESTION_ON_THRESH(congestion_kb) - \ 55 55 (CONGESTION_ON_THRESH(congestion_kb) >> 2)) 56 56 57 - 57 + static inline struct ceph_snap_context *page_snap_context(struct page *page) 58 + { 59 + if (PagePrivate(page)) 60 + return (void *)page->private; 61 + return NULL; 62 + } 58 63 59 64 /* 60 65 * Dirty a page. Optimistically adjust accounting, on the assumption ··· 147 142 { 148 143 struct inode *inode; 149 144 struct ceph_inode_info *ci; 150 - struct ceph_snap_context *snapc = (void *)page->private; 145 + struct ceph_snap_context *snapc = page_snap_context(page); 151 146 152 147 BUG_ON(!PageLocked(page)); 153 - BUG_ON(!page->private); 154 148 BUG_ON(!PagePrivate(page)); 155 149 BUG_ON(!page->mapping); 156 150 ··· 186 182 struct inode *inode = page->mapping ? page->mapping->host : NULL; 187 183 dout("%p releasepage %p idx %lu\n", inode, page, page->index); 188 184 WARN_ON(PageDirty(page)); 189 - WARN_ON(page->private); 190 185 WARN_ON(PagePrivate(page)); 191 186 return 0; 192 187 } ··· 446 443 osdc = &fsc->client->osdc; 447 444 448 445 /* verify this is a writeable snap context */ 449 - snapc = (void *)page->private; 446 + snapc = page_snap_context(page); 450 447 if (snapc == NULL) { 451 448 dout("writepage %p page %p not dirty?\n", inode, page); 452 449 goto out; ··· 454 451 oldest = get_oldest_context(inode, &snap_size); 455 452 if (snapc->seq > oldest->seq) { 456 453 dout("writepage %p page %p snapc %p not writeable - noop\n", 457 - inode, page, (void *)page->private); 454 + inode, page, snapc); 458 455 /* we should only noop if called by kswapd */ 459 456 WARN_ON((current->flags & PF_MEMALLOC) == 0); 460 457 ceph_put_snap_context(oldest); ··· 594 591 clear_bdi_congested(&fsc->backing_dev_info, 595 592 BLK_RW_ASYNC); 596 593 597 - ceph_put_snap_context((void *)page->private); 594 + ceph_put_snap_context(page_snap_context(page)); 598 595 page->private = 0; 599 596 ClearPagePrivate(page); 600 597 dout("unlocking %d %p\n", i, page); ··· 798 795 } 799 796 800 797 /* only if matching snap context */ 801 - pgsnapc = (void *)page->private; 798 + pgsnapc = page_snap_context(page); 802 799 if (pgsnapc->seq > snapc->seq) { 803 800 dout("page snapc %p %lld > oldest %p %lld\n", 804 801 pgsnapc, pgsnapc->seq, snapc, snapc->seq); ··· 987 984 BUG_ON(!ci->i_snap_realm); 988 985 down_read(&mdsc->snap_rwsem); 989 986 BUG_ON(!ci->i_snap_realm->cached_context); 990 - snapc = (void *)page->private; 987 + snapc = page_snap_context(page); 991 988 if (snapc && snapc != ci->i_head_snapc) { 992 989 /* 993 990 * this page is already dirty in another (older) snap
-7
net/ceph/ceph_common.c
··· 504 504 /* unmount */ 505 505 ceph_osdc_stop(&client->osdc); 506 506 507 - /* 508 - * make sure osd connections close out before destroying the 509 - * auth module, which is needed to free those connections' 510 - * ceph_authorizers. 511 - */ 512 - ceph_msgr_flush(); 513 - 514 507 ceph_monc_stop(&client->monc); 515 508 516 509 ceph_debugfs_client_cleanup(client);
+4
net/ceph/messenger.c
··· 563 563 m->hdr.seq = cpu_to_le64(++con->out_seq); 564 564 m->needs_out_seq = false; 565 565 } 566 + #ifdef CONFIG_BLOCK 567 + else 568 + m->bio_iter = NULL; 569 + #endif 566 570 567 571 dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", 568 572 m, con->out_seq, le16_to_cpu(m->hdr.type),
+8
net/ceph/mon_client.c
··· 847 847 848 848 mutex_unlock(&monc->mutex); 849 849 850 + /* 851 + * flush msgr queue before we destroy ourselves to ensure that: 852 + * - any work that references our embedded con is finished. 853 + * - any osd_client or other work that may reference an authorizer 854 + * finishes before we shut down the auth subsystem. 855 + */ 856 + ceph_msgr_flush(); 857 + 850 858 ceph_auth_destroy(monc->auth); 851 859 852 860 ceph_msg_put(monc->m_auth);
+6 -6
net/ceph/osd_client.c
··· 139 139 140 140 if (req->r_request) 141 141 ceph_msg_put(req->r_request); 142 - if (req->r_reply) 143 - ceph_msg_put(req->r_reply); 144 142 if (req->r_con_filling_msg) { 145 143 dout("release_request revoking pages %p from con %p\n", 146 144 req->r_pages, req->r_con_filling_msg); 147 145 ceph_con_revoke_message(req->r_con_filling_msg, 148 146 req->r_reply); 149 - ceph_con_put(req->r_con_filling_msg); 147 + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); 150 148 } 149 + if (req->r_reply) 150 + ceph_msg_put(req->r_reply); 151 151 if (req->r_own_pages) 152 152 ceph_release_page_vector(req->r_pages, 153 153 req->r_num_pages); ··· 1216 1216 if (req->r_con_filling_msg == con && req->r_reply == msg) { 1217 1217 dout(" dropping con_filling_msg ref %p\n", con); 1218 1218 req->r_con_filling_msg = NULL; 1219 - ceph_con_put(con); 1219 + con->ops->put(con); 1220 1220 } 1221 1221 1222 1222 if (!req->r_got_reply) { ··· 2028 2028 dout("get_reply revoking msg %p from old con %p\n", 2029 2029 req->r_reply, req->r_con_filling_msg); 2030 2030 ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); 2031 - ceph_con_put(req->r_con_filling_msg); 2031 + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); 2032 2032 req->r_con_filling_msg = NULL; 2033 2033 } 2034 2034 ··· 2063 2063 #endif 2064 2064 } 2065 2065 *skip = 0; 2066 - req->r_con_filling_msg = ceph_con_get(con); 2066 + req->r_con_filling_msg = con->ops->get(con); 2067 2067 dout("get_reply tid %lld %p\n", tid, m); 2068 2068 2069 2069 out: