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 #ifdef SEASTAR_COROUTINES_ENABLED
26 #include <seastar/core/coroutine.hh>
27 #include <seastar/coroutine/generator.hh>
28 #endif
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>
42 #include <linux/fs.h>
43 #include <sys/uio.h>
44 #include <unistd.h>
45 #include <chrono>
46 #include <concepts>
47 #include <cstdint>
48 #include <functional>
49 #include <optional>
50 #endif
51 
52 namespace seastar {
53 
54 SEASTAR_MODULE_EXPORT_BEGIN
55 
58 
62  sstring name;
64  std::optional<directory_entry_type> type;
65 };
66 
68 struct stat_data {
69  uint64_t device_id; // ID of device containing file
70  uint64_t inode_number; // Inode number
71  uint64_t mode; // File type and mode
73  uint64_t number_of_links;// Number of hard links
74  uint64_t uid; // User ID of owner
75  uint64_t gid; // Group ID of owner
76  uint64_t rdev; // Device ID (if special file)
77  uint64_t size; // Total size, in bytes
78  uint64_t block_size; // Block size for filesystem I/O
79  uint64_t allocated_size; // Total size of allocated storage, in bytes
80 
81  std::chrono::system_clock::time_point time_accessed; // Time of last content access
82  std::chrono::system_clock::time_point time_modified; // Time of last content modification
83  std::chrono::system_clock::time_point time_changed; // Time of last status change (either content or attributes)
84 };
85 
92  uint64_t extent_allocation_size_hint = 1 << 20;
93  bool sloppy_size = false;
94  uint64_t sloppy_size_hint = 1 << 20;
95  file_permissions create_permissions = file_permissions::default_file_permissions;
96  bool append_is_unlikely = false;
97 
98  // The fsxattr.fsx_extsize is 32-bit
99  static constexpr uint64_t max_extent_allocation_size_hint = 1 << 31;
100 };
101 
102 class file;
103 class file_impl;
104 class io_intent;
105 class file_handle;
106 class file_data_sink_impl;
107 class file_data_source_impl;
108 
109 // A handle that can be transported across shards and used to
110 // create a dup(2)-like `file` object referring to the same underlying file
112 public:
113  virtual ~file_handle_impl() = default;
114  virtual std::unique_ptr<file_handle_impl> clone() const = 0;
115  virtual shared_ptr<file_impl> to_file() && = 0;
116 };
117 
118 class file_impl {
119  friend class file;
120 protected:
121  static file_impl* get_file_impl(file& f);
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;
128 public:
129  virtual ~file_impl() {}
130 
131 #if SEASTAR_API_LEVEL >= 7
132  virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, io_intent*) = 0;
133  virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, io_intent*) = 0;
134  virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, io_intent*) = 0;
135  virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, io_intent*) = 0;
136  virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, io_intent*) = 0;
137 #else
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;
142  virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc) = 0;
143 
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);
146  }
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);
149  }
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);
152  }
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);
155  }
156  virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc, io_intent*) {
157  return dma_read_bulk(offset, range_size, pc);
158  }
159 #endif
160 
161  virtual future<> flush() = 0;
162  virtual future<struct stat> stat() = 0;
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;
170  virtual future<uint64_t> size() = 0;
171  virtual future<> close() = 0;
172  virtual std::unique_ptr<file_handle_impl> dup();
173  virtual subscription<directory_entry> list_directory(std::function<future<> (directory_entry de)> next) = 0;
174 #ifdef SEASTAR_COROUTINES_ENABLED
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 #endif
179 };
180 
181 future<shared_ptr<file_impl>> make_file_impl(int fd, file_open_options options, int oflags, struct stat st) noexcept;
182 
184 
194 class file {
195  shared_ptr<file_impl> _file_impl;
196 public:
207  file() noexcept : _file_impl(nullptr) {}
208 
210  : _file_impl(std::move(impl)) {}
211 
213  explicit file(file_handle&& handle) noexcept;
214 
219  explicit operator bool() const noexcept { return bool(_file_impl); }
220 
225  file(const file& x) = default;
227  file(file&& x) noexcept : _file_impl(std::move(x._file_impl)) {}
232  file& operator=(const file& x) noexcept = default;
234  file& operator=(file&& x) noexcept = default;
235 
236  // O_DIRECT reading requires that buffer, offset, and read length, are
237  // all aligned. Alignment of 4096 was necessary in the past, but no longer
238  // is - 512 is usually enough; But we'll need to use BLKSSZGET ioctl to
239  // be sure it is really enough on this filesystem. 4096 is always safe.
240  // In addition, if we start reading in things outside page boundaries,
241  // we will end up with various pages around, some of them with
242  // overlapping ranges. Those would be very challenging to cache.
243 
245  uint64_t disk_read_dma_alignment() const noexcept {
246  return _file_impl->_disk_read_dma_alignment;
247  }
248 
250  uint64_t disk_write_dma_alignment() const noexcept {
251  return _file_impl->_disk_write_dma_alignment;
252  }
253 
260  uint64_t disk_overwrite_dma_alignment() const noexcept {
261  return _file_impl->_disk_overwrite_dma_alignment;
262  }
263 
265  uint64_t memory_dma_alignment() const noexcept {
266  return _file_impl->_memory_dma_alignment;
267  }
268 
273  size_t disk_read_max_length() const noexcept {
274  return _file_impl->_read_max_length;
275  }
276 
281  size_t disk_write_max_length() const noexcept {
282  return _file_impl->_write_max_length;
283  }
284 
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);
308  }
309 #endif
310 
325  template <typename CharType>
326  future<size_t>
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);
329  }
330 
331 #if SEASTAR_API_LEVEL < 7
350  template <typename CharType>
351  [[deprecated("Use scheduling_groups and API level >= 7")]]
352  future<temporary_buffer<CharType>> dma_read(uint64_t pos, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
353  return dma_read_impl(pos, len, internal::maybe_priority_class_ref(pc), intent).then([] (temporary_buffer<uint8_t> t) {
354  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
355  });
356  }
357 #endif
358 
374  template <typename CharType>
375  future<temporary_buffer<CharType>> dma_read(uint64_t pos, size_t len, io_intent* intent = nullptr) noexcept {
376  return dma_read_impl(pos, len, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
377  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
378  });
379  }
380 
383  class eof_error : public std::exception {};
384 
385 #if SEASTAR_API_LEVEL < 7
401  template <typename CharType>
402  [[deprecated("Use scheduling_groups and API level >= 7")]]
404  dma_read_exactly(uint64_t pos, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
405  return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(pc), intent).then([] (temporary_buffer<uint8_t> t) {
406  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
407  });
408  }
409 #endif
410 
423  template <typename CharType>
424  future<temporary_buffer<CharType>>
425  dma_read_exactly(uint64_t pos, size_t len, io_intent* intent = nullptr) noexcept {
426  return dma_read_exactly_impl(pos, len, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
427  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
428  });
429  }
430 
431 #if SEASTAR_API_LEVEL < 7
444  [[deprecated("Use scheduling_groups and API level >= 7")]]
445  future<size_t> dma_read(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
446  return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
447  }
448 #endif
449 
459  future<size_t> dma_read(uint64_t pos, std::vector<iovec> iov, io_intent* intent = nullptr) noexcept {
460  return dma_read_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
461  }
462 
463 #if SEASTAR_API_LEVEL < 7
477  template <typename CharType>
478  [[deprecated("Use scheduling_groups and API level >= 7")]]
479  future<size_t> dma_write(uint64_t pos, const CharType* buffer, size_t len, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
480  return dma_write_impl(pos, reinterpret_cast<const uint8_t*>(buffer), len, internal::maybe_priority_class_ref(pc), intent);
481  }
482 #endif
483 
494  template <typename CharType>
495  future<size_t> dma_write(uint64_t pos, const CharType* buffer, size_t len, io_intent* intent = nullptr) noexcept {
496  return dma_write_impl(pos, reinterpret_cast<const uint8_t*>(buffer), len, internal::maybe_priority_class_ref(), intent);
497  }
498 
499 #if SEASTAR_API_LEVEL < 7
512  [[deprecated("Use scheduling_groups and API level >= 7")]]
513  future<size_t> dma_write(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc, io_intent* intent = nullptr) noexcept {
514  return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(pc), intent);
515  }
516 #endif
517 
527  future<size_t> dma_write(uint64_t pos, std::vector<iovec> iov, io_intent* intent = nullptr) noexcept {
528  return dma_write_impl(pos, std::move(iov), internal::maybe_priority_class_ref(), intent);
529  }
530 
535  future<> flush() noexcept;
536 
538  future<struct stat> stat() noexcept;
539 
541  future<> truncate(uint64_t length) noexcept;
542 
555  future<> allocate(uint64_t position, uint64_t length) noexcept;
556 
561  future<> discard(uint64_t offset, uint64_t length) noexcept;
562 
575  future<int> ioctl(uint64_t cmd, void* argp) noexcept;
576 
591  future<int> ioctl_short(uint64_t cmd, void* argp) noexcept;
592 
604  future<int> fcntl(int op, uintptr_t arg = 0UL) noexcept;
605 
619  future<int> fcntl_short(int op, uintptr_t arg = 0UL) noexcept;
620 
632  [[deprecated("This API was removed from the kernel")]]
633  future<> set_file_lifetime_hint(uint64_t hint) noexcept;
634 
646  future<> set_inode_lifetime_hint(uint64_t hint) noexcept;
647 
659  [[deprecated("This API was removed from the kernel")]]
660  future<uint64_t> get_file_lifetime_hint() noexcept;
661 
673  future<uint64_t> get_inode_lifetime_hint() noexcept;
674 
676  future<uint64_t> size() const noexcept;
677 
687  future<> close() noexcept;
688 
691 
692 #ifdef SEASTAR_COROUTINES_ENABLED
694  // due to https://github.com/scylladb/seastar/issues/1913, we cannot use
695  // buffered generator yet.
696  coroutine::experimental::generator<directory_entry> experimental_list_directory();
697 #endif
698 
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) {
722  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
723  });
724  }
725 #endif
726 
741  template <typename CharType>
742  future<temporary_buffer<CharType>>
743  dma_read_bulk(uint64_t offset, size_t range_size, io_intent* intent = nullptr) noexcept {
744  return dma_read_bulk_impl(offset, range_size, internal::maybe_priority_class_ref(), intent).then([] (temporary_buffer<uint8_t> t) {
745  return temporary_buffer<CharType>(reinterpret_cast<CharType*>(t.get_write()), t.size(), t.release());
746  });
747  }
748 
758 private:
760  dma_read_bulk_impl(uint64_t offset, size_t range_size, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
761 
763  dma_write_impl(uint64_t pos, const uint8_t* buffer, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
764 
766  dma_write_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
767 
769  dma_read_impl(uint64_t pos, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
770 
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;
773 
775  dma_read_impl(uint64_t pos, std::vector<iovec> iov, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
776 
778  dma_read_exactly_impl(uint64_t pos, size_t len, internal::maybe_priority_class_ref pc, io_intent* intent) noexcept;
779 
780  future<uint64_t> get_lifetime_hint_impl(int op) noexcept;
781  future<> set_lifetime_hint_impl(int op, uint64_t hint) noexcept;
782 
783  friend class reactor;
784  friend class file_impl;
785  friend class file_data_sink_impl;
786  friend class file_data_source_impl;
787 };
788 
796 template <typename Func>
797 SEASTAR_CONCEPT( requires std::invocable<Func, file&> && std::is_nothrow_move_constructible_v<Func> )
798 auto with_file(future<file> file_fut, Func func) noexcept {
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] {
803  return f.close();
804  });
805  });
806  });
807 }
808 
823 template <typename Func>
824 SEASTAR_CONCEPT( requires std::invocable<Func, file&> && std::is_nothrow_move_constructible_v<Func> )
825 auto with_file_close_on_failure(future<file> file_fut, Func func) noexcept {
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 {
830  if (!ret.failed()) {
831  return ret;
832  }
833  return ret.finally([&f] {
834  // If f.close() fails, return that as nested exception.
835  return f.close();
836  });
837  });
838  });
839  });
840 }
841 
845 
853 class file_handle {
854  std::unique_ptr<file_handle_impl> _impl;
855 private:
856  explicit file_handle(std::unique_ptr<file_handle_impl> impl) : _impl(std::move(impl)) {}
857 public:
863  file_handle& operator=(const file_handle&);
865  file_handle& operator=(file_handle&&) noexcept;
867  file to_file() const &;
869  file to_file() &&;
870 
871  friend class file;
872 };
873 
875 
877 class cancelled_error : public std::exception {
878 public:
879  virtual const char* what() const noexcept {
880  return "cancelled";
881  }
882 };
883 
884 SEASTAR_MODULE_EXPORT_END
885 
886 }
An exception Cancelled IOs resolve their future into (see io_intent)
Definition: file.hh:877
Definition: file.hh:383
Definition: file.hh:111
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.
Definition: file.hh:118
Definition: file.hh:194
future close() noexcept
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
future flush() 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
Definition: file.hh:91
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