summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-06-16 19:48:52 -0700
committerSage Weil <sage@inktank.com>2013-06-17 12:24:02 -0700
commitee40c217e373b538e227f7218b09c1c794b4124a (patch)
tree3efef87b811820bc88edc2c61932ecd2e3ecf0e9
parente3fb095d8aa88556e4356c76b848fa61b09acbc0 (diff)
downloadceph-ee40c217e373b538e227f7218b09c1c794b4124a.tar.gz
client: fix sync read zeroing at EOF
If we have a read that hits EOF, we need to do a short read. Previously we would zero the buffer if we were completely withing the file, but we also need to zero things if we overlap with EOF. This fixes a hang of mpi-fsx on ceph-fuse. Triggered/tested by LibCephFS.MulticlientHoleEOF. Fixes: #5368 Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/client/Client.cc14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 204dc98d74d..dec364567b6 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -5826,13 +5826,17 @@ int Client::_read_sync(Fh *f, uint64_t off, uint64_t len, bufferlist *bl)
}
// short read?
if (r >= 0 && r < wanted) {
- if (pos + left <= in->size) {
- // hole, zero and return.
- bufferptr z(left);
+ if (pos < in->size) {
+ // zero up to known EOF
+ int some = MIN(in->size - pos, left);
+ bufferptr z(some);
z.zero();
bl->push_back(z);
- read += left;
- return read;
+ read += some;
+ pos += some;
+ left -= some;
+ if (left == 0)
+ return read;
}
// reverify size