diff options
author | dormando <dormando@rydia.net> | 2017-12-14 17:51:35 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2017-12-14 17:51:35 -0800 |
commit | c65a2fbb13bec94313ddf308468b59d8be5db5b0 (patch) | |
tree | bdae0fc9ebabde9552ac27d41a1b6f44d6be626a /storage.c | |
parent | bca66424e9f367a57a5bcf5a5707a4d4b33520fb (diff) | |
download | memcached-c65a2fbb13bec94313ddf308468b59d8be5db5b0.tar.gz |
extstore: fix crash while moving extstore chunks
ITEM_LINKED was still set on the objects being written to disk. If a page
being moved contains a chunk read from extstore currently being written back
to the client, it will mistake it for a chunk properly linked and attempt to
unlink if if the page has also been jammed in the mover.
So you need a cross section of a particular chunk being active the entire
time a page is jammed, then it tries to unlink it but the header is partially
garbage and it segfaults.
The page mover ignores all items which don't either have LINKED or SLABBED,
assuming they're in transition. So the fix is to simply remove the LINKED bit
after copying into the write buffer.
Diffstat (limited to 'storage.c')
-rw-r--r-- | storage.c | 1 |
1 files changed, 1 insertions, 0 deletions
@@ -96,6 +96,7 @@ int lru_maintainer_store(void *storage, const int clsid) { memcpy((char *)io.buf+32, (char *)it+32, io.len-32); } // crc what we copied so we can do it sequentially. + buf_it->it_flags &= ~ITEM_LINKED; buf_it->exptime = crc32c(0, (char*)io.buf+32, orig_ntotal-32); extstore_write(storage, &io); item_hdr *hdr = (item_hdr *) ITEM_data(hdr_it); |