pub struct DmaFile { /* private fields */ }
Expand description
An asynchronously accessed Direct Memory Access (DMA) file.
All access uses Direct I/O, and all operations including open and close are
asynchronous (with some exceptions noted). Reads from and writes to this
struct must come and go through the DmaBuffer
type, which will buffer
them in memory; on calling DmaFile::write_at
and DmaFile::read_at
,
the buffers will be passed to the OS to asynchronously write directly to the
file on disk, bypassing page caches.
See the module-level documentation for more details and examples.
Implementations
sourceimpl DmaFile
impl DmaFile
sourcepub fn is_same(&self, other: &DmaFile) -> bool
pub fn is_same(&self, other: &DmaFile) -> bool
Returns true if the DmaFiles represent the same file on the underlying device.
Files are considered to be the same if they live in the same file system and have the same Linux inode. Note that based on this rule a symlink is not considered to be the same file.
Files will be considered to be the same if:
- A file is opened multiple times (different file descriptors, but same file!)
- they are hard links.
Examples
use glommio::{io::DmaFile, LocalExecutor};
use std::os::unix::io::AsRawFd;
let ex = LocalExecutor::default();
ex.run(async {
let mut wfile = DmaFile::create("myfile.txt").await.unwrap();
let mut rfile = DmaFile::open("myfile.txt").await.unwrap();
// Different objects (OS file descriptors), so they will be different...
assert_ne!(wfile.as_raw_fd(), rfile.as_raw_fd());
// However they represent the same object.
assert!(wfile.is_same(&rfile));
wfile.close().await;
rfile.close().await;
});
sourcepub fn alloc_dma_buffer(&self, size: usize) -> DmaBuffer
pub fn alloc_dma_buffer(&self, size: usize) -> DmaBuffer
Allocates a buffer that is suitable for using to write to this file.
sourcepub async fn create<P: AsRef<Path>>(path: P) -> Result<DmaFile, ()>
pub async fn create<P: AsRef<Path>>(path: P) -> Result<DmaFile, ()>
Similar to create()
in the standard library, but returns a DMA file
sourcepub async fn open<P: AsRef<Path>>(path: P) -> Result<DmaFile, ()>
pub async fn open<P: AsRef<Path>>(path: P) -> Result<DmaFile, ()>
Similar to open()
in the standard library, but returns a DMA file
sourcepub async fn write_at(&self, buf: DmaBuffer, pos: u64) -> Result<usize, ()>
pub async fn write_at(&self, buf: DmaBuffer, pos: u64) -> Result<usize, ()>
Write the buffer in buf
to a specific position in the file.
It is expected that the buffer and the position be properly aligned for Direct I/O. In most platforms that means 4096 bytes. There is no write_at_aligned, since a nonaligned write would require a read-modify-write.
Buffers should be allocated through alloc_dma_buffer
, which
guarantees proper alignment, but alignment on position is still up
to the user.
This method acquires ownership of the buffer so the buffer can be kept alive while the kernel has it.
Note that it is legal to return fewer bytes than the buffer size. That is the situation, for example, when the device runs out of space (See the man page for write(2) for details)
Examples
use glommio::{io::DmaFile, LocalExecutor};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("test.txt").await.unwrap();
let mut buf = file.alloc_dma_buffer(4096);
let res = file.write_at(buf, 0).await.unwrap();
assert!(res <= 4096);
file.close().await.unwrap();
});
sourcepub async fn read_at_aligned(
&self,
pos: u64,
size: usize
) -> Result<ReadResult, ()>
pub async fn read_at_aligned(
&self,
pos: u64,
size: usize
) -> Result<ReadResult, ()>
Reads from a specific position in the file and returns the buffer.
The position must be aligned to for Direct I/O. In most platforms that means 512 bytes.
sourcepub async fn read_at(&self, pos: u64, size: usize) -> Result<ReadResult, ()>
pub async fn read_at(&self, pos: u64, size: usize) -> Result<ReadResult, ()>
Reads into buffer in buf from a specific position in the file.
It is not necessary to respect the O_DIRECT
alignment of the file, and
this API will internally convert the positions and sizes to match,
at a cost.
If you can guarantee proper alignment, prefer Self::read_at_aligned
instead
sourcepub fn read_many<V, S>(
self: &Rc<DmaFile>,
iovs: S,
buffer_limit: MergedBufferLimit,
read_amp_limit: ReadAmplificationLimit
) -> ReadManyResult<V, impl Stream<Item = (ScheduledSource, ReadManyArgs<V>)>> where
V: IoVec + Unpin,
S: Stream<Item = V> + Unpin,
pub fn read_many<V, S>(
self: &Rc<DmaFile>,
iovs: S,
buffer_limit: MergedBufferLimit,
read_amp_limit: ReadAmplificationLimit
) -> ReadManyResult<V, impl Stream<Item = (ScheduledSource, ReadManyArgs<V>)>> where
V: IoVec + Unpin,
S: Stream<Item = V> + Unpin,
Submit many reads and process the results in a stream-like fashion via a
ReadManyResult
.
This API will optimistically coalesce and deduplicate IO requests such
that two overlapping or adjacent reads will result in a single IO
request. This is transparent for the consumer, you will still
receive individual ReadResult
s corresponding to what you asked for.
The first argument is a stream of IoVec
. The last two
arguments control how aggressive the IO coalescing should be:
buffer_limit
controls how large a merged IO request can get;read_amp_limit
controls how much read amplification is acceptable.
It is not necessary to respect the O_DIRECT
alignment of the file, and
this API will internally align the reads appropriately.
sourcepub async fn fdatasync(&self) -> Result<(), ()>
pub async fn fdatasync(&self) -> Result<(), ()>
Issues fdatasync
for the underlying file, instructing the OS to flush
all writes to the device, providing durability even if the system
crashes or is rebooted.
As this is a DMA file, the OS will not be caching this file; however, there may be caches on the drive itself.
sourcepub async fn pre_allocate(&self, size: u64) -> Result<(), ()>
pub async fn pre_allocate(&self, size: u64) -> Result<(), ()>
pre-allocates space in the filesystem to hold a file at least as big as the size argument.
sourcepub async fn hint_extent_size(&self, size: usize) -> Result<i32, ()>
pub async fn hint_extent_size(&self, size: usize) -> Result<i32, ()>
Hint to the OS the size of increase of this file, to allow more efficient allocation of blocks.
Allocating blocks at the filesystem level turns asynchronous writes into threaded synchronous writes, as we need to first find the blocks to host the file.
If the extent is larger, that means many blocks are allocated at a time.
For instance, if the extent size is 1 MiB, that means that only 1 out
of 4 256 KiB writes will be turned synchronous. Combined with diligent
use of fallocate
we can greatly minimize context switches.
It is important not to set the extent size too big. Writes can fail otherwise if the extent can’t be allocated.
sourcepub async fn truncate(&self, size: u64) -> Result<(), ()>
pub async fn truncate(&self, size: u64) -> Result<(), ()>
Truncates a file to the specified size.
Note: this syscall might be issued in a background thread depending on the system’s capabilities.
sourcepub async fn rename<P: AsRef<Path>>(&self, new_path: P) -> Result<(), ()>
pub async fn rename<P: AsRef<Path>>(&self, new_path: P) -> Result<(), ()>
Rename this file.
Note: this syscall might be issued in a background thread depending on the system’s capabilities.
sourcepub async fn remove(&self) -> Result<(), ()>
pub async fn remove(&self) -> Result<(), ()>
Remove this file.
The file does not have to be closed to be removed. Removing removes the name from the filesystem but the file will still be accessible for as long as it is open.
Note: this syscall might be issued in a background thread depending on the system’s capabilities.
sourcepub fn path(&self) -> Option<Ref<'_, Path>>
pub fn path(&self) -> Option<Ref<'_, Path>>
Returns an Option
containing the path associated with this open
directory, or None
if there isn’t one.
sourcepub async fn close_rc(self: Rc<DmaFile>) -> Result<CloseResult, ()>
pub async fn close_rc(self: Rc<DmaFile>) -> Result<CloseResult, ()>
Convenience method that closes a DmaFile wrapped inside an Rc.
Returns CloseResult to indicate which operation was performed.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for DmaFile
impl !Send for DmaFile
impl !Sync for DmaFile
impl Unpin for DmaFile
impl !UnwindSafe for DmaFile
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
impl<T> Pointable for T
impl<T> Pointable for T
sourceimpl<T> WithSubscriber for T
impl<T> WithSubscriber for T
sourcefn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
sourcefn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more