Seastar
High performance C++ framework for concurrent servers
file.hh
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright 2015 Cloudius Systems
20 */
21
22#pragma once
23
24#include <seastar/util/std-compat.hh>
25#include <seastar/core/coroutine.hh>
26#include <seastar/coroutine/generator.hh>
27#include <seastar/core/do_with.hh>
28#include <seastar/core/stream.hh>
29#include <seastar/core/sstring.hh>
30#include <seastar/core/shared_ptr.hh>
31#include <seastar/core/align.hh>
32#include <seastar/core/io_priority_class.hh>
33#include <seastar/core/file-types.hh>
34#include <seastar/core/circular_buffer.hh>
35#include <seastar/util/modules.hh>
36#ifndef SEASTAR_MODULE
37#include <sys/statvfs.h>
38#include <sys/ioctl.h>
39#include <linux/fs.h>
40#include <sys/uio.h>
41#include <unistd.h>
42#include <chrono>
43#include <concepts>
44#include <cstdint>
45#include <functional>
46#include <optional>
47#endif
48
49namespace seastar {
50
51SEASTAR_MODULE_EXPORT_BEGIN
52
55
59 sstring name;
61 std::optional<directory_entry_type> type;
62};
63
65struct stat_data {
66 uint64_t device_id; // ID of device containing file
67 uint64_t inode_number; // Inode number
68 uint64_t mode; // File type and mode
70 uint64_t number_of_links;// Number of hard links
71 uint64_t uid; // User ID of owner
72 uint64_t gid; // Group ID of owner
73 uint64_t rdev; // Device ID (if special file)
74 uint64_t size; // Total size, in bytes
75 uint64_t block_size; // Block size for filesystem I/O
76 uint64_t allocated_size; // Total size of allocated storage, in bytes
77
78 std::chrono::system_clock::time_point time_accessed; // Time of last content access
79 std::chrono::system_clock::time_point time_modified; // Time of last content modification
80 std::chrono::system_clock::time_point time_changed; // Time of last status change (either content or attributes)
81};
82
89 uint64_t extent_allocation_size_hint = 1 << 20;
90 bool sloppy_size = false;
91 uint64_t sloppy_size_hint = 1 << 20;
92 file_permissions create_permissions = file_permissions::default_file_permissions;
93 bool append_is_unlikely = false;
94
95 // The fsxattr.fsx_extsize is 32-bit
96 static constexpr uint64_t max_extent_allocation_size_hint = 1 << 31;
97
98 // XFS ignores hints that are not aligned to the logical block size.
99 // To fulfill the requirement, we ensure that hint is aligned to 128KB (best guess).
100 static constexpr uint32_t min_extent_size_hint_alignment{128u << 10}; // 128KB
101};
102
103class file;
104class file_impl;
105class io_intent;
106class file_handle;
107class file_data_sink_impl;
108class file_data_source_impl;
109
110// A handle that can be transported across shards and used to
111// create a dup(2)-like `file` object referring to the same underlying file
113public:
114 virtual ~file_handle_impl() = default;
115 virtual std::unique_ptr<file_handle_impl> clone() const = 0;
116 virtual shared_ptr<file_impl> to_file() && = 0;
117};
118
120 friend class file;
121protected:
122 static file_impl* get_file_impl(file& f);
123 unsigned _memory_dma_alignment = 4096;
124 unsigned _disk_read_dma_alignment = 4096;
125 unsigned _disk_write_dma_alignment = 4096;
126 unsigned _disk_overwrite_dma_alignment = 4096;
127 unsigned _read_max_length = 1u << 30;
128 unsigned _write_max_length = 1u << 30;
129public:
130 virtual ~file_impl() {}
131
132#if SEASTAR_API_LEVEL >= 7
133 virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, io_intent*) = 0;
134 virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, io_intent*) = 0;
135 virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, io_intent*) = 0;
136 virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, io_intent*) = 0;
137 virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, io_intent*) = 0;
138#else
139 virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, const io_priority_class& pc) = 0;
140 virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) = 0;
141 virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, const io_priority_class& pc) = 0;
142 virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) = 0;
143 virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc) = 0;
144
145 virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, const io_priority_class& pc, io_intent*) {
146 return write_dma(pos, buffer, len, pc);
147 }
148 virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent*) {
149 return write_dma(pos, std::move(iov), pc);
150 }
151 virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, const io_priority_class& pc, io_intent*) {
152 return read_dma(pos, buffer, len, pc);
153 }
154 virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent*) {
155 return read_dma(pos, std::move(iov), pc);
156 }
157 virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc, io_intent*) {
158 return dma_read_bulk(offset, range_size, pc);
159 }
160#endif
161
162 virtual future<> flush() = 0;
163 virtual future<struct stat> stat() = 0;
164 virtual future<> truncate(uint64_t length) = 0;
165 virtual future<> discard(uint64_t offset, uint64_t length) = 0;
166 virtual future<int> ioctl(uint64_t cmd, void* argp) noexcept;
167 virtual future<int> ioctl_short(uint64_t cmd, void* argp) noexcept;
168 virtual future<int> fcntl(int op, uintptr_t arg) noexcept;
169 virtual future<int> fcntl_short(int op, uintptr_t arg) noexcept;
170 virtual future<> allocate(uint64_t position, uint64_t length) = 0;
171 virtual future<uint64_t> size() = 0;
172 virtual future<> close() = 0;
173 virtual std::unique_ptr<file_handle_impl> dup();
174 virtual subscription<directory_entry> list_directory(std::function<future<> (directory_entry de)> next) = 0;
175 // due to https://github.com/scylladb/seastar/issues/1913, we cannot use
176 // buffered generator yet.
177 virtual coroutine::experimental::generator<directory_entry> experimental_list_directory();
178};
179
180future<shared_ptr<file_impl>> make_file_impl(int fd, file_open_options options, int oflags, struct stat st) noexcept;
181
183
193class file {
194 shared_ptr<file_impl> _file_impl;
195public:
206 file() noexcept : _file_impl(nullptr) {}
207
209 : _file_impl(std::move(impl)) {}
210
212 explicit file(file_handle&& handle) noexcept;
213
218 explicit operator bool() const noexcept { return bool(_file_impl); }
219
224 file(const file& x) = default;
226 file(file&& x) noexcept : _file_impl(std::move(x._file_impl)) {}
231 file& operator=(const file& x) noexcept = default;
233 file& operator=(file&& x) noexcept = default;
234
235 // O_DIRECT reading requires that buffer, offset, and read length, are
236 // all aligned. Alignment of 4096 was necessary in the past, but no longer
237 // is - 512 is usually enough; But we'll need to use BLKSSZGET ioctl to
238 // be sure it is really enough on this filesystem. 4096 is always safe.
239 // In addition, if we start reading in things outside page boundaries,
240 // we will end up with various pages around, some of them with
241 // overlapping ranges. Those would be very challenging to cache.
242
244 uint64_t disk_read_dma_alignment() const noexcept {
245 return _file_impl->_disk_read_dma_alignment;
246 }
247
249 uint64_t disk_write_dma_alignment() const noexcept {
250 return _file_impl->_disk_write_dma_alignment;
251 }
252
259 uint64_t disk_overwrite_dma_alignment() const noexcept {
260 return _file_impl->_disk_overwrite_dma_alignment;
261 }
262
264 uint64_t memory_dma_alignment() const noexcept {
265 return _file_impl->_memory_dma_alignment;
266 }
267
272 size_t disk_read_max_length() const noexcept {
273 return _file_impl->_read_max_length;
274 }
275
280 size_t disk_write_max_length() const noexcept {
281 return _file_impl->_write_max_length;
282 }
283
284#if SEASTAR_API_LEVEL < 7
302 template <typename CharType>
303 [[deprecated("Use scheduling_groups and API level >= 7")]]
305 dma_read(uint64_t aligned_pos, CharType* aligned_buffer, size_t aligned_len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
306 return dma_read_impl(aligned_pos, reinterpret_cast<uint8_t*>(aligned_buffer), aligned_len, internal::maybe_priority_class_ref(pc), intent);
307 }
308#endif
309
324 template <typename CharType>
325 future<size_t>
326 dma_read(uint64_t aligned_pos, CharType* aligned_buffer, size_t aligned_len, io_intent* intent = nullptr) noexcept {
327 return dma_read_impl(aligned_pos, reinterpret_cast<uint8_t*>(aligned_buffer), aligned_len, internal::maybe_priority_class_ref(), intent);
328 }
329
330#if SEASTAR_API_LEVEL < 7
349 template <typename CharType>
350 [[deprecated("Use scheduling_groups and API level >= 7")]]
351 future<temporary_buffer<CharType>> dma_read(uint64_t pos, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
352 return dma_read_impl(pos, len, internal::maybe_priority_class_ref(pc), intent).then([] (temporary_buffer<uint8_t> t) {
353 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
354 });
355 }
356#endif
357
373 template <typename CharType>
374 future<temporary_buffer<CharType>> dma_read(uint64_t pos, size_t len, io_intent* intent = nullptr) noexcept {
375 return dma_read_impl(pos, len, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
376 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
377 });
378 }
379
382 class eof_error : public std::exception {};
383
384#if SEASTAR_API_LEVEL < 7
400 template <typename CharType>
401 [[deprecated("Use scheduling_groups and API level >= 7")]]
403 dma_read_exactly(uint64_t pos, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
404 return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(pc), intent).then([] (temporary_buffer<uint8_t> t) {
405 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
406 });
407 }
408#endif
409
422 template <typename CharType>
423 future<temporary_buffer<CharType>>
424 dma_read_exactly(uint64_t pos, size_t len, io_intent* intent = nullptr) noexcept {
425 return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
426 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
427 });
428 }
429
430#if SEASTAR_API_LEVEL < 7
443 [[deprecated("Use scheduling_groups and API level >= 7")]]
444 future<size_t> dma_read(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
445 return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
446 }
447#endif
448
458 future<size_t> dma_read(uint64_t pos, std::vector<iovec> iov, io_intent* intent = nullptr) noexcept {
459 return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
460 }
461
462#if SEASTAR_API_LEVEL < 7
476 template <typename CharType>
477 [[deprecated("Use scheduling_groups and API level >= 7")]]
478 future<size_t> dma_write(uint64_t pos, const CharType* buffer, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
479 return dma_write_impl(pos, reinterpret_cast<const uint8_t*>(buffer), len, internal::maybe_priority_class_ref(pc), intent);
480 }
481#endif
482
493 template <typename CharType>
494 future<size_t> dma_write(uint64_t pos, const CharType* buffer, size_t len, io_intent* intent = nullptr) noexcept {
495 return dma_write_impl(pos, reinterpret_cast<const uint8_t*>(buffer), len, internal::maybe_priority_class_ref(), intent);
496 }
497
498#if SEASTAR_API_LEVEL < 7
511 [[deprecated("Use scheduling_groups and API level >= 7")]]
512 future<size_t> dma_write(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
513 return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
514 }
515#endif
516
526 future<size_t> dma_write(uint64_t pos, std::vector<iovec> iov, io_intent* intent = nullptr) noexcept {
527 return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
528 }
529
534 future<> flush() noexcept;
535
537 future<struct stat> stat() noexcept;
538
540 future<> truncate(uint64_t length) noexcept;
541
554 future<> allocate(uint64_t position, uint64_t length) noexcept;
555
560 future<> discard(uint64_t offset, uint64_t length) noexcept;
561
574 future<int> ioctl(uint64_t cmd, void* argp) noexcept;
575
590 future<int> ioctl_short(uint64_t cmd, void* argp) noexcept;
591
603 future<int> fcntl(int op, uintptr_t arg = 0UL) noexcept;
604
618 future<int> fcntl_short(int op, uintptr_t arg = 0UL) noexcept;
619
631 [[deprecated("This API was removed from the kernel")]]
632 future<> set_file_lifetime_hint(uint64_t hint) noexcept;
633
645 future<> set_inode_lifetime_hint(uint64_t hint) noexcept;
646
658 [[deprecated("This API was removed from the kernel")]]
659 future<uint64_t> get_file_lifetime_hint() noexcept;
660
672 future<uint64_t> get_inode_lifetime_hint() noexcept;
673
675 future<uint64_t> size() const noexcept;
676
687 future<> close() noexcept;
688
691
693 // due to https://github.com/scylladb/seastar/issues/1913, we cannot use
694 // buffered generator yet.
695 coroutine::experimental::generator<directory_entry> experimental_list_directory();
696
697#if SEASTAR_API_LEVEL < 7
715 template <typename CharType>
716 [[deprecated("Use scheduling_groups and API level >= 7")]]
718 dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
719 return dma_read_bulk_impl(offset, range_size, internal::maybe_priority_class_ref(pc), intent).then([] (temporary_buffer<uint8_t> t) {
720 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
721 });
722 }
723#endif
724
739 template <typename CharType>
741 dma_read_bulk(uint64_t offset, size_t range_size, io_intent* intent = nullptr) noexcept {
742 return dma_read_bulk_impl(offset, range_size, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
743 return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
744 });
745 }
746
756private:
758 dma_read_bulk_impl(uint64_t offset, size_t range_size, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
759
761 dma_write_impl(uint64_t pos, const uint8_t* buffer, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
762
764 dma_write_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
765
767 dma_read_impl(uint64_t pos, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
768
770 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;
771
773 dma_read_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
774
776 dma_read_exactly_impl(uint64_t pos, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
777
778 future<uint64_t> get_lifetime_hint_impl(int op) noexcept;
779 future<> set_lifetime_hint_impl(int op, uint64_t hint) noexcept;
780
781 friend class file_impl;
782 friend class file_data_sink_impl;
783 friend class file_data_source_impl;
784};
785
793template <std::invocable<file&> Func>
794requires std::is_nothrow_move_constructible_v<Func>
795auto with_file(future<file> file_fut, Func func) noexcept {
796 static_assert(std::is_nothrow_move_constructible_v<Func>, "Func's move constructor must not throw");
797 return file_fut.then([func = std::move(func)] (file f) mutable {
798 return do_with(std::move(f), [func = std::move(func)] (file& f) mutable {
799 return futurize_invoke(func, f).finally([&f] {
800 return f.close();
801 });
802 });
803 });
804}
805
820template <std::invocable<file&> Func>
821requires std::is_nothrow_move_constructible_v<Func>
822auto with_file_close_on_failure(future<file> file_fut, Func func) noexcept {
823 static_assert(std::is_nothrow_move_constructible_v<Func>, "Func's move constructor must not throw");
824 return file_fut.then([func = std::move(func)] (file f) mutable {
825 return do_with(std::move(f), [func = std::move(func)] (file& f) mutable {
826 return futurize_invoke(std::move(func), f).then_wrapped([&f] (auto ret) mutable {
827 if (!ret.failed()) {
828 return ret;
829 }
830 return ret.finally([&f] {
831 // If f.close() fails, return that as nested exception.
832 return f.close();
833 });
834 });
835 });
836 });
837}
838
842
851 std::unique_ptr<file_handle_impl> _impl;
852private:
853 explicit file_handle(std::unique_ptr<file_handle_impl> impl) : _impl(std::move(impl)) {}
854public:
860 file_handle& operator=(const file_handle&);
862 file_handle& operator=(file_handle&&) noexcept;
864 file to_file() const &;
867
868 friend class file;
869};
870
872
874class cancelled_error : public std::exception {
875public:
876 virtual const char* what() const noexcept {
877 return "cancelled";
878 }
879};
880
881SEASTAR_MODULE_EXPORT_END
882
883}
An exception Cancelled IOs resolve their future into (see io_intent)
Definition: file.hh:874
Definition: file.hh:382
Definition: file.hh:112
A shard-transportable handle to a file.
Definition: file.hh:850
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.
Definition: file.hh:119
Definition: file.hh:193
future close() noexcept
future< int > ioctl(uint64_t cmd, void *argp) noexcept
future< temporary_buffer< CharType > > dma_read(uint64_t pos, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:374
file & operator=(file &&x) noexcept=default
Moves assigns a file object.
future< temporary_buffer< CharType > > dma_read_bulk(uint64_t offset, size_t range_size, io_intent *intent=nullptr) noexcept
Definition: file.hh:741
subscription< directory_entry > list_directory(std::function< future<>(directory_entry de)> next)
Returns a directory listing, given that this file object is a directory.
file & operator=(const file &x) noexcept=default
future< size_t > dma_write(uint64_t pos, std::vector< iovec > iov, io_intent *intent=nullptr) noexcept
Definition: file.hh:526
future allocate(uint64_t position, uint64_t length) noexcept
future set_inode_lifetime_hint(uint64_t hint) noexcept
uint64_t memory_dma_alignment() const noexcept
Alignment requirement for data buffers.
Definition: file.hh:264
file(file_handle &&handle) noexcept
Constructs a file object from a file_handle obtained from another shard.
future< size_t > dma_write(uint64_t pos, const CharType *buffer, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:494
future< int > fcntl_short(int op, uintptr_t arg=0UL) noexcept
size_t disk_read_max_length() const noexcept
Definition: file.hh:272
future< size_t > dma_read(uint64_t pos, std::vector< iovec > iov, io_intent *intent=nullptr) noexcept
Definition: file.hh:458
future set_file_lifetime_hint(uint64_t hint) noexcept
future flush() noexcept
file_handle dup()
Creates a handle that can be transported across shards.
future< uint64_t > get_inode_lifetime_hint() noexcept
file(file &&x) noexcept
Moves a file object.
Definition: file.hh:226
uint64_t disk_read_dma_alignment() const noexcept
Alignment requirement for file offsets (for reads)
Definition: file.hh:244
future< uint64_t > size() const noexcept
Gets the file size.
future discard(uint64_t offset, uint64_t length) noexcept
future< struct stat > stat() noexcept
Returns stat information about the file.
uint64_t disk_overwrite_dma_alignment() const noexcept
Definition: file.hh:259
future< size_t > dma_read(uint64_t aligned_pos, CharType *aligned_buffer, size_t aligned_len, io_intent *intent=nullptr) noexcept
Definition: file.hh:326
future truncate(uint64_t length) noexcept
Truncates the file to a specified length.
future< int > ioctl_short(uint64_t cmd, void *argp) noexcept
coroutine::experimental::generator< directory_entry > experimental_list_directory()
Returns a directory listing, given that this file object is a directory.
size_t disk_write_max_length() const noexcept
Definition: file.hh:280
uint64_t disk_write_dma_alignment() const noexcept
Alignment requirement for file offsets (for writes)
Definition: file.hh:249
future< int > fcntl(int op, uintptr_t arg=0UL) noexcept
future< uint64_t > get_file_lifetime_hint() noexcept
file() noexcept
Definition: file.hh:206
file(const file &x)=default
future< temporary_buffer< CharType > > dma_read_exactly(uint64_t pos, size_t len, io_intent *intent=nullptr) noexcept
Definition: file.hh:424
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
Definition: io_intent.hh:44
Definition: shared_ptr.hh:513
Definition: stream.hh:127
Definition: temporary_buffer.hh:67
deleter release() noexcept
Definition: temporary_buffer.hh:203
size_t size() const noexcept
Gets the buffer size.
Definition: temporary_buffer.hh:130
CharType * get_write() noexcept
Definition: temporary_buffer.hh:128
std::optional< directory_entry_type > type
Type of the directory entry, if known.
Definition: file.hh:61
sstring name
Name of the file in a directory entry. Will never be "." or "..". Only the last component is included...
Definition: file.hh:59
directory_entry_type
Definition: file-types.hh:70
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:822
auto with_file(future< file > file_fut, Func func) noexcept
Helper for ensuring a file is closed after func is called.
Definition: file.hh:795
A directory entry being listed.
Definition: file.hh:57
Filesystem object stat information.
Definition: file.hh:65
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
STL namespace.
Definition: file.hh:88
bool sloppy_size
Allow the file size not to track the amount of data written until a flush.
Definition: file.hh:90
uint64_t sloppy_size_hint
Hint as to what the eventual file size will be.
Definition: file.hh:91
bool append_is_unlikely
Hint that user promises (or at least tries hard) not to write behind file size.
Definition: file.hh:93
file_permissions create_permissions
File permissions to use when creating a file.
Definition: file.hh:92
uint64_t extent_allocation_size_hint
Allocate this much disk space when extending the file.
Definition: file.hh:89