From 9499cdcd87ddac4a91abffe401baddb91f8a11d5 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Tue, 8 Nov 2016 12:22:06 -0800 Subject: [PATCH] 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 --- src/os/filestore/FileStore.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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); -- 2.39.5