From: Sage Weil Date: Wed, 28 Jul 2010 21:57:11 +0000 (-0700) Subject: filestore: fix fallback clone_range implementation on short files X-Git-Tag: v0.21~16 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eb1f58743a4d183bd3a47c18a301b0d48c19f276;p=ceph.git filestore: fix fallback clone_range implementation on short files If we read less data from the source, don't loop forever... return -ERANGE instead. --- diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index cb88b36ae91a..f76e84856efb 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -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; }