Skip to main content

FileOptions

Struct FileOptions 

Source
pub struct FileOptions<A: DataAccess = NoData> { /* private fields */ }
Expand description

What to open: the data access, the other rights, what other opens may do meanwhile, what the open does about a file that is there or not, whether a link is opened or followed, and the cache hints. Only these, because the open mode is what an OpenedFile vouches for, and a caller’s own flags could change it. A file is shared for reading, writing and deletion, as std opens one, until share says otherwise.

The data access is the type parameter A: it starts as NoData, and read and write move it, so the handle an open makes carries the access it was asked for.

use win_durable_ioring::windows_backend::{FileOptions, FileRights, ReadWrite};

let options: FileOptions<ReadWrite> = FileOptions::new()
    .read()
    .write()
    .rights(FileRights::WRITE_ATTRIBUTES);

Implementations§

Source§

impl FileOptions<NoData>

Source

pub fn new() -> Self

Nothing requested: no data access and no other right. Ask to read and write before opening a file that is to become a target.

Source§

impl<A: DataAccess> FileOptions<A>

Source

pub fn read(self) -> FileOptions<A::WithRead>

Ask for the right to read the data (FILE_READ_DATA). The options carry the access this adds to what they already had: NoData becomes ReadOnly and WriteOnly becomes ReadWrite.

Source

pub fn write(self) -> FileOptions<A::WithWrite>

Ask for the right to write the data (FILE_WRITE_DATA), as read asks to read.

Source

pub fn rights(self, rights: FileRights) -> Self

The rights to open with besides the data access (dwDesiredAccess): the attribute, delete and security rights, which gate calls made on the handle this crate lends and not anything it does itself. What the file’s security allows is the kernel’s to say, and its refusal reaches the caller as its own error.

Calling this again replaces the rights; join them with | to ask for several.

Source

pub fn share(self, share: ShareMode) -> Self

What other opens of the file may request while this handle is open (dwShareMode). The default is ShareMode::ALL; ShareMode::NONE is an exclusive open, which a database that owns its file wants.

An open the sharing of either side does not allow fails with a SharingViolation, whichever of the two opens came first. Calling this again replaces the mode.

Source

pub fn disposition(self, disposition: Disposition) -> Self

What the open does about a file that is there and one that is not (dwCreationDisposition). The default is Disposition::OpenExisting. Calling this again replaces the disposition.

No disposition changes the contents of a file that exists, so none is refused for want of the right to write. A caller that wants an existing file emptied does it through the handle this crate lends, with File::set_len(0), which needs the write right and is not atomic with the open.

Source

pub fn open_reparse_point(self, open_reparse_point: bool) -> Self

Open a link itself and not what it points to (FILE_FLAG_OPEN_REPARSE_POINT). Without it a link is followed, including by Disposition::CreateNew, which then creates the file the link names. With it a link that is already there is what exists, so CreateNew fails and OpenAlways opens the link. It has no effect on a path that is not a reparse point.

Source

pub fn attributes(self, attributes: FileAttributes) -> Self

The attributes a file the open creates is given (FILE_ATTRIBUTE_* in dwFlagsAndAttributes). The default is none, which is not FILE_ATTRIBUTE_NORMAL: the empty set passes no attribute at all, and a created file has the attributes the file system gives it, ARCHIVE among them (measured: the same as an open that passes NORMAL). Calling this again replaces the set.

They are for a file that is created, and what an open of a file that exists does with them is Win32’s: the CreateFileW page says they are generally combined with the file’s own or ignored, and nothing here changes an existing file’s attributes (measured: the open leaves them as they were).

Source

pub fn delete_on_close(self, delete_on_close: bool) -> Self

Delete the file when its last handle is closed (FILE_FLAG_DELETE_ON_CLOSE). A durability report is then about data that does not outlive the handles, which is the caller’s choice to make.

The file goes when the last handle to it, however that was opened, is closed. Measured on Windows 11 build 26300: the open succeeds without the right to delete among the rights (the CreateFileW pages do not say it is needed; ZwCreateFile’s does, for its own flag, and that is not the call made here), and while the handle is open a later open has to share deletion (ShareMode::DELETE) or it fails with a SharingViolation. Nothing is added or checked here; which combinations are refused ahead of the open is DI-14.4’s.

Source

pub fn open_no_recall(self, open_no_recall: bool) -> Self

Ask that the file’s data not be brought back from remote storage to be read (FILE_FLAG_OPEN_NO_RECALL). The CreateFileW page says the flag is for remote storage systems; it is passed on and nothing about a target depends on it. What it does to a file on a local disk was not measured.

Source

pub fn posix_semantics(self, posix_semantics: bool) -> Self

Access the file by POSIX rules (FILE_FLAG_POSIX_SEMANTICS). The CreateFileW page says that this includes allowing names that differ only in case, and that a file made with the flag may not be reachable by applications written for MS-DOS or 16-bit Windows. It is passed on and nothing about a target depends on it.

Source

pub fn overlapped(self, overlapped: bool) -> Self

Open the file for overlapped I/O (FILE_FLAG_OVERLAPPED). Every operation this crate’s targets make is addressed by offset, so the file pointer the system then stops keeping is not one they read. Measured on Windows 11 build 26300 (the run is in DI-D-64), the ring takes such a handle and reports the same result for each operation as for one opened without the flag, in each buffering mode. What differs is when a completion is there: a handle opened without the flag completes during the submit, and an unbuffered one opened with it was not complete then for its reads, which then completed in an order that was not always the order queued.

The handle this crate lends is the same one, so I/O a caller makes on it directly without an offset, with a std::fs::File for one, is I/O on an overlapped handle, where the CreateFileW page says the file pointer is not maintained and operations are not serialised.

Source

pub fn random_access(self, random_access: bool) -> Self

Hint that the file will be accessed at random (FILE_FLAG_RANDOM_ACCESS), which the system may use to tune its caching.

It is passed to an unbuffered file as well as a cached one, and is never refused. The CreateFileW documentation says the flag “has no effect if the file system does not support cached I/O and FILE_FLAG_NO_BUFFERING”, which can be read two ways, so what it does to an unbuffered file is the kernel’s to say. Measured on Windows 11 build 26300: every combination of the two hints, cached and unbuffered, opens and carries a sector-aligned write and read, and an unbuffered one also runs through the ring. Whether a hint changes the system’s caching was not measured, and nothing about the warranty class, the alignment or write-through depends on it. Asking for this and sequential_scan together is the documentation’s “self-defeating”, and is passed on all the same.

Source

pub fn sequential_scan(self, sequential_scan: bool) -> Self

Hint that the file will be read sequentially from beginning to end (FILE_FLAG_SEQUENTIAL_SCAN), which the system may use to tune its caching. The documentation says it should not be used if reverse scans will be.

Passed through and documented as random_access is.

Trait Implementations§

Source§

impl<A: Clone + DataAccess> Clone for FileOptions<A>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<A: Copy + DataAccess> Copy for FileOptions<A>

Source§

impl<A: Debug + DataAccess> Debug for FileOptions<A>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for FileOptions<NoData>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<A> Freeze for FileOptions<A>
where PhantomData<A>: Freeze,

§

impl<A> RefUnwindSafe for FileOptions<A>

§

impl<A> Send for FileOptions<A>
where PhantomData<A>: Send,

§

impl<A> Sync for FileOptions<A>
where PhantomData<A>: Sync,

§

impl<A> Unpin for FileOptions<A>
where PhantomData<A>: Unpin,

§

impl<A> UnsafeUnpin for FileOptions<A>

§

impl<A> UnwindSafe for FileOptions<A>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.