Skip to content

Commit 3260b98

Browse files
committed
FIX: Modify mismatched error types when get_item_info failed
1 parent 5505624 commit 3260b98

File tree

1 file changed

+132
-141
lines changed

1 file changed

+132
-141
lines changed

memcached.c

Lines changed: 132 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)