新加结构体POSIXSTATFS与SuperBlock用于处理statfs系统调用 (#667)

* 新加结构体POSIXSTATFS与SuperBlock用于处理statfs系统调用
This commit is contained in:
TTaq 2024-03-26 18:28:26 +08:00 committed by GitHub
parent 0cb807346c
commit 597ecc08c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 384 additions and 13 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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 {

View File

@ -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)
}
} }

View File

@ -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,

View File

@ -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
View File

@ -0,0 +1 @@
test_fstatfs

View 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:

View 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
View File

@ -0,0 +1 @@
test_statfs

View 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:

View 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;
}

View 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
}

View 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
}