mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
新加结构体POSIXSTATFS与SuperBlock用于处理statfs系统调用 (#667)
* 新加结构体POSIXSTATFS与SuperBlock用于处理statfs系统调用
This commit is contained in:
parent
0cb807346c
commit
597ecc08c2
@ -6,7 +6,7 @@ use super::vfs::{
|
|||||||
core::{generate_inode_id, ROOT_INODE},
|
core::{generate_inode_id, ROOT_INODE},
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
syscall::ModeType,
|
syscall::ModeType,
|
||||||
FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Metadata,
|
FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::device::device_number::DeviceNumber,
|
driver::base::device::device_number::DeviceNumber,
|
||||||
@ -25,13 +25,14 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
const DEVFS_MAX_NAMELEN: usize = 64;
|
const DEVFS_BLOCK_SIZE: u64 = 512;
|
||||||
|
const DEVFS_MAX_NAMELEN: usize = 255;
|
||||||
/// @brief dev文件系统
|
/// @brief dev文件系统
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevFS {
|
pub struct DevFS {
|
||||||
// 文件系统根节点
|
// 文件系统根节点
|
||||||
root_inode: Arc<LockedDevFSInode>,
|
root_inode: Arc<LockedDevFSInode>,
|
||||||
|
super_block: SuperBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileSystem for DevFS {
|
impl FileSystem for DevFS {
|
||||||
@ -53,10 +54,19 @@ impl FileSystem for DevFS {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"devfs"
|
"devfs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
self.super_block.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DevFS {
|
impl DevFS {
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new() -> Arc<Self> {
|
||||||
|
let super_block = SuperBlock::new(
|
||||||
|
Magic::DEVFS_MAGIC,
|
||||||
|
DEVFS_BLOCK_SIZE,
|
||||||
|
DEVFS_MAX_NAMELEN as u64,
|
||||||
|
);
|
||||||
// 初始化root inode
|
// 初始化root inode
|
||||||
let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
|
let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
|
||||||
// /dev 的权限设置为 读+执行,root 可以读写
|
// /dev 的权限设置为 读+执行,root 可以读写
|
||||||
@ -64,7 +74,10 @@ impl DevFS {
|
|||||||
DevFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
|
DevFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let devfs: Arc<DevFS> = Arc::new(DevFS { root_inode: root });
|
let devfs: Arc<DevFS> = Arc::new(DevFS {
|
||||||
|
root_inode: root,
|
||||||
|
super_block,
|
||||||
|
});
|
||||||
|
|
||||||
// 对root inode加锁,并继续完成初始化工作
|
// 对root inode加锁,并继续完成初始化工作
|
||||||
let mut root_guard: SpinLockGuard<DevFSInode> = devfs.root_inode.0.lock();
|
let mut root_guard: SpinLockGuard<DevFSInode> = devfs.root_inode.0.lock();
|
||||||
|
@ -11,7 +11,7 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::driver::base::device::device_number::DeviceNumber;
|
use crate::driver::base::device::device_number::DeviceNumber;
|
||||||
use crate::filesystem::vfs::SpecialNodeData;
|
use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock};
|
||||||
use crate::ipc::pipe::LockedPipeInode;
|
use crate::ipc::pipe::LockedPipeInode;
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
||||||
@ -36,6 +36,8 @@ use super::{
|
|||||||
utils::RESERVED_CLUSTERS,
|
utils::RESERVED_CLUSTERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FAT_MAX_NAMELEN: u64 = 255;
|
||||||
|
|
||||||
/// FAT32文件系统的最大的文件大小
|
/// FAT32文件系统的最大的文件大小
|
||||||
pub const MAX_FILE_SIZE: u64 = 0xffff_ffff;
|
pub const MAX_FILE_SIZE: u64 = 0xffff_ffff;
|
||||||
|
|
||||||
@ -252,6 +254,14 @@ impl FileSystem for FATFileSystem {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"fat"
|
"fat"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
SuperBlock::new(
|
||||||
|
Magic::FAT_MAGIC,
|
||||||
|
self.bpb.bytes_per_sector.into(),
|
||||||
|
FAT_MAX_NAMELEN,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FATFileSystem {
|
impl FATFileSystem {
|
||||||
|
@ -22,7 +22,7 @@ use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
|||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
|
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
|
||||||
FileType, FsInfo, IndexNode, InodeId, Metadata,
|
FileType, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod callback;
|
pub mod callback;
|
||||||
@ -51,11 +51,19 @@ impl FileSystem for KernFS {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"kernfs"
|
"kernfs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
SuperBlock::new(
|
||||||
|
Magic::KER_MAGIC,
|
||||||
|
KernFS::KERNFS_BLOCK_SIZE,
|
||||||
|
KernFS::MAX_NAMELEN as u64,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KernFS {
|
impl KernFS {
|
||||||
pub const MAX_NAMELEN: usize = 4096;
|
pub const MAX_NAMELEN: usize = 4096;
|
||||||
|
pub const KERNFS_BLOCK_SIZE: u64 = 512;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new() -> Arc<Self> {
|
||||||
let root_inode = Self::create_root_inode();
|
let root_inode = Self::create_root_inode();
|
||||||
|
@ -20,6 +20,7 @@ use crate::{
|
|||||||
kerror, kinfo,
|
kerror, kinfo,
|
||||||
libs::{
|
libs::{
|
||||||
once::Once,
|
once::Once,
|
||||||
|
rwlock::RwLock,
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
},
|
},
|
||||||
mm::allocator::page_frame::FrameAllocator,
|
mm::allocator::page_frame::FrameAllocator,
|
||||||
@ -30,7 +31,7 @@ use crate::{
|
|||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
file::{FileMode, FilePrivateData},
|
file::{FileMode, FilePrivateData},
|
||||||
syscall::ModeType,
|
syscall::ModeType,
|
||||||
FileSystem, FsInfo, IndexNode, InodeId, Metadata,
|
FileSystem, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod kmsg;
|
pub mod kmsg;
|
||||||
@ -76,7 +77,7 @@ pub struct InodeInfo {
|
|||||||
|
|
||||||
/// @brief procfs的inode名称的最大长度
|
/// @brief procfs的inode名称的最大长度
|
||||||
const PROCFS_MAX_NAMELEN: usize = 64;
|
const PROCFS_MAX_NAMELEN: usize = 64;
|
||||||
|
const PROCFS_BLOCK_SIZE: u64 = 512;
|
||||||
/// @brief procfs文件系统的Inode结构体
|
/// @brief procfs文件系统的Inode结构体
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LockedProcFSInode(SpinLock<ProcFSInode>);
|
pub struct LockedProcFSInode(SpinLock<ProcFSInode>);
|
||||||
@ -86,6 +87,7 @@ pub struct LockedProcFSInode(SpinLock<ProcFSInode>);
|
|||||||
pub struct ProcFS {
|
pub struct ProcFS {
|
||||||
/// procfs的root inode
|
/// procfs的root inode
|
||||||
root_inode: Arc<LockedProcFSInode>,
|
root_inode: Arc<LockedProcFSInode>,
|
||||||
|
super_block: RwLock<SuperBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -290,10 +292,19 @@ impl FileSystem for ProcFS {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"procfs"
|
"procfs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
self.super_block.read().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcFS {
|
impl ProcFS {
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new() -> Arc<Self> {
|
||||||
|
let super_block = SuperBlock::new(
|
||||||
|
Magic::PROC_MAGIC,
|
||||||
|
PROCFS_BLOCK_SIZE,
|
||||||
|
PROCFS_MAX_NAMELEN as u64,
|
||||||
|
);
|
||||||
// 初始化root inode
|
// 初始化root inode
|
||||||
let root: Arc<LockedProcFSInode> =
|
let root: Arc<LockedProcFSInode> =
|
||||||
Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
|
Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
|
||||||
@ -324,7 +335,10 @@ impl ProcFS {
|
|||||||
},
|
},
|
||||||
})));
|
})));
|
||||||
|
|
||||||
let result: Arc<ProcFS> = Arc::new(ProcFS { root_inode: root });
|
let result: Arc<ProcFS> = Arc::new(ProcFS {
|
||||||
|
root_inode: root,
|
||||||
|
super_block: RwLock::new(super_block),
|
||||||
|
});
|
||||||
|
|
||||||
// 对root inode加锁,并继续完成初始化工作
|
// 对root inode加锁,并继续完成初始化工作
|
||||||
let mut root_guard: SpinLockGuard<ProcFSInode> = result.root_inode.0.lock();
|
let mut root_guard: SpinLockGuard<ProcFSInode> = result.root_inode.0.lock();
|
||||||
|
@ -2,6 +2,7 @@ use core::any::Any;
|
|||||||
use core::intrinsics::unlikely;
|
use core::intrinsics::unlikely;
|
||||||
|
|
||||||
use crate::filesystem::vfs::FSMAKER;
|
use crate::filesystem::vfs::FSMAKER;
|
||||||
|
use crate::libs::rwlock::RwLock;
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::device::device_number::DeviceNumber,
|
driver::base::device::device_number::DeviceNumber,
|
||||||
filesystem::vfs::{core::generate_inode_id, FileType},
|
filesystem::vfs::{core::generate_inode_id, FileType},
|
||||||
@ -21,10 +22,11 @@ use super::vfs::{
|
|||||||
file::FilePrivateData, syscall::ModeType, FileSystem, FileSystemMaker, FsInfo, IndexNode,
|
file::FilePrivateData, syscall::ModeType, FileSystem, FileSystemMaker, FsInfo, IndexNode,
|
||||||
InodeId, Metadata, SpecialNodeData,
|
InodeId, Metadata, SpecialNodeData,
|
||||||
};
|
};
|
||||||
|
use super::vfs::{Magic, SuperBlock};
|
||||||
|
|
||||||
/// RamFS的inode名称的最大长度
|
/// RamFS的inode名称的最大长度
|
||||||
const RAMFS_MAX_NAMELEN: usize = 64;
|
const RAMFS_MAX_NAMELEN: usize = 64;
|
||||||
|
const RAMFS_BLOCK_SIZE: u64 = 512;
|
||||||
/// @brief 内存文件系统的Inode结构体
|
/// @brief 内存文件系统的Inode结构体
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct LockedRamFSInode(SpinLock<RamFSInode>);
|
struct LockedRamFSInode(SpinLock<RamFSInode>);
|
||||||
@ -34,6 +36,7 @@ struct LockedRamFSInode(SpinLock<RamFSInode>);
|
|||||||
pub struct RamFS {
|
pub struct RamFS {
|
||||||
/// RamFS的root inode
|
/// RamFS的root inode
|
||||||
root_inode: Arc<LockedRamFSInode>,
|
root_inode: Arc<LockedRamFSInode>,
|
||||||
|
super_block: RwLock<SuperBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 内存文件系统的Inode结构体(不包含锁)
|
/// @brief 内存文件系统的Inode结构体(不包含锁)
|
||||||
@ -80,10 +83,19 @@ impl FileSystem for RamFS {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"ramfs"
|
"ramfs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
self.super_block.read().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RamFS {
|
impl RamFS {
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new() -> Arc<Self> {
|
||||||
|
let super_block = SuperBlock::new(
|
||||||
|
Magic::RAMFS_MAGIC,
|
||||||
|
RAMFS_BLOCK_SIZE,
|
||||||
|
RAMFS_MAX_NAMELEN as u64,
|
||||||
|
);
|
||||||
// 初始化root inode
|
// 初始化root inode
|
||||||
let root: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode {
|
let root: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode {
|
||||||
parent: Weak::default(),
|
parent: Weak::default(),
|
||||||
@ -110,7 +122,10 @@ impl RamFS {
|
|||||||
special_node: None,
|
special_node: None,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
let result: Arc<RamFS> = Arc::new(RamFS { root_inode: root });
|
let result: Arc<RamFS> = Arc::new(RamFS {
|
||||||
|
root_inode: root,
|
||||||
|
super_block: RwLock::new(super_block),
|
||||||
|
});
|
||||||
|
|
||||||
// 对root inode加锁,并继续完成初始化工作
|
// 对root inode加锁,并继续完成初始化工作
|
||||||
let mut root_guard: SpinLockGuard<RamFSInode> = result.root_inode.0.lock();
|
let mut root_guard: SpinLockGuard<RamFSInode> = result.root_inode.0.lock();
|
||||||
|
@ -584,6 +584,60 @@ impl Default for Metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SuperBlock {
|
||||||
|
// type of filesystem
|
||||||
|
pub magic: Magic,
|
||||||
|
// optimal transfer block size
|
||||||
|
pub bsize: u64,
|
||||||
|
// total data blocks in filesystem
|
||||||
|
pub blocks: u64,
|
||||||
|
// free block in system
|
||||||
|
pub bfree: u64,
|
||||||
|
// 可供非特权用户使用的空闲块
|
||||||
|
pub bavail: u64,
|
||||||
|
// total inodes in filesystem
|
||||||
|
pub files: u64,
|
||||||
|
// free inodes in filesystem
|
||||||
|
pub ffree: u64,
|
||||||
|
// filesysytem id
|
||||||
|
pub fsid: u64,
|
||||||
|
// Max length of filename
|
||||||
|
pub namelen: u64,
|
||||||
|
// fragment size
|
||||||
|
pub frsize: u64,
|
||||||
|
// mount flags of filesystem
|
||||||
|
pub flags: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SuperBlock {
|
||||||
|
pub fn new(magic: Magic, bsize: u64, namelen: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
magic,
|
||||||
|
bsize,
|
||||||
|
blocks: 0,
|
||||||
|
bfree: 0,
|
||||||
|
bavail: 0,
|
||||||
|
files: 0,
|
||||||
|
ffree: 0,
|
||||||
|
fsid: 0,
|
||||||
|
namelen,
|
||||||
|
frsize: 0,
|
||||||
|
flags: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bitflags! {
|
||||||
|
pub struct Magic: u64 {
|
||||||
|
const DEVFS_MAGIC = 0x1373;
|
||||||
|
const FAT_MAGIC = 0xf2f52011;
|
||||||
|
const KER_MAGIC = 0x3153464b;
|
||||||
|
const PROC_MAGIC = 0x9fa0;
|
||||||
|
const RAMFS_MAGIC = 0x858458f6;
|
||||||
|
const MOUNT_MAGIC = 61267;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief 所有文件系统都应该实现的trait
|
/// @brief 所有文件系统都应该实现的trait
|
||||||
pub trait FileSystem: Any + Sync + Send + Debug {
|
pub trait FileSystem: Any + Sync + Send + Debug {
|
||||||
/// @brief 获取当前文件系统的root inode的指针
|
/// @brief 获取当前文件系统的root inode的指针
|
||||||
@ -597,6 +651,8 @@ pub trait FileSystem: Any + Sync + Send + Debug {
|
|||||||
fn as_any_ref(&self) -> &dyn Any;
|
fn as_any_ref(&self) -> &dyn Any;
|
||||||
|
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &str;
|
||||||
|
|
||||||
|
fn super_block(&self) -> SuperBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DowncastArc for dyn FileSystem {
|
impl DowncastArc for dyn FileSystem {
|
||||||
|
@ -13,8 +13,11 @@ use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::S
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
|
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
|
||||||
|
Magic, SuperBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MOUNTFS_BLOCK_SIZE: u64 = 512;
|
||||||
|
const MOUNTFS_MAX_NAMELEN: u64 = 64;
|
||||||
/// @brief 挂载文件系统
|
/// @brief 挂载文件系统
|
||||||
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -398,4 +401,7 @@ impl FileSystem for MountFS {
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"mountfs"
|
"mountfs"
|
||||||
}
|
}
|
||||||
|
fn super_block(&self) -> SuperBlock {
|
||||||
|
SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use crate::{
|
|||||||
time::TimeSpec,
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::SuperBlock;
|
||||||
use super::{
|
use super::{
|
||||||
core::{do_mkdir, do_remove_dir, do_unlink_at},
|
core::{do_mkdir, do_remove_dir, do_unlink_at},
|
||||||
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
||||||
@ -323,6 +324,41 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct PosixStatfs {
|
||||||
|
f_type: u64,
|
||||||
|
f_bsize: u64,
|
||||||
|
f_blocks: u64,
|
||||||
|
f_bfree: u64,
|
||||||
|
f_bavail: u64,
|
||||||
|
f_files: u64,
|
||||||
|
f_ffree: u64,
|
||||||
|
f_fsid: u64,
|
||||||
|
f_namelen: u64,
|
||||||
|
f_frsize: u64,
|
||||||
|
f_flags: u64,
|
||||||
|
f_spare: [u64; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SuperBlock> for PosixStatfs {
|
||||||
|
fn from(super_block: SuperBlock) -> Self {
|
||||||
|
Self {
|
||||||
|
f_type: super_block.magic.bits,
|
||||||
|
f_bsize: super_block.bsize,
|
||||||
|
f_blocks: super_block.blocks,
|
||||||
|
f_bfree: super_block.bfree,
|
||||||
|
f_bavail: super_block.bavail,
|
||||||
|
f_files: super_block.files,
|
||||||
|
f_ffree: super_block.ffree,
|
||||||
|
f_fsid: super_block.fsid,
|
||||||
|
f_namelen: super_block.namelen,
|
||||||
|
f_frsize: super_block.frsize,
|
||||||
|
f_flags: super_block.flags,
|
||||||
|
f_spare: [0u64; 4],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
///
|
///
|
||||||
/// Arguments for how openat2(2) should open the target path. If only @flags and
|
/// Arguments for how openat2(2) should open the target path. If only @flags and
|
||||||
/// @mode are non-zero, then openat2(2) operates very similarly to openat(2).
|
/// @mode are non-zero, then openat2(2) operates very similarly to openat(2).
|
||||||
@ -1209,6 +1245,36 @@ impl Syscall {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn statfs(path: *const u8, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> {
|
||||||
|
let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?;
|
||||||
|
let fd = Self::open(
|
||||||
|
path,
|
||||||
|
FileMode::O_RDONLY.bits(),
|
||||||
|
ModeType::empty().bits(),
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN)).unwrap();
|
||||||
|
let pcb = ProcessManager::current_pcb();
|
||||||
|
let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
|
||||||
|
let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
|
||||||
|
let statfs = PosixStatfs::from(inode.fs().super_block());
|
||||||
|
writer.copy_one_to_user(&statfs, 0)?;
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fstatfs(fd: i32, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> {
|
||||||
|
let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?;
|
||||||
|
let binding = ProcessManager::current_pcb().fd_table();
|
||||||
|
let fd_table_guard = binding.read();
|
||||||
|
let file = fd_table_guard
|
||||||
|
.get_file_by_fd(fd)
|
||||||
|
.ok_or(SystemError::EBADF)?;
|
||||||
|
drop(fd_table_guard);
|
||||||
|
let statfs = PosixStatfs::from(file.lock().inode().fs().super_block());
|
||||||
|
writer.copy_one_to_user(&statfs, 0)?;
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn do_statx(
|
pub fn do_statx(
|
||||||
fd: i32,
|
fd: i32,
|
||||||
path: *const u8,
|
path: *const u8,
|
||||||
|
@ -6,7 +6,7 @@ use core::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||||
filesystem::vfs::syscall::PosixStatx,
|
filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
|
||||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||||
mm::syscall::MremapFlags,
|
mm::syscall::MremapFlags,
|
||||||
net::syscall::MsgHdr,
|
net::syscall::MsgHdr,
|
||||||
@ -721,6 +721,18 @@ impl Syscall {
|
|||||||
Self::stat(path, kstat)
|
Self::stat(path, kstat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYS_STATFS => {
|
||||||
|
let path = args[0] as *const u8;
|
||||||
|
let statfs = args[1] as *mut PosixStatfs;
|
||||||
|
Self::statfs(path, statfs)
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_FSTATFS => {
|
||||||
|
let fd = args[0] as i32;
|
||||||
|
let statfs = args[1] as *mut PosixStatfs;
|
||||||
|
Self::fstatfs(fd, statfs)
|
||||||
|
}
|
||||||
|
|
||||||
SYS_STATX => {
|
SYS_STATX => {
|
||||||
let fd = args[0] as i32;
|
let fd = args[0] as i32;
|
||||||
let path = args[1] as *const u8;
|
let path = args[1] as *const u8;
|
||||||
|
1
user/apps/test_fstatfs/.gitignore
vendored
Normal file
1
user/apps/test_fstatfs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_fstatfs
|
20
user/apps/test_fstatfs/Makefile
Normal file
20
user/apps/test_fstatfs/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
ifeq ($(ARCH), x86_64)
|
||||||
|
CROSS_COMPILE=x86_64-linux-musl-
|
||||||
|
else ifeq ($(ARCH), riscv64)
|
||||||
|
CROSS_COMPILE=riscv64-linux-musl-
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC=$(CROSS_COMPILE)gcc
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: main.c
|
||||||
|
$(CC) -static -o test_fstatfs main.c
|
||||||
|
|
||||||
|
.PHONY: install clean
|
||||||
|
install: all
|
||||||
|
mv test_fstatfs $(DADK_CURRENT_BUILD_DIR)/test_fstatfs
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test_fstatfs *.o
|
||||||
|
|
||||||
|
fmt:
|
41
user/apps/test_fstatfs/main.c
Normal file
41
user/apps/test_fstatfs/main.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <sys/statfs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
int main(int argc,char **argv)
|
||||||
|
{
|
||||||
|
int fd = open("/bin/about.elf", O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return 0;
|
||||||
|
printf("fd = %d\n", fd);
|
||||||
|
struct statfs diskInfo;
|
||||||
|
|
||||||
|
|
||||||
|
fstatfs(fd, &diskInfo);
|
||||||
|
unsigned long long blocksize1 = diskInfo.f_bsize; //每个block里包含的字节数
|
||||||
|
unsigned long long totalsize = blocksize1 * diskInfo.f_blocks;//总的字节数,f_blocks为block的数目
|
||||||
|
printf("Total_size=%llu B =%llu KB =%llu MB = %llu GB\n",
|
||||||
|
totalsize,totalsize>>10,totalsize>>20, totalsize>>30);
|
||||||
|
|
||||||
|
/* 2.获取一下剩余空间和可用空间的大小 */
|
||||||
|
unsigned long long freeDisk = diskInfo.f_bfree * blocksize1; //剩余空间的大小
|
||||||
|
unsigned long long availableDisk = diskInfo.f_bavail * blocksize1; //可用空间大小
|
||||||
|
printf("Disk_free=%llu MB =%llu GB Disk_available=%llu MB = %llu GB\n",
|
||||||
|
freeDisk>>20,freeDisk>>30,availableDisk>>20, availableDisk>>30);
|
||||||
|
|
||||||
|
|
||||||
|
printf("====================\n");
|
||||||
|
printf("diskInfo address: %p\n", diskInfo);
|
||||||
|
printf("f_type= %lu\n", diskInfo.f_type);
|
||||||
|
printf("f_bsize = %lu\n", diskInfo.f_bsize);
|
||||||
|
printf("f_blocks = %d\n", diskInfo.f_blocks);
|
||||||
|
printf("f_bfree = %lu\n", diskInfo.f_bfree);
|
||||||
|
printf("b_avail = %d\n", diskInfo.f_bavail);
|
||||||
|
printf("f_files = %d\n", diskInfo.f_files);
|
||||||
|
printf("f_ffree = %lu\n", diskInfo.f_ffree);
|
||||||
|
printf("f_fsid = %ld\n", diskInfo.f_fsid);
|
||||||
|
printf("f_namelen = %ld\n", diskInfo.f_namelen);
|
||||||
|
printf("f_frsize = %ld\n", diskInfo.f_frsize);
|
||||||
|
printf("f_flags = %ld\n", diskInfo.f_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
1
user/apps/test_statfs/.gitignore
vendored
Normal file
1
user/apps/test_statfs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_statfs
|
20
user/apps/test_statfs/Makefile
Normal file
20
user/apps/test_statfs/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
ifeq ($(ARCH), x86_64)
|
||||||
|
CROSS_COMPILE=x86_64-linux-musl-
|
||||||
|
else ifeq ($(ARCH), riscv64)
|
||||||
|
CROSS_COMPILE=riscv64-linux-musl-
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC=$(CROSS_COMPILE)gcc
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: main.c
|
||||||
|
$(CC) -static -o test_statfs main.c
|
||||||
|
|
||||||
|
.PHONY: install clean
|
||||||
|
install: all
|
||||||
|
mv test_statfs $(DADK_CURRENT_BUILD_DIR)/test_statfs
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test_statfs *.o
|
||||||
|
|
||||||
|
fmt:
|
36
user/apps/test_statfs/main.c
Normal file
36
user/apps/test_statfs/main.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <sys/statfs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc,char **argv)
|
||||||
|
{
|
||||||
|
struct statfs diskInfo;
|
||||||
|
|
||||||
|
|
||||||
|
statfs("/bin/about.elf", &diskInfo);
|
||||||
|
unsigned long long blocksize1 = diskInfo.f_bsize; //每个block里包含的字节数
|
||||||
|
unsigned long long totalsize = blocksize1 * diskInfo.f_blocks;//总的字节数,f_blocks为block的数目
|
||||||
|
printf("Total_size=%llu B =%llu KB =%llu MB = %llu GB\n",
|
||||||
|
totalsize,totalsize>>10,totalsize>>20, totalsize>>30);
|
||||||
|
|
||||||
|
/* 2.获取一下剩余空间和可用空间的大小 */
|
||||||
|
unsigned long long freeDisk = diskInfo.f_bfree * blocksize1; //剩余空间的大小
|
||||||
|
unsigned long long availableDisk = diskInfo.f_bavail * blocksize1; //可用空间大小
|
||||||
|
printf("Disk_free=%llu MB =%llu GB Disk_available=%llu MB = %llu GB\n",
|
||||||
|
freeDisk>>20,freeDisk>>30,availableDisk>>20, availableDisk>>30);
|
||||||
|
|
||||||
|
|
||||||
|
printf("====================\n");
|
||||||
|
printf("diskInfo address: %p\n", diskInfo);
|
||||||
|
printf("f_type= %lu\n", diskInfo.f_type);
|
||||||
|
printf("f_bsize = %lu\n", diskInfo.f_bsize);
|
||||||
|
printf("f_blocks = %d\n", diskInfo.f_blocks);
|
||||||
|
printf("f_bfree = %lu\n", diskInfo.f_bfree);
|
||||||
|
printf("b_avail = %d\n", diskInfo.f_bavail);
|
||||||
|
printf("f_files = %d\n", diskInfo.f_files);
|
||||||
|
printf("f_ffree = %lu\n", diskInfo.f_ffree);
|
||||||
|
printf("f_fsid = %ld\n", diskInfo.f_fsid);
|
||||||
|
printf("f_namelen = %ld\n", diskInfo.f_namelen);
|
||||||
|
printf("f_frsize = %ld\n", diskInfo.f_frsize);
|
||||||
|
printf("f_flags = %ld\n", diskInfo.f_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
26
user/dadk/config/test_fstatfs_0_1_0.dadk
Normal file
26
user/dadk/config/test_fstatfs_0_1_0.dadk
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "test_fstatfs",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "测试fstatfs",
|
||||||
|
"rust_target": null,
|
||||||
|
"task_type": {
|
||||||
|
"BuildFromSource": {
|
||||||
|
"Local": {
|
||||||
|
"path": "apps/test_fstatfs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depends": [],
|
||||||
|
"build": {
|
||||||
|
"build_command": "make install"
|
||||||
|
},
|
||||||
|
"install": {
|
||||||
|
"in_dragonos_path": "/bin"
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
|
"clean_command": "make clean"
|
||||||
|
},
|
||||||
|
"envs": [],
|
||||||
|
"build_once": false,
|
||||||
|
"install_once": false
|
||||||
|
}
|
26
user/dadk/config/test_statfs_0_1_0.dadk
Normal file
26
user/dadk/config/test_statfs_0_1_0.dadk
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "test_statfs",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "测试statfs",
|
||||||
|
"rust_target": null,
|
||||||
|
"task_type": {
|
||||||
|
"BuildFromSource": {
|
||||||
|
"Local": {
|
||||||
|
"path": "apps/test_statfs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depends": [],
|
||||||
|
"build": {
|
||||||
|
"build_command": "make install"
|
||||||
|
},
|
||||||
|
"install": {
|
||||||
|
"in_dragonos_path": "/bin"
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
|
"clean_command": "make clean"
|
||||||
|
},
|
||||||
|
"envs": [],
|
||||||
|
"build_once": false,
|
||||||
|
"install_once": false
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user