Skip to content

Commit 3b83f60

Browse files
committed
libceph: enable fallback to ceph_msg_new() in ceph_msgpool_get()
ceph_msgpool_get() can fall back to ceph_msg_new() when it is asked for a message whose front portion is larger than pool->front_len. However the caller always passes 0, effectively disabling that code path. The allocation goes to the message pool and returns a message with a front that is smaller than requested, setting us up for a crash. One example of this is a directory with a large number of snapshots. If its snap context doesn't fit, we oops in encode_request_partial(). Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 61d2f85 commit 3b83f60

File tree

2 files changed

+3
-3
lines changed

2 files changed

+3
-3
lines changed

net/ceph/msgpool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
6161
if (front_len > pool->front_len) {
6262
dout("msgpool_get %s need front %d, pool size is %d\n",
6363
pool->name, front_len, pool->front_len);
64-
WARN_ON(1);
64+
WARN_ON_ONCE(1);
6565

6666
/* try to alloc a fresh message */
6767
return ceph_msg_new(pool->type, front_len, GFP_NOFS, false);

net/ceph/osd_client.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
641641
msg_size += 4 + 8; /* retry_attempt, features */
642642

643643
if (req->r_mempool)
644-
msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
644+
msg = ceph_msgpool_get(&osdc->msgpool_op, msg_size);
645645
else
646646
msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp, true);
647647
if (!msg)
@@ -656,7 +656,7 @@ int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
656656
msg_size += req->r_num_ops * sizeof(struct ceph_osd_op);
657657

658658
if (req->r_mempool)
659-
msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
659+
msg = ceph_msgpool_get(&osdc->msgpool_op_reply, msg_size);
660660
else
661661
msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, msg_size, gfp, true);
662662
if (!msg)

0 commit comments

Comments
 (0)