From: Samuel Just Date: Tue, 8 Nov 2016 20:22:06 +0000 (-0800) Subject: FileStore::_do_copy_range: tolerate short reads on replay X-Git-Tag: v11.1.0~245^2~38 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=9499cdcd87ddac4a91abffe401baddb91f8a11d5;p=ceph-ci.git FileStore::_do_copy_range: tolerate short reads on replay Consider a sequence like: 0. foo object size is 15 1. clone_range foo -> foo.0 5~5 2. write foo 5~5 3. clone_range foo -> foo.1 10~5 4. write 10~5 foo 5. rename foo -> foo.1 6. remove foo.0 7. remove foo.1 8. remove foo.2 If this sequence is interupted after 8 and replayed from 1, by the time it gets to 3 the object will only have size 10 and no replay guard (since 1 was skipped and 2 recreated the object with size 10 resulting in a short read. This should only happen if the replay guard is missing, which should only happen if the object gets deleted later in the sequence. Signed-off-by: Samuel Just --- diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index 7ff064acf5d..d3f632192b5 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -3728,7 +3728,12 @@ int FileStore::_do_copy_range(int from, int to, uint64_t srcoff, uint64_t len, u } } - assert(pos == end); + if (r < 0 && replaying) { + assert(r == -ERANGE); + derr << "Filestore: short source tolerated because we are replaying" << dendl; + r = pos - from;; + } + assert(replaying || pos == end); if (r >= 0 && !skip_sloppycrc && m_filestore_sloppy_crc) { int rc = backend->_crc_update_clone_range(from, to, srcoff, len, dstoff); assert(rc >= 0);