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 <sjust@redhat.com>
This commit is contained in:
Samuel Just 2016-11-08 12:22:06 -08:00
parent bcb5a0da21
commit 9499cdcd87

View File

@ -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);