Introduce AtomicFileCreationMask
This commit is contained in:
parent
c56089309b
commit
4552fdb830
|
|
@ -1,13 +1,16 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use ostd::sync::{RwLock, RwMutex};
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
use super::{fs_resolver::FsResolver, utils::FileCreationMask};
|
||||
use ostd::sync::RwMutex;
|
||||
|
||||
use super::{fs_resolver::FsResolver, utils::AtomicFileCreationMask};
|
||||
use crate::fs::utils::FileCreationMask;
|
||||
|
||||
/// FS information for a POSIX thread.
|
||||
pub struct ThreadFsInfo {
|
||||
resolver: RwMutex<FsResolver>,
|
||||
umask: RwLock<FileCreationMask>,
|
||||
umask: AtomicFileCreationMask,
|
||||
}
|
||||
|
||||
impl ThreadFsInfo {
|
||||
|
|
@ -15,7 +18,7 @@ impl ThreadFsInfo {
|
|||
pub fn new(fs_resolver: FsResolver) -> Self {
|
||||
Self {
|
||||
resolver: RwMutex::new(fs_resolver),
|
||||
umask: RwLock::new(FileCreationMask::default()),
|
||||
umask: AtomicFileCreationMask::new(FileCreationMask::default()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -25,8 +28,13 @@ impl ThreadFsInfo {
|
|||
}
|
||||
|
||||
/// Returns the associated `FileCreationMask`.
|
||||
pub fn umask(&self) -> &RwLock<FileCreationMask> {
|
||||
&self.umask
|
||||
pub fn umask(&self) -> FileCreationMask {
|
||||
self.umask.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
/// Sets a new `FileCreationMask`, returning the old one.
|
||||
pub fn swap_umask(&self, new_mask: FileCreationMask) -> FileCreationMask {
|
||||
self.umask.swap(new_mask, Ordering::AcqRel)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +42,7 @@ impl Clone for ThreadFsInfo {
|
|||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
resolver: RwMutex::new(self.resolver.read().clone()),
|
||||
umask: RwLock::new(FileCreationMask::new(self.umask.read().get())),
|
||||
umask: AtomicFileCreationMask::new(self.umask.load(Ordering::Acquire)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,24 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use core::sync::atomic::AtomicU16;
|
||||
|
||||
use atomic_integer_wrapper::define_atomic_version_of_integer_like_type;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
/// A mask for the file mode of a newly-created file or directory.
|
||||
///
|
||||
/// This mask is always a subset of `0o777`.
|
||||
pub struct FileCreationMask(u16);
|
||||
|
||||
impl FileCreationMask {
|
||||
// Creates a new instance, the initial value is `0o777`.
|
||||
pub fn new(val: u16) -> Self {
|
||||
Self(0o777 & val)
|
||||
}
|
||||
/// The valid bits of a `FileCreationMask`.
|
||||
const MASK: u16 = 0o777;
|
||||
|
||||
/// Get a new value.
|
||||
pub fn get(&self) -> u16 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Set a new value.
|
||||
pub fn set(&mut self, new_mask: u16) -> u16 {
|
||||
let new_mask = new_mask & 0o777;
|
||||
let old_mask = self.0;
|
||||
self.0 = new_mask;
|
||||
old_mask
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FileCreationMask {
|
||||
|
|
@ -30,3 +26,30 @@ impl Default for FileCreationMask {
|
|||
Self(0o022)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u16> for FileCreationMask {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
||||
if value & !Self::MASK != 0 {
|
||||
Err(Error::with_message(
|
||||
crate::Errno::EINVAL,
|
||||
"Invalid FileCreationMask.",
|
||||
))
|
||||
} else {
|
||||
Ok(Self(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FileCreationMask> for u16 {
|
||||
fn from(value: FileCreationMask) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
define_atomic_version_of_integer_like_type!(FileCreationMask, try_from = true, {
|
||||
/// An atomic version of `FileCreationMask`.
|
||||
#[derive(Debug)]
|
||||
pub struct AtomicFileCreationMask(AtomicU16);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub use dirent_visitor::{DirentCounter, DirentVisitor};
|
|||
pub use direntry_vec::DirEntryVecExt;
|
||||
pub use endpoint::{Endpoint, EndpointState};
|
||||
pub use falloc_mode::FallocMode;
|
||||
pub use file_creation_mask::FileCreationMask;
|
||||
pub use file_creation_mask::{AtomicFileCreationMask, FileCreationMask};
|
||||
pub use flock::{FlockItem, FlockList, FlockType};
|
||||
pub use fs::{FileSystem, FsFlags, SuperBlock};
|
||||
pub use inode::{Extension, Inode, InodeType, Metadata, MknodType, Permission};
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ pub fn sys_mkdirat(
|
|||
};
|
||||
|
||||
let inode_mode = {
|
||||
let mask_mode = mode & !fs_ref.umask().read().get();
|
||||
let mask_mode = mode & !fs_ref.umask().get();
|
||||
InodeMode::from_bits_truncate(mask_mode)
|
||||
};
|
||||
let _ = dir_path.new_fs_child(name.trim_end_matches('/'), InodeType::Dir, inode_mode)?;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub fn sys_mknodat(
|
|||
let path_name = ctx.user_space().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let inode_mode = {
|
||||
let mask_mode = mode & !fs_ref.umask().read().get();
|
||||
let mask_mode = mode & !fs_ref.umask().get();
|
||||
InodeMode::from_bits_truncate(mask_mode)
|
||||
};
|
||||
let inode_type = InodeType::from_raw_mode(mode)?;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub fn sys_openat(
|
|||
let path = path.to_string_lossy();
|
||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let mask_mode = mode & !fs_ref.umask().read().get();
|
||||
let mask_mode = mode & !fs_ref.umask().get();
|
||||
let inode_handle = fs_ref
|
||||
.resolver()
|
||||
.read()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ use crate::prelude::*;
|
|||
|
||||
pub fn sys_umask(mask: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||
debug!("mask = 0o{:o}", mask);
|
||||
let old_mask = ctx.thread_local.borrow_fs().umask().write().set(mask);
|
||||
Ok(SyscallReturn::Return(old_mask as _))
|
||||
let old_mask = ctx.thread_local.borrow_fs().swap_umask(mask.try_into()?);
|
||||
Ok(SyscallReturn::Return(old_mask.get() as _))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue