diff --git a/src/client/messenger.h b/src/client/messenger.h index c254b25f..17d82d76 100644 --- a/src/client/messenger.h +++ b/src/client/messenger.h @@ -38,6 +38,8 @@ #define MSGR_SENDP_HDR 1 #define MSGR_SENDP_FREE 2 +#define MAX_SIMPLE_PAYLOAD_SIZE 1048576 + struct msgr_sendp_t { osd_op_t *op; @@ -181,9 +183,12 @@ public: timerfd_manager_t *tfd = NULL; ring_loop_i *ringloop = NULL; bool has_sendmsg_zc = false; - // osd_num_t is only for logging and asserts uint64_t next_client_id = 1; - osd_num_t osd_num; + // osd_num = 0 for client messenger, osd_num > 0 for OSD messenger + osd_num_t osd_num = 0; + uint32_t clean_entry_bitmap_size = 0; + uint32_t bs_block_size = 0; + uint32_t max_write_request_size = 0; robin_hood::unordered_flat_map clients; robin_hood::unordered_flat_map osd_peers; robin_hood::unordered_flat_map clients_by_fd; @@ -249,7 +254,7 @@ protected: bool handle_read(int result, osd_client_t *cl); bool handle_read_buffer(osd_client_t *cl, void *curbuf, int remain); bool handle_finished_read(osd_client_t *cl); - void handle_op_hdr(osd_client_t *cl); + bool handle_op_hdr(osd_client_t *cl); bool handle_reply_hdr(osd_client_t *cl); void handle_reply_ready(osd_op_t *op); void handle_immediate_ops(); diff --git a/src/client/msgr_op.h b/src/client/msgr_op.h index ce8c2869..59f70e96 100644 --- a/src/client/msgr_op.h +++ b/src/client/msgr_op.h @@ -165,7 +165,7 @@ struct __attribute__((visibility("default"))) osd_op_t // bitmap, bitmap_len, bmp_data are only meaningful for reads void *bitmap = NULL; unsigned bitmap_len = 0; - unsigned bmp_data = 0; + size_t bmp_data = 0; void *bitmap_buf = NULL; void *rmw_buf = NULL; osd_primary_op_data_t* op_data = NULL; diff --git a/src/client/msgr_receive.cpp b/src/client/msgr_receive.cpp index 19e26896..d0af75e3 100644 --- a/src/client/msgr_receive.cpp +++ b/src/client/msgr_receive.cpp @@ -231,7 +231,11 @@ bool osd_messenger_t::handle_finished_read(osd_client_t *cl) } cl->read_op_id++; } - handle_op_hdr(cl); + if (!handle_op_hdr(cl)) + { + stop_client(cl->client_id); + return false; + } } else { @@ -262,7 +266,7 @@ bool osd_messenger_t::handle_finished_read(osd_client_t *cl) return true; } -void osd_messenger_t::handle_op_hdr(osd_client_t *cl) +bool osd_messenger_t::handle_op_hdr(osd_client_t *cl) { osd_op_t *cur_op = cl->read_op; if (cur_op->req.hdr.opcode == OSD_OP_SEC_READ) @@ -274,7 +278,16 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) { if (cur_op->req.sec_rw.attr_len > 0) { - if (cur_op->req.sec_rw.attr_len > sizeof(unsigned)) + if (cur_op->req.sec_rw.attr_len > clean_entry_bitmap_size) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju secondary write request attr_len too large (%u > %u bytes), stopping\n", cl->client_id, + cur_op->req.sec_rw.attr_len, clean_entry_bitmap_size); + } + return false; + } + else if (cur_op->req.sec_rw.attr_len > sizeof(cur_op->bmp_data)) cur_op->bitmap = cur_op->rmw_buf = malloc_or_die(cur_op->req.sec_rw.attr_len); else cur_op->bitmap = &cur_op->bmp_data; @@ -282,6 +295,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) } if (cur_op->req.sec_rw.len > 0) { + if (cur_op->req.sec_rw.len > bs_block_size) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju secondary write request size too large (%u > %u bytes), stopping\n", cl->client_id, + cur_op->req.sec_rw.len, bs_block_size); + } + return false; + } cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_rw.len); cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_rw.len); } @@ -292,6 +314,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) { if (cur_op->req.sec_stab.len > 0) { + if (cur_op->req.sec_stab.len > MAX_SIMPLE_PAYLOAD_SIZE) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju stabilize request size too large (%lu > %u bytes), stopping\n", cl->client_id, + cur_op->req.sec_stab.len, MAX_SIMPLE_PAYLOAD_SIZE); + } + return false; + } cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_stab.len); cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_stab.len); } @@ -301,6 +332,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) { if (cur_op->req.sec_read_bmp.len > 0) { + if (cur_op->req.sec_read_bmp.len > MAX_SIMPLE_PAYLOAD_SIZE) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju sec_read_bmp request size too large (%lu > %u bytes), stopping\n", cl->client_id, + cur_op->req.sec_read_bmp.len, MAX_SIMPLE_PAYLOAD_SIZE); + } + return false; + } cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_read_bmp.len); cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_read_bmp.len); } @@ -310,6 +350,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) { if (cur_op->req.rw.len > 0) { + if (cur_op->req.rw.len > max_write_request_size) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju write request size too large (%u > %u bytes), stopping\n", cl->client_id, + cur_op->req.rw.len, max_write_request_size); + } + return false; + } cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.rw.len); cl->recv_list.push_back(cur_op->buf, cur_op->req.rw.len); } @@ -319,6 +368,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) { if (cur_op->req.show_conf.json_len > 0) { + if (cur_op->req.show_conf.json_len > MAX_SIMPLE_PAYLOAD_SIZE) + { + if (log_level > 1) + { + fprintf(stderr, "Error: peer %ju show_config request length too large (%lu > %u bytes), stopping\n", cl->client_id, + cur_op->req.show_conf.json_len, MAX_SIMPLE_PAYLOAD_SIZE); + } + return false; + } cur_op->buf = malloc_or_die(cur_op->req.show_conf.json_len+1); ((uint8_t*)cur_op->buf)[cur_op->req.show_conf.json_len] = 0; cl->recv_list.push_back(cur_op->buf, cur_op->req.show_conf.json_len); @@ -344,6 +402,7 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl) cl->read_op = NULL; cl->read_state = 0; } + return true; } bool osd_messenger_t::handle_reply_hdr(osd_client_t *cl) diff --git a/src/osd/osd.cpp b/src/osd/osd.cpp index 7078af0f..9af3d1e8 100644 --- a/src/osd/osd.cpp +++ b/src/osd/osd.cpp @@ -192,6 +192,9 @@ void osd_t::parse_config(bool init) if (!bs_bitmap_granularity) bs_bitmap_granularity = DEFAULT_BITMAP_GRANULARITY; clean_entry_bitmap_size = bs_block_size / bs_bitmap_granularity / 8; + msgr.bs_block_size = bs_block_size; + msgr.clean_entry_bitmap_size = clean_entry_bitmap_size; + msgr.max_write_request_size = MAX_DATA_BLOCK_SIZE; // will be changed after pool config // immediate_commit if (config["immediate_commit"] == "all") immediate_commit = IMMEDIATE_ALL; diff --git a/src/osd/osd_cluster.cpp b/src/osd/osd_cluster.cpp index 3ccf7129..9f19c2b3 100644 --- a/src/osd/osd_cluster.cpp +++ b/src/osd/osd_cluster.cpp @@ -427,6 +427,21 @@ void osd_t::on_change_pool_config_hook() { apply_pg_locks_localize_only(); } + msgr.max_write_request_size = 0; + for (auto & pc: st_cli->pool_config) + { + auto & pool_cfg = pc.second; + uint32_t pg_data_size = (pool_cfg.scheme == POOL_SCHEME_REPLICATED ? 1 : pool_cfg.pg_size-pool_cfg.parity_chunks); + uint32_t pg_block_size = pool_cfg.data_block_size * pg_data_size; + if (msgr.max_write_request_size < pg_block_size) + { + msgr.max_write_request_size = pg_block_size; + } + } + if (!msgr.max_write_request_size) + { + msgr.max_write_request_size = MAX_DATA_BLOCK_SIZE; + } } void osd_t::apply_pg_locks_localize_only() diff --git a/src/osd/osd_flush.cpp b/src/osd/osd_flush.cpp index 669f0552..63dd993f 100644 --- a/src/osd/osd_flush.cpp +++ b/src/osd/osd_flush.cpp @@ -6,6 +6,8 @@ #define FLUSH_BATCH 512 #define SELF_CLIENT 0 +static_assert(FLUSH_BATCH <= MAX_SIMPLE_PAYLOAD_SIZE / sizeof(obj_ver_id)); + void osd_t::submit_pg_flush_ops(pg_t & pg) { pg_flush_batch_t *fb = new pg_flush_batch_t();