mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-22 17:40:34 +00:00
core: add support for file classes
Intended to allow different file classes to implement their own file operations; currently supporting regular and block device files. This support would also be required for a native file system, for example. Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
This commit is contained in:
committed by
Avi Kivity
parent
a85baa4e8f
commit
f3e429bc43
@@ -160,9 +160,9 @@ void reactor::process_io(size_t count)
|
||||
}
|
||||
|
||||
future<size_t>
|
||||
reactor::write_dma(file& f, uint64_t pos, const void* buffer, size_t len) {
|
||||
return submit_io([&f, pos, buffer, len] (iocb& io) {
|
||||
io_prep_pwrite(&io, f._fd, const_cast<void*>(buffer), len, pos);
|
||||
posix_file_impl::write_dma(uint64_t pos, const void* buffer, size_t len) {
|
||||
return engine.submit_io([this, pos, buffer, len] (iocb& io) {
|
||||
io_prep_pwrite(&io, _fd, const_cast<void*>(buffer), len, pos);
|
||||
}).then([] (io_event ev) {
|
||||
throw_kernel_error(long(ev.res));
|
||||
return make_ready_future<size_t>(size_t(ev.res));
|
||||
@@ -170,9 +170,9 @@ reactor::write_dma(file& f, uint64_t pos, const void* buffer, size_t len) {
|
||||
}
|
||||
|
||||
future<size_t>
|
||||
reactor::write_dma(file& f, uint64_t pos, std::vector<iovec> iov) {
|
||||
return submit_io([&f, pos, iov = std::move(iov)] (iocb& io) {
|
||||
io_prep_pwritev(&io, f._fd, iov.data(), iov.size(), pos);
|
||||
posix_file_impl::write_dma(uint64_t pos, std::vector<iovec> iov) {
|
||||
return engine.submit_io([this, pos, iov = std::move(iov)] (iocb& io) {
|
||||
io_prep_pwritev(&io, _fd, iov.data(), iov.size(), pos);
|
||||
}).then([] (io_event ev) {
|
||||
throw_kernel_error(long(ev.res));
|
||||
return make_ready_future<size_t>(size_t(ev.res));
|
||||
@@ -180,9 +180,9 @@ reactor::write_dma(file& f, uint64_t pos, std::vector<iovec> iov) {
|
||||
}
|
||||
|
||||
future<size_t>
|
||||
reactor::read_dma(file& f, uint64_t pos, void* buffer, size_t len) {
|
||||
return submit_io([&f, pos, buffer, len] (iocb& io) {
|
||||
io_prep_pread(&io, f._fd, buffer, len, pos);
|
||||
posix_file_impl::read_dma(uint64_t pos, void* buffer, size_t len) {
|
||||
return engine.submit_io([this, pos, buffer, len] (iocb& io) {
|
||||
io_prep_pread(&io, _fd, buffer, len, pos);
|
||||
}).then([] (io_event ev) {
|
||||
throw_kernel_error(long(ev.res));
|
||||
return make_ready_future<size_t>(size_t(ev.res));
|
||||
@@ -190,9 +190,9 @@ reactor::read_dma(file& f, uint64_t pos, void* buffer, size_t len) {
|
||||
}
|
||||
|
||||
future<size_t>
|
||||
reactor::read_dma(file& f, uint64_t pos, std::vector<iovec> iov) {
|
||||
return submit_io([&f, pos, iov = std::move(iov)] (iocb& io) {
|
||||
io_prep_preadv(&io, f._fd, iov.data(), iov.size(), pos);
|
||||
posix_file_impl::read_dma(uint64_t pos, std::vector<iovec> iov) {
|
||||
return engine.submit_io([this, pos, iov = std::move(iov)] (iocb& io) {
|
||||
io_prep_preadv(&io, _fd, iov.data(), iov.size(), pos);
|
||||
}).then([] (io_event ev) {
|
||||
throw_kernel_error(long(ev.res));
|
||||
return make_ready_future<size_t>(size_t(ev.res));
|
||||
@@ -210,9 +210,9 @@ reactor::open_file_dma(sstring name) {
|
||||
}
|
||||
|
||||
future<>
|
||||
reactor::flush(file& f) {
|
||||
return _thread_pool.submit<syscall_result<int>>([&f] {
|
||||
return wrap_syscall<int>(::fsync(f._fd));
|
||||
posix_file_impl::flush(void) {
|
||||
return engine._thread_pool.submit<syscall_result<int>>([this] {
|
||||
return wrap_syscall<int>(::fsync(_fd));
|
||||
}).then([] (syscall_result<int> sr) {
|
||||
sr.throw_if_error();
|
||||
return make_ready_future<>();
|
||||
@@ -220,10 +220,10 @@ reactor::flush(file& f) {
|
||||
}
|
||||
|
||||
future<struct stat>
|
||||
reactor::stat(file& f) {
|
||||
return _thread_pool.submit<struct stat>([&f] {
|
||||
posix_file_impl::stat(void) {
|
||||
return engine._thread_pool.submit<struct stat>([this] {
|
||||
struct stat st;
|
||||
auto ret = ::fstat(f._fd, &st);
|
||||
auto ret = ::fstat(_fd, &st);
|
||||
throw_system_error_on(ret == -1);
|
||||
return (st);
|
||||
});
|
||||
|
||||
@@ -427,8 +427,9 @@ public:
|
||||
future<size_t> write_all(pollable_fd_state& fd, const void* buffer, size_t size);
|
||||
|
||||
future<file> open_file_dma(sstring name);
|
||||
future<> flush(file& f);
|
||||
future<struct stat> stat(file& f);
|
||||
|
||||
template <typename Func>
|
||||
future<io_event> submit_io(Func prepare_io);
|
||||
|
||||
int run();
|
||||
void exit(int ret);
|
||||
@@ -441,14 +442,6 @@ public:
|
||||
private:
|
||||
future<size_t> write_all_part(pollable_fd_state& fd, const void* buffer, size_t size, size_t completed);
|
||||
|
||||
future<size_t> read_dma(file& f, uint64_t pos, void* buffer, size_t len);
|
||||
future<size_t> read_dma(file& f, uint64_t pos, std::vector<iovec> iov);
|
||||
future<size_t> write_dma(file& f, uint64_t pos, const void* buffer, size_t len);
|
||||
future<size_t> write_dma(file& f, uint64_t pos, std::vector<iovec> iov);
|
||||
|
||||
template <typename Func>
|
||||
future<io_event> submit_io(Func prepare_io);
|
||||
|
||||
void process_io(size_t count);
|
||||
|
||||
void add_timer(timer* tmr);
|
||||
@@ -580,41 +573,85 @@ public:
|
||||
private:
|
||||
};
|
||||
|
||||
class file {
|
||||
int _fd;
|
||||
private:
|
||||
explicit file(int fd) : _fd(fd) {}
|
||||
class file_impl {
|
||||
public:
|
||||
~file() {
|
||||
virtual ~file_impl() {}
|
||||
|
||||
virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len) = 0;
|
||||
virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov) = 0;
|
||||
virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len) = 0;
|
||||
virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov) = 0;
|
||||
virtual future<> flush(void) = 0;
|
||||
virtual future<struct stat> stat(void) = 0;
|
||||
|
||||
friend class reactor;
|
||||
};
|
||||
|
||||
class posix_file_impl : public file_impl {
|
||||
public:
|
||||
int _fd;
|
||||
posix_file_impl(int fd) : _fd(fd) {}
|
||||
~posix_file_impl() {
|
||||
if (_fd != -1) {
|
||||
::close(_fd);
|
||||
}
|
||||
}
|
||||
file(file&& x) : _fd(x._fd) { x._fd = -1; }
|
||||
|
||||
future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len);
|
||||
future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov);
|
||||
future<size_t> read_dma(uint64_t pos, void* buffer, size_t len);
|
||||
future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov);
|
||||
future<> flush(void);
|
||||
future<struct stat> stat(void);
|
||||
};
|
||||
|
||||
class blockdev_file_impl : public posix_file_impl {
|
||||
public:
|
||||
blockdev_file_impl(int fd) : posix_file_impl(fd) {}
|
||||
};
|
||||
|
||||
inline
|
||||
std::unique_ptr<file_impl>
|
||||
make_file_impl(int fd) {
|
||||
struct stat st;
|
||||
::fstat(fd, &st);
|
||||
if (S_ISBLK(st.st_mode)) {
|
||||
return std::unique_ptr<file_impl>(new blockdev_file_impl(fd));
|
||||
} else {
|
||||
return std::unique_ptr<file_impl>(new posix_file_impl(fd));
|
||||
}
|
||||
}
|
||||
|
||||
class file {
|
||||
std::unique_ptr<file_impl> _file_impl;
|
||||
private:
|
||||
explicit file(int fd) : _file_impl(make_file_impl(fd)) {}
|
||||
public:
|
||||
file(file&& x) : _file_impl(std::move(x._file_impl)) {}
|
||||
template <typename CharType>
|
||||
future<size_t> dma_read(uint64_t pos, CharType* buffer, size_t len) {
|
||||
return engine.read_dma(*this, pos, buffer, len);
|
||||
return _file_impl->read_dma(pos, buffer, len);
|
||||
}
|
||||
|
||||
future<size_t> dma_read(uint64_t pos, std::vector<iovec> iov) {
|
||||
return engine.read_dma(*this, pos, std::move(iov));
|
||||
return _file_impl->read_dma(pos, std::move(iov));
|
||||
}
|
||||
|
||||
template <typename CharType>
|
||||
future<size_t> dma_write(uint64_t pos, const CharType* buffer, size_t len) {
|
||||
return engine.write_dma(*this, pos, buffer, len);
|
||||
return _file_impl->write_dma(pos, buffer, len);
|
||||
}
|
||||
|
||||
future<size_t> dma_write(uint64_t pos, std::vector<iovec> iov) {
|
||||
return engine.write_dma(*this, pos, std::move(iov));
|
||||
return _file_impl->write_dma(pos, std::move(iov));
|
||||
}
|
||||
|
||||
future<> flush() {
|
||||
return engine.flush(*this);
|
||||
return _file_impl->flush();
|
||||
}
|
||||
|
||||
future<struct stat> stat() {
|
||||
return engine.stat(*this);
|
||||
return _file_impl->stat();
|
||||
}
|
||||
|
||||
friend class reactor;
|
||||
|
||||
Reference in New Issue
Block a user