memcached / memcached/memcached
mg: E (new CAS) flag ignored when modifying an existing item
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 14.3k
- Forks
- 3.3k
- PR merge metrics
- No merged PRs in 30d
Description
Describe the bug
Meta Get (mg) documents the E(token) flag as "use token as new CAS value if item is modified"(doc/protocol.txt:558, in the metaget flag list). In practice E is applied only when mg autovivifies a new item (N flag); when mg modifies an existing item — e.g. touches its TTL with T — the E override is parsed and then silently dropped, and the item keeps its old CAS. Either the modify path is missing the override, or E should not be listed for mg in the docs.
To Reproduce
Against a default instance (memcached -p 11311 -l 127.0.0.1), over nc. use_cas is on (default). Sequence and actual responses:
set foo 0 0 3
bar
STORED
mg foo c t
HD c2 t-1 // baseline: CAS=2, no TTL
mg foo T90 E555 c t
HD c2 t90 // T applied (TTL→90) but CAS is STILL 2, not 555
mg foo c t
HD c2 t90 // confirms CAS unchanged
// contrast — E IS honored when N autovivifies a NEW key:
mg newkey N90 E555 c t
HD c555 t90 W // created; CAS set to 555 by E
mg newkey c t
HD c555 t90 Z // confirms CAS=555
Expected: because T90 modified foo, E555 should set its CAS to 555, so the second mg foo c t should report c555. Actual: CAS stays c2 on the modify path; E works only on autovivify-create.
Versions affected: reproduced on 1.6.44 (latest at time of writing). The relevant code (E parsed for all meta cmds, applied only on the mg autovivify do_item_link, with no case 'E' in the existing-item flag loop) appears unchanged for many prior releases, so likely long-standing — not an upgrade regression.
Root cause pointer (in case useful): E is parsed into of.cas_id_in at proto_parser.c:593; applied on autovivify via do_item_link(it, hv, of.has_cas_in ? of.cas_id_in : get_cas_id()); but the existing-item flag loop in process_mget handles T/N/R/s/t/c/f with no case 'E', so no ITEM_set_cas on the modify path. The parser comment at proto_parser.c:593 scopes E to // ms, md, ma, which suggests the doc listing E under metaget may be the error.
System Information
- OS/Distro: Ubuntu
- Version of OS/distro: 24.04.4 LTS (kernel 6.17.0-35-generic, x86_64)
- Version of memcached: 1.6.44
- Hardware detail: 13th Gen Intel Core i7-1360P (16 cores)
Detail (please include!)
No crash/segfault — addr2line/core dump N/A.
Fresh default instance. Relevant stats settings:
STAT cas_enabled yes
STAT maxbytes 67108864
STAT item_size_max 1048576
STAT num_threads 4
STAT binding_protocol auto-negotiate
STAT hashpower_init 0
STAT verbosity 0
stats (post-repro, otherwise idle): version 1.6.44, pointer_size 64, curr_items 2, total_items 2, cmd_set 1. Full stats / stats items / stats slabs are all defaults and available on request.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with proto_parser.c:593 to confirm how E is parsed, then inspect the existing-item flag loop in process_mget and the autovivify path using do_item_link. Reproduce the issue with the provided nc sequence against memcached, and verify that modifying foo with T90 E555 reports CAS 555 afterward, or that the documentation no longer advertises E for mg if that is the intended resolution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100