From a34a08df55345d086ee7d5d05f6e920599571f0c Mon Sep 17 00:00:00 2001 From: Daniel Xu Date: Sun, 9 Jan 2022 13:22:05 -0800 Subject: [PATCH] rust: file: Add `FileFlags` type for `File` flags 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 #606. Signed-off-by: Daniel Xu --- rust/kernel/file.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index 648628837d8239..bbc96557add79c 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -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 @@ -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 }