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 <sjust@redhat.com>
}
}
- 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);