@@ -3212,16 +3212,13 @@ static void complete_update_ascii(conn *c)
32123212 }
32133213
32143214 item *it = c->item;
3215+ ENGINE_ERROR_CODE ret;
32153216 if (!mc_engine.v1->get_item_info(mc_engine.v0, c, it, &c->hinfo)) {
3216- mc_engine.v1->release(mc_engine.v0, c, it);
32173217 mc_logger->log(EXTENSION_LOG_WARNING, c,
32183218 "%d: Failed to get item info\n", c->sfd);
3219- out_string(c, "SERVER_ERROR failed to get item details");
3220- return;
3221- }
3222-
3223- ENGINE_ERROR_CODE ret;
3224- if (hinfo_check_ascii_tail_string(&c->hinfo) != 0) { /* check "\r\n" */
3219+ out_string(c, "SERVER_ERROR out of memory for getting item info");
3220+ ret = ENGINE_ENOMEM;
3221+ } else if (hinfo_check_ascii_tail_string(&c->hinfo) != 0) { /* check "\r\n" */
32253222 out_string(c, "CLIENT_ERROR bad data chunk");
32263223 ret = ENGINE_EBADVALUE;
32273224 } else {
@@ -3705,87 +3702,86 @@ static void complete_update_bin(conn *c)
37053702 assert(c != NULL);
37063703
37073704 item *it = c->item;
3705+ ENGINE_ERROR_CODE ret;
37083706 if (!mc_engine.v1->get_item_info(mc_engine.v0, c, it, &c->hinfo)) {
3709- mc_engine.v1->release(mc_engine.v0, c, it);
37103707 mc_logger->log(EXTENSION_LOG_WARNING, c,
37113708 "%d: Failed to get item info\n", c->sfd);
3712- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINTERNAL , 0);
3713- return ;
3714- }
3715- /* We don't actually receive the trailing two characters in the bin
3716- * protocol, so we're going to just append them here */
3717- hinfo_append_ascii_tail_string(&c->hinfo); /* append "\r\n" */
3709+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM , 0);
3710+ ret = ENGINE_ENOMEM ;
3711+ } else {
3712+ /* We don't actually receive the trailing two characters in the bin
3713+ * protocol, so we're going to just append them here */
3714+ hinfo_append_ascii_tail_string(&c->hinfo); /* append "\r\n" */
37183715
3719- ENGINE_ERROR_CODE ret;
3720- ret = mc_engine.v1->store(mc_engine.v0, c, it, &c->cas, c->store_op,
3721- c->binary_header.request.vbucket);
3722- CONN_CHECK_AND_SET_EWOULDBLOCK(ret, c);
3716+ ret = mc_engine.v1->store(mc_engine.v0, c, it, &c->cas, c->store_op,
3717+ c->binary_header.request.vbucket);
3718+ CONN_CHECK_AND_SET_EWOULDBLOCK(ret, c);
37233719#ifdef ENABLE_DTRACE
3724- switch (c->cmd) {
3725- case OPERATION_ADD:
3726- MEMCACHED_COMMAND_ADD(c->sfd, c->hinfo.key, c->hinfo.nkey,
3727- (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3728- break;
3729- case OPERATION_REPLACE:
3730- MEMCACHED_COMMAND_REPLACE(c->sfd, c->hinfo.key, c->hinfo.nkey,
3720+ switch (c->cmd) {
3721+ case OPERATION_ADD:
3722+ MEMCACHED_COMMAND_ADD(c->sfd, c->hinfo.key, c->hinfo.nkey,
37313723 (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3732- break;
3733- case OPERATION_APPEND:
3734- MEMCACHED_COMMAND_APPEND(c->sfd, c->hinfo.key, c->hinfo.nkey,
3735- (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3736- break;
3737- case OPERATION_PREPEND:
3738- MEMCACHED_COMMAND_PREPEND(c->sfd, c->hinfo.key, c->hinfo.nkey,
3724+ break;
3725+ case OPERATION_REPLACE:
3726+ MEMCACHED_COMMAND_REPLACE(c->sfd, c->hinfo.key, c->hinfo.nkey,
3727+ (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3728+ break;
3729+ case OPERATION_APPEND:
3730+ MEMCACHED_COMMAND_APPEND(c->sfd, c->hinfo.key, c->hinfo.nkey,
3731+ (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3732+ break;
3733+ case OPERATION_PREPEND:
3734+ MEMCACHED_COMMAND_PREPEND(c->sfd, c->hinfo.key, c->hinfo.nkey,
3735+ (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3736+ break;
3737+ case OPERATION_SET:
3738+ MEMCACHED_COMMAND_SET(c->sfd, c->hinfo.key, c->hinfo.nkey,
37393739 (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3740- break;
3741- case OPERATION_SET:
3742- MEMCACHED_COMMAND_SET(c->sfd, c->hinfo.key, c->hinfo.nkey,
3743- (ret == ENGINE_SUCCESS) ? c->hinfo.nbytes : -1, c->cas);
3744- break;
3745- }
3740+ break;
3741+ }
37463742#endif
37473743
3748- switch (ret) {
3749- case ENGINE_SUCCESS:
3750- write_bin_response(c, NULL, 0, 0, 0);
3751- break;
3752- case ENGINE_KEY_EEXISTS:
3753- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0);
3754- break;
3755- case ENGINE_KEY_ENOENT:
3756- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0);
3757- break;
3758- case ENGINE_NOT_STORED:
3759- /* FIXME: check below code, later. */
3760- if (c->store_op == OPERATION_ADD) {
3744+ switch (ret) {
3745+ case ENGINE_SUCCESS:
3746+ write_bin_response(c, NULL, 0, 0, 0);
3747+ break;
3748+ case ENGINE_KEY_EEXISTS:
37613749 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0);
3762- } else if (c->store_op == OPERATION_REPLACE) {
3750+ break;
3751+ case ENGINE_KEY_ENOENT:
37633752 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0);
3764- } else {
3765- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_NOT_STORED, 0);
3753+ break;
3754+ case ENGINE_NOT_STORED:
3755+ /* FIXME: check below code, later. */
3756+ if (c->store_op == OPERATION_ADD) {
3757+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0);
3758+ } else if (c->store_op == OPERATION_REPLACE) {
3759+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0);
3760+ } else {
3761+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_NOT_STORED, 0);
3762+ }
3763+ break;
3764+ case ENGINE_PREFIX_ENAME:
3765+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_PREFIX_ENAME, 0);
3766+ break;
3767+ case ENGINE_ENOMEM:
3768+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0);
3769+ break;
3770+ case ENGINE_EINVAL:
3771+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINVAL, 0);
3772+ break;
3773+ case ENGINE_E2BIG:
3774+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_E2BIG, 0);
3775+ break;
3776+ case ENGINE_NOT_MY_VBUCKET:
3777+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET, 0);
3778+ break;
3779+ case ENGINE_EBADTYPE:
3780+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EBADTYPE, 0);
3781+ break;
3782+ default:
3783+ handle_unexpected_errorcode_bin(c, __func__, ret, 0);
37663784 }
3767- //write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_NOT_STORED, 0);
3768- break;
3769- case ENGINE_PREFIX_ENAME:
3770- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_PREFIX_ENAME, 0);
3771- break;
3772- case ENGINE_ENOMEM:
3773- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0);
3774- break;
3775- case ENGINE_EINVAL:
3776- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINVAL, 0);
3777- break;
3778- case ENGINE_E2BIG:
3779- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_E2BIG, 0);
3780- break;
3781- case ENGINE_NOT_MY_VBUCKET:
3782- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET, 0);
3783- break;
3784- case ENGINE_EBADTYPE:
3785- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EBADTYPE, 0);
3786- break;
3787- default:
3788- handle_unexpected_errorcode_bin(c, __func__, ret, 0);
37893785 }
37903786
37913787 if (c->store_op == OPERATION_CAS) {
@@ -3829,7 +3825,7 @@ static void process_bin_get(conn *c)
38293825 mc_engine.v1->release(mc_engine.v0, c, it);
38303826 mc_logger->log(EXTENSION_LOG_WARNING, c,
38313827 "%d: Failed to get item info\n", c->sfd);
3832- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINTERNAL , 0);
3828+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM , 0);
38333829 break;
38343830 }
38353831
@@ -7104,41 +7100,43 @@ static void process_bin_update(conn *c)
71047100 req->message.body.flags,
71057101 realtime(req->message.body.expiration),
71067102 c->binary_header.request.cas);
7107- if (ret == ENGINE_SUCCESS && !mc_engine.v1->get_item_info(mc_engine.v0,
7108- c, it, &c->hinfo)) {
7109- mc_engine.v1->release(mc_engine.v0, c, it);
7110- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINTERNAL, 0);
7111- return;
7112- }
7103+ if (ret == ENGINE_SUCCESS) {
7104+ if (!mc_engine.v1->get_item_info(mc_engine.v0, c, it, &c->hinfo)) {
7105+ mc_engine.v1->release(mc_engine.v0, c, it);
7106+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen);
7107+ ret = ENGINE_ENOMEM;
7108+ } else {
7109+ if (c->cmd == PROTOCOL_BINARY_CMD_ADD)
7110+ c->store_op = OPERATION_ADD;
7111+ else if (c->cmd == PROTOCOL_BINARY_CMD_SET)
7112+ c->store_op = OPERATION_SET;
7113+ else if (c->cmd == PROTOCOL_BINARY_CMD_REPLACE)
7114+ c->store_op = OPERATION_REPLACE;
7115+ else
7116+ assert(0);
71137117
7114- switch (ret) {
7115- case ENGINE_SUCCESS:
7116- if (c->cmd == PROTOCOL_BINARY_CMD_ADD)
7117- c->store_op = OPERATION_ADD;
7118- else if (c->cmd == PROTOCOL_BINARY_CMD_SET)
7119- c->store_op = OPERATION_SET;
7120- else if (c->cmd == PROTOCOL_BINARY_CMD_REPLACE)
7121- c->store_op = OPERATION_REPLACE;
7122- else
7123- assert(0);
7118+ if (c->binary_header.request.cas != 0) {
7119+ c->store_op = OPERATION_CAS;
7120+ }
71247121
7125- if (c->binary_header.request.cas != 0) {
7126- c->store_op = OPERATION_CAS;
7122+ c->item = it;
7123+ ritem_set_first(c, CONN_RTYPE_HINFO, vlen);
7124+ conn_set_state(c, conn_nread);
7125+ c->substate = bin_read_set_value;
71277126 }
7128-
7129- c->item = it;
7130- ritem_set_first(c, CONN_RTYPE_HINFO, vlen);
7131- conn_set_state(c, conn_nread);
7132- c->substate = bin_read_set_value;
7133- break;
7134- case ENGINE_E2BIG:
7135- case ENGINE_ENOMEM:
7136- if (ret == ENGINE_E2BIG) {
7127+ } else {
7128+ switch (ret) {
7129+ case ENGINE_E2BIG:
71377130 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_E2BIG, vlen);
7138- } else {
7131+ break;
7132+ case ENGINE_ENOMEM:
71397133 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen);
7134+ break;
7135+ default:
7136+ handle_unexpected_errorcode_bin(c, __func__, ret, vlen);
71407137 }
7141-
7138+ }
7139+ if (ret != ENGINE_SUCCESS) {
71427140 /*
71437141 * Avoid stale data persisting in cache because we failed alloc.
71447142 * Unacceptable for SET (but only if cas matches).
@@ -7158,9 +7156,6 @@ static void process_bin_update(conn *c)
71587156 c->noreply = false;
71597157 }
71607158 }
7161- break;
7162- default:
7163- handle_unexpected_errorcode_bin(c, __func__, ret, vlen);
71647159 }
71657160}
71667161
@@ -7186,37 +7181,34 @@ static void process_bin_append_prepend(conn *c)
71867181 ENGINE_ERROR_CODE ret;
71877182 ret = mc_engine.v1->allocate(mc_engine.v0, c, &it, key, nkey, vlen+2,
71887183 0, 0, c->binary_header.request.cas);
7189- if (ret == ENGINE_SUCCESS && !mc_engine.v1->get_item_info(mc_engine.v0,
7190- c, it, &c->hinfo)) {
7191- mc_engine.v1->release(mc_engine.v0, c, it);
7192- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_EINTERNAL, 0);
7193- return;
7194- }
7195-
7196- switch (ret) {
7197- case ENGINE_SUCCESS:
7198- if (c->cmd == PROTOCOL_BINARY_CMD_APPEND)
7199- c->store_op = OPERATION_APPEND;
7200- else if (c->cmd == PROTOCOL_BINARY_CMD_PREPEND)
7201- c->store_op = OPERATION_PREPEND;
7202- else
7203- assert(0);
7184+ if (ret == ENGINE_SUCCESS) {
7185+ if (!mc_engine.v1->get_item_info(mc_engine.v0, c, it, &c->hinfo)) {
7186+ mc_engine.v1->release(mc_engine.v0, c, it);
7187+ write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen);
7188+ } else {
7189+ if (c->cmd == PROTOCOL_BINARY_CMD_APPEND)
7190+ c->store_op = OPERATION_APPEND;
7191+ else if (c->cmd == PROTOCOL_BINARY_CMD_PREPEND)
7192+ c->store_op = OPERATION_PREPEND;
7193+ else
7194+ assert(0);
72047195
7205- c->item = it;
7206- ritem_set_first(c, CONN_RTYPE_HINFO, vlen);
7207- conn_set_state(c, conn_nread);
7208- c->substate = bin_read_set_value;
7209- break;
7210- case ENGINE_E2BIG:
7211- case ENGINE_ENOMEM:
7212- if (ret == ENGINE_E2BIG) {
7196+ c->item = it;
7197+ ritem_set_first(c, CONN_RTYPE_HINFO, vlen);
7198+ conn_set_state(c, conn_nread);
7199+ c->substate = bin_read_set_value;
7200+ }
7201+ } else {
7202+ switch (ret) {
7203+ case ENGINE_E2BIG:
72137204 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_E2BIG, vlen);
7214- } else {
7205+ break;
7206+ case ENGINE_ENOMEM:
72157207 write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen);
7208+ break;
7209+ default:
7210+ handle_unexpected_errorcode_bin(c, __func__, ret, vlen);
72167211 }
7217- break;
7218- default:
7219- handle_unexpected_errorcode_bin(c, __func__, ret, vlen);
72207212 }
72217213}
72227214
@@ -8475,25 +8467,24 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken
84758467 if (!mc_engine.v1->get_item_info(mc_engine.v0, c, it, &c->hinfo)) {
84768468 mc_engine.v1->release(mc_engine.v0, c, it);
84778469 out_string(c, "SERVER_ERROR error getting item data");
8478- ret = ENGINE_FAILED; /* FIXME: error type */
8470+ ret = ENGINE_ENOMEM;
84798471 } else {
84808472 c->item = it;
84818473 ritem_set_first(c, CONN_RTYPE_HINFO, vlen);
84828474 c->store_op = store_op;
84838475 conn_set_state(c, conn_nread);
84848476 }
8485- }
8486- if (ret != ENGINE_SUCCESS) {
8477+ } else {
84878478 if (ret == ENGINE_E2BIG) {
84888479 out_string(c, "CLIENT_ERROR object too large for cache");
84898480 } else if (ret == ENGINE_ENOMEM) {
84908481 out_string(c, "SERVER_ERROR out of memory storing object");
8491- } else if (ret == ENGINE_FAILED) {
8492- /* out_string() was called above. so, do nothing */
84938482 } else {
84948483 handle_unexpected_errorcode_ascii(c, __func__, ret);
84958484 }
8485+ }
84968486
8487+ if (ret != ENGINE_SUCCESS) {
84978488 /* Avoid stale data persisting in cache because we failed alloc.
84988489 * Unacceptable for SET. Anywhere else too?
84998490 */
0 commit comments