Often a single file is used in multiple fibers, and so it is wrapped in a
lw_shared_ptr. Remove the need for this by making files internally reference
counted.
file_data_source_impl always calls file::size(), which can be slow. This
slows down applications that create many short-lived input streams on the
same file (for random-access processing of a subset of the data).
Fix by not calling size(), and letting the file code handle short reads
itself.
Closing a file can both expose latent errors that did not have the
opportunity to be reported earlier, and also may block. While both
are unlikely in the case of O_DIRECT files, better not to risk it.
When creating a file object, we call fstat() to determine whether it's
a block device or a regular file. While unlikely, the fstat() call can
block. Use an ioctl() that we expect to fail on regular files instead.
Make read_maybe_eof() return zero-sized buffer when pos is at or beyond
EOF. This will prevent an internal exception throwing inside "file" class
in cases when dma_read_bulk() is going to succeed and return read data, e.g. when
it was called with "offset" less than file size but "offset" + "range_size"
beyond EOF.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
Move read_state helper class, file::dma_read_bulk() and file::read_maybe_eof()
definitions outside the class declaration in order to make reading the class
interface easier.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
Move the get() logic in fstream.cc into the file::dma_read_bulk()
fixing some issues:
- Fix the funny "alignment" calculation.
- Make sure the length is aligned too.
- Added new functions:
- dma_read(pos, len): returns a temporary_buffer with read data and
doesn't assume/require any alignment from either "pos"
or "len". Unlike dma_read_bulk() this function will
trim the resulting buffer to the requested size.
- dma_read_exactly(pos, len): does exactly what dma_read(pos, len) does but it
will also throw and exception if it failed to read
the required number of bytes (e.g. EOF is reached).
- Changed the names of parameters of dma_read(pos, buf, len) in order to emphasize
that they have to be aligned.
- Added a description to dma_read(pos, buf, len) to make it even more clear.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
I am currently unable to use core/file.hh in a fresh include file. Type
conflicts arise, which probably don't happen in other existing files because
of existing includes that end up getting the environment all right beforehand.
FAILED: g++ -MMD -MT build/release/db/db.o -MF build/release/db/db.o.d -std=gnu++1y -g -Wall -Werror -fvisibility=hidden -pthread -I. -DHAVE_XEN -DHAVE_HWLOC -DHAVE_NUMA -O2 -I build/release/gen -c -o build/release/db/db.o db/db.cc
In file included from ./sstables.hh:4:0,
from ./database.hh:22,
from db/composites/composite.hh:27,
from db/db.cc:8:
./core/file.hh:35:64: error: ‘iovec’ was not declared in this scope
virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov) = 0;
Adding <sys/uio.h> to the include list of file.hh makes it includable (apparently) anywhere.
Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
open_directory() is similar to open_file_dma() with just the O_ flags adjusted.
list_directory() returns a subscription(), so that both the producer and
the consumer can be asynchronous.