Skip to content

Commit

Permalink
rust: file: Add FileFlags type for File flags
Browse files Browse the repository at this point in the history
This commit addes a wrapper struct, `FileFlags`, that defines constants
for `struct file`'s `f_flags`.

This struct is desirable b/c callers will no longer need to access
soon-to-be-private `bindings` module. It also documents the previously
ambiguous u32 return value on `flags()`.

This closes torvalds#606.

Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
  • Loading branch information
danobi committed Jan 16, 2022
1 parent 27fe495 commit a34a08d
Showing 1 changed file with 101 additions and 0 deletions.
101 changes: 101 additions & 0 deletions rust/kernel/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,105 @@
use crate::{bindings, cred::CredentialRef, error::Error, Result};
use core::{mem::ManuallyDrop, ops::Deref};

/// Access mode associated with a file
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum AccessMode {
/// File is read only.
ReadOnly,
/// File is write only.
WriteOnly,
/// File is readable and writeable.
ReadWrite,
}

/// Flags associated with a [`File`].
///
/// It is tagged with `non_exhaustive` to prevent users from instantiating it.
#[non_exhaustive]
pub struct FileFlags;

impl FileFlags {
/// File is opened in append mode.
pub const O_APPEND: u32 = bindings::O_APPEND;

/// Signal-driven I/O is enabled.
pub const O_ASYNC: u32 = bindings::FASYNC;

/// Close-on-exec flag is set.
pub const O_CLOEXEC: u32 = bindings::O_CLOEXEC;

/// File was created if it didn't already exist.
pub const O_CREAT: u32 = bindings::O_CREAT;

/// Direct I/O is enabled for this file.
pub const O_DIRECT: u32 = bindings::O_DIRECT;

/// File must be a directory.
pub const O_DIRECTORY: u32 = bindings::O_DIRECTORY;

/// Like `Self::O_SYNC` except metadata is not synced.
pub const O_DSYNC: u32 = bindings::O_DSYNC;

/// Ensure that this file is created with the `open(2)` call.
pub const O_EXCL: u32 = bindings::O_EXCL;

/// Large file size enabled (`off64_t` over `off_t`)
pub const O_LARGEFILE: u32 = bindings::O_LARGEFILE;

/// Do not update the file last access time.
pub const O_NOATIME: u32 = bindings::O_NOATIME;

/// File should not be used as process's controlling terminal.
pub const O_NOCTTY: u32 = bindings::O_NOCTTY;

/// If basename of path is a symbolic link, fail open.
pub const O_NOFOLLOW: u32 = bindings::O_NOFOLLOW;

/// File is using nonblocking I/O.
pub const O_NONBLOCK: u32 = bindings::O_NONBLOCK;

/// Also known as `O_NDELAY`.
///
/// This is effectively the same flag as [`Self::O_NONBLOCK`] on all architectures
/// except SPARC64.
pub const O_NDELAY: u32 = bindings::O_NDELAY;

/// Used to obtain a path file descriptor.
pub const O_PATH: u32 = bindings::O_PATH;

/// Write operations on this file will flush data and metadata.
pub const O_SYNC: u32 = bindings::O_SYNC;

/// This file is an unnamed temporary regular file.
pub const O_TMPFILE: u32 = bindings::O_TMPFILE;

/// File should be truncated to length 0.
pub const O_TRUNC: u32 = bindings::O_TRUNC;

/// Bitmask for access mode flags.
///
/// # Examples
///
/// ```
/// use kernel::file::FileFlags;
/// # fn do_something() {}
/// # let flags = 0;
/// if (flags & FileFlags::O_ACCMODE) == FileFlags::O_RDONLY {
/// do_something();
/// }
/// ```
pub const O_ACCMODE: u32 = bindings::O_ACCMODE;

/// File is read only.
pub const O_RDONLY: u32 = bindings::O_RDONLY;

/// File is write only.
pub const O_WRONLY: u32 = bindings::O_WRONLY;

/// File can be both read and written.
pub const O_RDWR: u32 = bindings::O_RDWR;
}

/// Wraps the kernel's `struct file`.
///
/// # Invariants
Expand Down Expand Up @@ -56,6 +155,8 @@ impl File {
}

/// Returns the flags associated with the file.
///
/// The flags are a combination of the constants in [`FileFlags`].
pub fn flags(&self) -> u32 {
// SAFETY: `File::ptr` is guaranteed to be valid by the type invariants.
unsafe { (*self.ptr).f_flags }
Expand Down

0 comments on commit a34a08d

Please sign in to comment.