]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
FileStore::_do_copy_range: tolerate short reads on replay
authorSamuel Just <sjust@redhat.com>
Tue, 8 Nov 2016 20:22:06 +0000 (12:22 -0800)
committerSamuel Just <sjust@redhat.com>
Thu, 17 Nov 2016 18:40:16 +0000 (10:40 -0800)
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>
src/os/filestore/FileStore.cc

index 7ff064acf5d55fbe32187dd362bb34f016819ae4..d3f632192b5b0bf8de19cf5affac1f71fd863e73 100644 (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);