From 861d2625b23b1cf299a6d135699f306ba2308b6a Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 18 Feb 2015 15:46:09 -0500 Subject: [PATCH] file_stream: proper seek support. Our file_stream interface supports seek, but when we try to seek to arbitrary locations that are smaller than an aio-boundary (say, for instance, f->seek(4)), we will end up not being able to perform the read. We need to guarantee the reads are aligned, and will then present to the caller the buffer properly offset. Signed-off-by: Glauber Costa --- core/fstream.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/fstream.cc b/core/fstream.cc index fe07627cc..e258884ab 100644 --- a/core/fstream.cc +++ b/core/fstream.cc @@ -17,10 +17,18 @@ file_data_source_impl::get() { auto q = static_cast(p); temporary_buffer buf(q, _buffer_size, make_free_deleter(p)); auto old_pos = _pos; - _pos += _buffer_size; + // dma_read needs to be aligned. It doesn't have to be page-aligned, + // though, and we could get away with something much smaller. However, if + // we start reading in things outside page boundaries, we will end up with + // various pages around, some of them with overlapping ranges. Those would + // be very challenging to cache. + old_pos &= ~4095; + auto front = _pos - old_pos; + _pos += _buffer_size - front; return _file.dma_read(old_pos, q, _buffer_size).then( - [buf = std::move(buf)] (size_t size) mutable { + [buf = std::move(buf), front] (size_t size) mutable { buf.trim(size); + buf.trim_front(front); return make_ready_future>(std::move(buf)); }); }