]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: fix fallback clone_range implementation on short files
authorSage Weil <sage@newdream.net>
Wed, 28 Jul 2010 21:57:11 +0000 (14:57 -0700)
committerSage Weil <sage@newdream.net>
Wed, 28 Jul 2010 21:57:11 +0000 (14:57 -0700)
If we read less data from the source, don't loop forever... return -ERANGE
instead.

src/os/FileStore.cc

index cb88b36ae91a0d7c94dccb0f414e91579f7f6971..f76e84856efb553a8c391e0888e0a9bc5b5469dc 100644 (file)
@@ -1516,19 +1516,32 @@ int FileStore::_do_clone_range(int from, int to, uint64_t off, uint64_t len)
   while (pos < end) {
     int l = MIN(end-pos, buflen);
     r = ::read(from, buf, l);
+    dout(25) << "  read from " << from << "~" << l << " got " << r << dendl;
     if (r < 0)
       break;
+    if (r == 0) {
+      // hrm, bad source range, wtf.
+      dout(0) << "_do_clone_range got short read result at " << from << " of " << from << "~" << len << dendl;
+      r = -ERANGE;
+      break;
+    }
     int op = 0;
-    while (op < l) {
-      int r2 = ::write(to, buf+op, l-op);
-      
-      if (r2 < 0) { r = r2; break; }
-      op += r2;          
+    while (op < r) {
+      int r2 = ::write(to, buf+op, r-op);
+      dout(25) << " write to " << to << "~" << (r-op) << " got " << r2 << dendl;      
+      if (r2 < 0) {
+       r = r2;
+       break;
+      }
+      op += r2;
     }
-    if (r < 0) break;
+    if (r < 0)
+      break;
     pos += r;
   }
-
+  if (r < 0)
+    r = -errno;
+  dout(20) << "_do_clone_range " << off << "~" << len << " = " << r << dendl;
   return r;
 }