Kernel/LibC: Implement {,f}statvfs

This commit is contained in:
2024-12-02 06:55:35 +02:00
parent ad1f175a39
commit a10ca47657
21 changed files with 173 additions and 5 deletions

View File

@@ -32,6 +32,18 @@ namespace Kernel
return superblock.magic == Ext2::Enum::SUPER_MAGIC;
}
unsigned long Ext2FS::bsize() const { return block_size(); }
unsigned long Ext2FS::frsize() const { return block_size(); }
fsblkcnt_t Ext2FS::blocks() const { return m_superblock.blocks_count; }
fsblkcnt_t Ext2FS::bfree() const { return m_superblock.free_blocks_count; }
fsblkcnt_t Ext2FS::bavail() const { return m_superblock.free_blocks_count; } // FIXME
fsfilcnt_t Ext2FS::files() const { return m_superblock.inodes_count; }
fsfilcnt_t Ext2FS::ffree() const { return m_superblock.free_inodes_count; }
fsfilcnt_t Ext2FS::favail() const { return m_superblock.free_inodes_count; } // FIXME
unsigned long Ext2FS::fsid() const { return *reinterpret_cast<const unsigned long*>(m_superblock.uuid); } // FIXME?
unsigned long Ext2FS::flag() const { return 0; }
unsigned long Ext2FS::namemax() const { return 0xFF; }
BAN::ErrorOr<BAN::RefPtr<Ext2FS>> Ext2FS::create(BAN::RefPtr<BlockDevice> block_device)
{
auto ext2fs = TRY(BAN::RefPtr<Ext2FS>::create(block_device));

View File

@@ -47,6 +47,11 @@ namespace Kernel
dwarnln("Could not cleanup inode from FS: {}", ret.error());
}
const FileSystem* Ext2Inode::filesystem() const
{
return &m_fs;
}
BAN::ErrorOr<BAN::Optional<uint32_t>> Ext2Inode::block_from_indirect_block(uint32_t block, uint32_t index, uint32_t depth)
{
if (block == 0)

View File

@@ -64,6 +64,18 @@ namespace Kernel
return validate_bpb(bpb_span.as<const FAT::BPB>());
}
unsigned long FATFS::bsize() const { return m_bpb.bytes_per_sector; }
unsigned long FATFS::frsize() const { return m_bpb.bytes_per_sector; }
fsblkcnt_t FATFS::blocks() const { return data_sector_count(); }
fsblkcnt_t FATFS::bfree() const { return 0; } // FIXME
fsblkcnt_t FATFS::bavail() const { return 0; } // FIXME
fsfilcnt_t FATFS::files() const { return m_bpb.number_of_fats * fat_size() * 8 / bits_per_fat_entry(); }
fsfilcnt_t FATFS::ffree() const { return 0; } // FIXME
fsfilcnt_t FATFS::favail() const { return 0; } // FIXME
unsigned long FATFS::fsid() const { return m_type == Type::FAT32 ? m_bpb.ext_32.volume_id : m_bpb.ext_12_16.volume_id; }
unsigned long FATFS::flag() const { return 0; }
unsigned long FATFS::namemax() const { return 255; }
BAN::ErrorOr<BAN::RefPtr<FATFS>> FATFS::create(BAN::RefPtr<BlockDevice> block_device)
{
// support only block devices with sectors at least 512 bytes
@@ -226,7 +238,7 @@ namespace Kernel
{
if (index >= root_sector_count())
return BAN::Error::from_errno(ENOENT);
const uint32_t first_root_sector = m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_sector_count());
const uint32_t first_root_sector = m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_size());
TRY(m_block_device->read_blocks(first_root_sector + index, 1, buffer));
return {};
}

View File

@@ -46,6 +46,11 @@ namespace Kernel
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}
const FileSystem* FATInode::filesystem() const
{
return &m_fs;
}
BAN::ErrorOr<void> FATInode::for_each_directory_entry(BAN::ConstByteSpan entry_span, BAN::Function<BAN::Iteration(const FAT::DirectoryEntry&)> callback)
{
ASSERT(mode().ifdir());

View File

@@ -41,6 +41,11 @@ namespace Kernel
/* GENERAL INODE */
const FileSystem* TmpInode::filesystem() const
{
return &m_fs;
}
dev_t TmpInode::dev() const
{
return m_fs.dev();

View File

@@ -1496,6 +1496,35 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_fstatvfsat(int fd, const char* path, struct statvfs* buf)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(buf, sizeof(struct statvfs), true));
auto inode = TRY(find_file(fd, path, 0)).inode;
auto* fs = inode->filesystem();
if (fs == nullptr)
{
ASSERT(inode->mode().ifsock() || inode->mode().ififo());
dwarnln("TODO: fstatvfs on sockets or pipe?");
return BAN::Error::from_errno(EINVAL);
}
buf->f_bsize = fs->bsize();
buf->f_frsize = fs->frsize();
buf->f_blocks = fs->blocks();
buf->f_bfree = fs->bfree();
buf->f_bavail = fs->bavail();
buf->f_files = fs->files();
buf->f_ffree = fs->ffree();
buf->f_favail = fs->favail();
buf->f_fsid = fs->fsid();
buf->f_flag = fs->flag();
buf->f_namemax = fs->namemax();
return 0;
}
BAN::ErrorOr<long> Process::sys_realpath(const char* path, char* buffer)
{
LockGuard _(m_process_lock);