24 #include <seastar/util/std-compat.hh>
25 #ifdef SEASTAR_COROUTINES_ENABLED
26 #include <seastar/core/coroutine.hh>
27 #include <seastar/coroutine/generator.hh>
29 #include <seastar/core/do_with.hh>
30 #include <seastar/core/stream.hh>
31 #include <seastar/core/sstring.hh>
32 #include <seastar/core/shared_ptr.hh>
33 #include <seastar/core/align.hh>
34 #include <seastar/core/io_priority_class.hh>
35 #include <seastar/core/file-types.hh>
36 #include <seastar/core/circular_buffer.hh>
37 #include <seastar/util/modules.hh>
38 #ifndef SEASTAR_MODULE
39 #include <system_error>
40 #include <sys/statvfs.h>
41 #include <sys/ioctl.h>
54 SEASTAR_MODULE_EXPORT_BEGIN
64 std::optional<directory_entry_type>
type;
70 uint64_t inode_number;
73 uint64_t number_of_links;
79 uint64_t allocated_size;
81 std::chrono::system_clock::time_point time_accessed;
82 std::chrono::system_clock::time_point time_modified;
83 std::chrono::system_clock::time_point time_changed;
99 static constexpr uint64_t max_extent_allocation_size_hint = 1 << 31;
106 class file_data_sink_impl;
107 class file_data_source_impl;
114 virtual std::unique_ptr<file_handle_impl> clone()
const = 0;
122 unsigned _memory_dma_alignment = 4096;
123 unsigned _disk_read_dma_alignment = 4096;
124 unsigned _disk_write_dma_alignment = 4096;
125 unsigned _disk_overwrite_dma_alignment = 4096;
126 unsigned _read_max_length = 1u << 30;
127 unsigned _write_max_length = 1u << 30;
131 #if SEASTAR_API_LEVEL >= 7
138 virtual future<size_t> write_dma(uint64_t pos,
const void* buffer,
size_t len,
const io_priority_class& pc) = 0;
139 virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov,
const io_priority_class& pc) = 0;
140 virtual future<size_t> read_dma(uint64_t pos,
void* buffer,
size_t len,
const io_priority_class& pc) = 0;
141 virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov,
const io_priority_class& pc) = 0;
144 virtual future<size_t> write_dma(uint64_t pos,
const void* buffer,
size_t len,
const io_priority_class& pc,
io_intent*) {
145 return write_dma(pos, buffer, len, pc);
147 virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov,
const io_priority_class& pc,
io_intent*) {
148 return write_dma(pos, std::move(iov), pc);
150 virtual future<size_t> read_dma(uint64_t pos,
void* buffer,
size_t len,
const io_priority_class& pc,
io_intent*) {
151 return read_dma(pos, buffer, len, pc);
153 virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov,
const io_priority_class& pc,
io_intent*) {
154 return read_dma(pos, std::move(iov), pc);
157 return dma_read_bulk(offset, range_size, pc);
163 virtual future<> truncate(uint64_t length) = 0;
164 virtual future<> discard(uint64_t offset, uint64_t length) = 0;
165 virtual future<int> ioctl(uint64_t cmd,
void* argp) noexcept;
166 virtual future<int> ioctl_short(uint64_t cmd,
void* argp) noexcept;
167 virtual future<int> fcntl(
int op, uintptr_t arg) noexcept;
168 virtual future<int> fcntl_short(
int op, uintptr_t arg) noexcept;
169 virtual future<> allocate(uint64_t position, uint64_t length) = 0;
172 virtual std::unique_ptr<file_handle_impl> dup();
174 #ifdef SEASTAR_COROUTINES_ENABLED
207 file() noexcept : _file_impl(
nullptr) {}
210 : _file_impl(std::move(
impl)) {}
219 explicit operator bool() const noexcept {
return bool(_file_impl); }
227 file(
file&& x) noexcept : _file_impl(std::move(x._file_impl)) {}
246 return _file_impl->_disk_read_dma_alignment;
251 return _file_impl->_disk_write_dma_alignment;
261 return _file_impl->_disk_overwrite_dma_alignment;
266 return _file_impl->_memory_dma_alignment;
274 return _file_impl->_read_max_length;
282 return _file_impl->_write_max_length;
285 #if SEASTAR_API_LEVEL < 7
303 template <
typename CharType>
304 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
306 dma_read(uint64_t aligned_pos, CharType* aligned_buffer,
size_t aligned_len,
const io_priority_class& pc,
io_intent* intent =
nullptr) noexcept {
307 return dma_read_impl(aligned_pos,
reinterpret_cast<uint8_t*
>(aligned_buffer), aligned_len, internal::maybe_priority_class_ref(pc), intent);
325 template <
typename CharType>
327 dma_read(uint64_t aligned_pos, CharType* aligned_buffer,
size_t aligned_len,
io_intent* intent =
nullptr) noexcept {
328 return dma_read_impl(aligned_pos,
reinterpret_cast<uint8_t*
>(aligned_buffer), aligned_len, internal::maybe_priority_class_ref(), intent);
331 #if SEASTAR_API_LEVEL < 7
350 template <
typename CharType>
351 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
374 template <
typename CharType>
385 #if SEASTAR_API_LEVEL < 7
401 template <
typename CharType>
402 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
405 return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(pc), intent).then([] (
temporary_buffer<uint8_t> t) {
423 template <
typename CharType>
424 future<temporary_buffer<CharType>>
426 return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(), intent).then([] (
temporary_buffer<uint8_t> t) {
431 #if SEASTAR_API_LEVEL < 7
444 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
446 return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
460 return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
463 #if SEASTAR_API_LEVEL < 7
477 template <
typename CharType>
478 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
480 return dma_write_impl(pos,
reinterpret_cast<const uint8_t*
>(buffer), len, internal::maybe_priority_class_ref(pc), intent);
494 template <
typename CharType>
496 return dma_write_impl(pos,
reinterpret_cast<const uint8_t*
>(buffer), len, internal::maybe_priority_class_ref(), intent);
499 #if SEASTAR_API_LEVEL < 7
512 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
514 return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
528 return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
632 [[deprecated("This API was removed from the kernel")]]
659 [[deprecated("This API was removed from the kernel")]]
692 #ifdef SEASTAR_COROUTINES_ENABLED
699 #if SEASTAR_API_LEVEL < 7
717 template <
typename CharType>
718 [[deprecated(
"Use scheduling_groups and API level >= 7")]]
720 dma_read_bulk(uint64_t offset,
size_t range_size,
const io_priority_class& pc,
io_intent* intent =
nullptr) noexcept {
721 return dma_read_bulk_impl(offset, range_size, internal::maybe_priority_class_ref(pc), intent).then([] (
temporary_buffer<uint8_t> t) {
741 template <
typename CharType>
742 future<temporary_buffer<CharType>>
744 return dma_read_bulk_impl(offset, range_size, internal::maybe_priority_class_ref(), intent).then([] (
temporary_buffer<uint8_t> t) {
760 dma_read_bulk_impl(uint64_t offset,
size_t range_size, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
763 dma_write_impl(uint64_t pos,
const uint8_t* buffer,
size_t len, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
766 dma_write_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
769 dma_read_impl(uint64_t pos,
size_t len, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
772 dma_read_impl(uint64_t aligned_pos, uint8_t* aligned_buffer,
size_t aligned_len, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
775 dma_read_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
778 dma_read_exactly_impl(uint64_t pos,
size_t len, internal::maybe_priority_class_ref pc,
io_intent* intent) noexcept;
781 future<> set_lifetime_hint_impl(
int op, uint64_t hint) noexcept;
785 friend class file_data_sink_impl;
786 friend class file_data_source_impl;
796 template <
typename Func>
797 SEASTAR_CONCEPT( requires std::invocable<Func, file&> && std::is_nothrow_move_constructible_v<Func> )
799 static_assert(std::is_nothrow_move_constructible_v<Func>,
"Func's move constructor must not throw");
800 return file_fut.then([func = std::move(func)] (
file f)
mutable {
801 return do_with(std::move(f), [func = std::move(func)] (
file& f)
mutable {
802 return futurize_invoke(func, f).finally([&f] {
823 template <
typename Func>
824 SEASTAR_CONCEPT( requires std::invocable<Func, file&> && std::is_nothrow_move_constructible_v<Func> )
826 static_assert(std::is_nothrow_move_constructible_v<Func>,
"Func's move constructor must not throw");
827 return file_fut.then([func = std::move(func)] (
file f)
mutable {
828 return do_with(std::move(f), [func = std::move(func)] (
file& f)
mutable {
829 return futurize_invoke(std::move(func), f).then_wrapped([&f] (
auto ret)
mutable {
833 return ret.finally([&f] {
854 std::unique_ptr<file_handle_impl> _impl;
879 virtual const char* what()
const noexcept {
884 SEASTAR_MODULE_EXPORT_END
An exception Cancelled IOs resolve their future into (see io_intent)
Definition: file.hh:877
Definition: generator.hh:33
A shard-transportable handle to a file.
Definition: file.hh:853
file_handle(file_handle &&) noexcept
Moves a file handle object.
file_handle(const file_handle &)
Copies a file handle object.
file to_file() const &
Converts the file handle object to a file.
subscription< directory_entry > list_directory(std::function< future<>(directory_entry de)> next)
Returns a directory listing, given that this file object is a directory.
future< size_t > dma_read(uint64_t pos, std::vector< iovec > iov, io_intent *intent=nullptr) noexcept
Definition: file.hh:459
future< size_t > dma_write(uint64_t pos, const CharType *buffer, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:495
file & operator=(const file &x) noexcept=default
future< int > fcntl_short(int op, uintptr_t arg=0UL) noexcept
future< size_t > dma_write(uint64_t pos, std::vector< iovec > iov, io_intent *intent=nullptr) noexcept
Definition: file.hh:527
future allocate(uint64_t position, uint64_t length) noexcept
future set_inode_lifetime_hint(uint64_t hint) noexcept
future< uint64_t > get_inode_lifetime_hint() noexcept
uint64_t memory_dma_alignment() const noexcept
Alignment requirement for data buffers.
Definition: file.hh:265
file(file_handle &&handle) noexcept
Constructs a file object from a file_handle obtained from another shard.
size_t disk_read_max_length() const noexcept
Definition: file.hh:273
future< size_t > dma_read(uint64_t aligned_pos, CharType *aligned_buffer, size_t aligned_len, io_intent *intent=nullptr) noexcept
Definition: file.hh:327
future< int > fcntl(int op, uintptr_t arg=0UL) noexcept
future< int > ioctl(uint64_t cmd, void *argp) noexcept
future set_file_lifetime_hint(uint64_t hint) noexcept
file_handle dup()
Creates a handle that can be transported across shards.
file(file &&x) noexcept
Moves a file object.
Definition: file.hh:227
uint64_t disk_read_dma_alignment() const noexcept
Alignment requirement for file offsets (for reads)
Definition: file.hh:245
future< temporary_buffer< CharType > > dma_read_exactly(uint64_t pos, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:425
future discard(uint64_t offset, uint64_t length) noexcept
uint64_t disk_overwrite_dma_alignment() const noexcept
Definition: file.hh:260
future< temporary_buffer< CharType > > dma_read(uint64_t pos, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:375
future truncate(uint64_t length) noexcept
Truncates the file to a specified length.
future< temporary_buffer< CharType > > dma_read_bulk(uint64_t offset, size_t range_size, io_intent *intent=nullptr) noexcept
Definition: file.hh:743
size_t disk_write_max_length() const noexcept
Definition: file.hh:281
uint64_t disk_write_dma_alignment() const noexcept
Alignment requirement for file offsets (for writes)
Definition: file.hh:250
future< struct stat > stat() noexcept
Returns stat information about the file.
future< uint64_t > size() const noexcept
Gets the file size.
future< int > ioctl_short(uint64_t cmd, void *argp) noexcept
file & operator=(file &&x) noexcept=default
Moves assigns a file object.
future< uint64_t > get_file_lifetime_hint() noexcept
file() noexcept
Definition: file.hh:207
file(const file &x)=default
A representation of a possibly not-yet-computed value.
Definition: future.hh:1238
Definition: io_intent.hh:44
Definition: reactor.hh:168
Definition: shared_ptr.hh:515
Definition: stream.hh:128
Definition: temporary_buffer.hh:67
deleter release() noexcept
Definition: temporary_buffer.hh:203
CharType * get_write() noexcept
Definition: temporary_buffer.hh:128
size_t size() const noexcept
Gets the buffer size.
Definition: temporary_buffer.hh:130
std::optional< directory_entry_type > type
Type of the directory entry, if known.
Definition: file.hh:64
sstring name
Name of the file in a directory entry. Will never be "." or "..". Only the last component is included...
Definition: file.hh:62
directory_entry_type
Definition: file-types.hh:70
auto with_file(future< file > file_fut, Func func) noexcept
Helper for ensuring a file is closed after func is called.
Definition: file.hh:798
auto with_file_close_on_failure(future< file > file_fut, Func func) noexcept
Helper for ensuring a file is closed if func fails.
Definition: file.hh:825
A directory entry being listed.
Definition: file.hh:60
Filesystem object stat information.
Definition: file.hh:68
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
holds the implementation parts of the metrics layer, do not use directly.
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
bool sloppy_size
Allow the file size not to track the amount of data written until a flush.
Definition: file.hh:93
uint64_t sloppy_size_hint
Hint as to what the eventual file size will be.
Definition: file.hh:94
bool append_is_unlikely
Hint that user promises (or at least tries hard) not to write behind file size.
Definition: file.hh:96
file_permissions create_permissions
File permissions to use when creating a file.
Definition: file.hh:95
uint64_t extent_allocation_size_hint
Allocate this much disk space when extending the file.
Definition: file.hh:92