forked from Bananymous/banan-os
Kernel/LibC: Implement {,f}statvfs
This commit is contained in:
parent
ad1f175a39
commit
a10ca47657
|
@ -11,6 +11,18 @@ namespace Kernel
|
||||||
class Ext2FS final : public FileSystem
|
class Ext2FS final : public FileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual unsigned long bsize() const override;
|
||||||
|
virtual unsigned long frsize() const override;
|
||||||
|
virtual fsblkcnt_t blocks() const override;
|
||||||
|
virtual fsblkcnt_t bfree() const override;
|
||||||
|
virtual fsblkcnt_t bavail() const override;
|
||||||
|
virtual fsfilcnt_t files() const override;
|
||||||
|
virtual fsfilcnt_t ffree() const override;
|
||||||
|
virtual fsfilcnt_t favail() const override;
|
||||||
|
virtual unsigned long fsid() const override;
|
||||||
|
virtual unsigned long flag() const override;
|
||||||
|
virtual unsigned long namemax() const override;
|
||||||
|
|
||||||
class BlockBufferWrapper
|
class BlockBufferWrapper
|
||||||
{
|
{
|
||||||
BAN_NON_COPYABLE(BlockBufferWrapper);
|
BAN_NON_COPYABLE(BlockBufferWrapper);
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace Kernel
|
||||||
virtual dev_t dev() const override { return 0; }
|
virtual dev_t dev() const override { return 0; }
|
||||||
virtual dev_t rdev() const override { return 0; }
|
virtual dev_t rdev() const override { return 0; }
|
||||||
|
|
||||||
|
virtual const FileSystem* filesystem() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override;
|
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override;
|
||||||
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override;
|
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override;
|
||||||
|
|
|
@ -20,6 +20,18 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual unsigned long bsize() const override;
|
||||||
|
virtual unsigned long frsize() const override;
|
||||||
|
virtual fsblkcnt_t blocks() const override;
|
||||||
|
virtual fsblkcnt_t bfree() const override;
|
||||||
|
virtual fsblkcnt_t bavail() const override;
|
||||||
|
virtual fsfilcnt_t files() const override;
|
||||||
|
virtual fsfilcnt_t ffree() const override;
|
||||||
|
virtual fsfilcnt_t favail() const override;
|
||||||
|
virtual unsigned long fsid() const override;
|
||||||
|
virtual unsigned long flag() const override;
|
||||||
|
virtual unsigned long namemax() const override;
|
||||||
|
|
||||||
static BAN::ErrorOr<bool> probe(BAN::RefPtr<BlockDevice>);
|
static BAN::ErrorOr<bool> probe(BAN::RefPtr<BlockDevice>);
|
||||||
static BAN::ErrorOr<BAN::RefPtr<FATFS>> create(BAN::RefPtr<BlockDevice>);
|
static BAN::ErrorOr<BAN::RefPtr<FATFS>> create(BAN::RefPtr<BlockDevice>);
|
||||||
|
|
||||||
|
@ -45,13 +57,15 @@ namespace Kernel
|
||||||
|
|
||||||
// TODO: These probably should be constant variables
|
// TODO: These probably should be constant variables
|
||||||
uint32_t root_sector_count() const { return BAN::Math::div_round_up<uint32_t>(m_bpb.root_entry_count * 32, m_bpb.bytes_per_sector); }
|
uint32_t root_sector_count() const { return BAN::Math::div_round_up<uint32_t>(m_bpb.root_entry_count * 32, m_bpb.bytes_per_sector); }
|
||||||
uint32_t fat_sector_count() const { return m_bpb.fat_size16 ? m_bpb.fat_size16 : m_bpb.ext_32.fat_size32; }
|
uint32_t fat_size() const { return m_bpb.fat_size16 ? m_bpb.fat_size16 : m_bpb.ext_32.fat_size32; }
|
||||||
uint32_t total_sector_count() const { return m_bpb.total_sectors16 ? m_bpb.total_sectors16 : m_bpb.total_sectors32; }
|
uint32_t total_sector_count() const { return m_bpb.total_sectors16 ? m_bpb.total_sectors16 : m_bpb.total_sectors32; }
|
||||||
uint32_t data_sector_count() const { return total_sector_count() - (m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_sector_count()) + root_sector_count()); }
|
uint32_t data_sector_count() const { return total_sector_count() - (m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_size()) + root_sector_count()); }
|
||||||
uint32_t cluster_count() const { return data_sector_count() / m_bpb.sectors_per_cluster; }
|
uint32_t cluster_count() const { return data_sector_count() / m_bpb.sectors_per_cluster; }
|
||||||
uint32_t first_data_sector() const { return m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_sector_count()) + root_sector_count(); }
|
uint32_t first_data_sector() const { return m_bpb.reserved_sector_count + (m_bpb.number_of_fats * fat_size()) + root_sector_count(); }
|
||||||
uint32_t first_fat_sector() const { return m_bpb.reserved_sector_count; }
|
uint32_t first_fat_sector() const { return m_bpb.reserved_sector_count; }
|
||||||
|
|
||||||
|
uint8_t bits_per_fat_entry() const { return static_cast<uint8_t>(m_type); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::RefPtr<BlockDevice> m_block_device;
|
BAN::RefPtr<BlockDevice> m_block_device;
|
||||||
BAN::RefPtr<FATInode> m_root_inode;
|
BAN::RefPtr<FATInode> m_root_inode;
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace Kernel
|
||||||
virtual dev_t dev() const override { return 0; }
|
virtual dev_t dev() const override { return 0; }
|
||||||
virtual dev_t rdev() const override { return 0; }
|
virtual dev_t rdev() const override { return 0; }
|
||||||
|
|
||||||
|
virtual const FileSystem* filesystem() const override;
|
||||||
|
|
||||||
const FAT::DirectoryEntry& entry() const { return m_entry; }
|
const FAT::DirectoryEntry& entry() const { return m_entry; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -9,6 +9,18 @@ namespace Kernel
|
||||||
class FileSystem : public BAN::RefCounted<FileSystem>
|
class FileSystem : public BAN::RefCounted<FileSystem>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual unsigned long bsize() const = 0;
|
||||||
|
virtual unsigned long frsize() const = 0;
|
||||||
|
virtual fsblkcnt_t blocks() const = 0;
|
||||||
|
virtual fsblkcnt_t bfree() const = 0;
|
||||||
|
virtual fsblkcnt_t bavail() const = 0;
|
||||||
|
virtual fsfilcnt_t files() const = 0;
|
||||||
|
virtual fsfilcnt_t ffree() const = 0;
|
||||||
|
virtual fsfilcnt_t favail() const = 0;
|
||||||
|
virtual unsigned long fsid() const = 0;
|
||||||
|
virtual unsigned long flag() const = 0;
|
||||||
|
virtual unsigned long namemax() const = 0;
|
||||||
|
|
||||||
virtual ~FileSystem() {}
|
virtual ~FileSystem() {}
|
||||||
|
|
||||||
static BAN::ErrorOr<BAN::RefPtr<FileSystem>> from_block_device(BAN::RefPtr<BlockDevice>);
|
static BAN::ErrorOr<BAN::RefPtr<FileSystem>> from_block_device(BAN::RefPtr<BlockDevice>);
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class FileSystem;
|
||||||
|
|
||||||
class FileBackedRegion;
|
class FileBackedRegion;
|
||||||
class SharedFileData;
|
class SharedFileData;
|
||||||
|
|
||||||
|
@ -86,6 +88,8 @@ namespace Kernel
|
||||||
virtual bool is_pipe() const { return false; }
|
virtual bool is_pipe() const { return false; }
|
||||||
virtual bool is_tty() const { return false; }
|
virtual bool is_tty() const { return false; }
|
||||||
|
|
||||||
|
virtual const FileSystem* filesystem() const = 0;
|
||||||
|
|
||||||
// Directory API
|
// Directory API
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode(BAN::StringView);
|
BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode(BAN::StringView);
|
||||||
BAN::ErrorOr<size_t> list_next_inodes(off_t, struct dirent* list, size_t list_size);
|
BAN::ErrorOr<size_t> list_next_inodes(off_t, struct dirent* list, size_t list_size);
|
||||||
|
|
|
@ -30,6 +30,8 @@ namespace Kernel
|
||||||
virtual dev_t dev() const override { return 0; } // FIXME
|
virtual dev_t dev() const override { return 0; } // FIXME
|
||||||
virtual dev_t rdev() const override { return 0; } // FIXME
|
virtual dev_t rdev() const override { return 0; } // FIXME
|
||||||
|
|
||||||
|
virtual const FileSystem* filesystem() const override { return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
||||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace Kernel
|
||||||
dev_t dev() const final override { ASSERT_NOT_REACHED(); }
|
dev_t dev() const final override { ASSERT_NOT_REACHED(); }
|
||||||
dev_t rdev() const final override { ASSERT_NOT_REACHED(); }
|
dev_t rdev() const final override { ASSERT_NOT_REACHED(); }
|
||||||
|
|
||||||
|
const FileSystem* filesystem() const final override { return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Socket(const Info& info)
|
Socket(const Info& info)
|
||||||
: m_info(info)
|
: m_info(info)
|
||||||
|
|
|
@ -40,6 +40,19 @@ namespace Kernel
|
||||||
static constexpr size_t no_page_limit = SIZE_MAX;
|
static constexpr size_t no_page_limit = SIZE_MAX;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// FIXME: basically all of these :)
|
||||||
|
virtual unsigned long bsize() const override { return PAGE_SIZE; }
|
||||||
|
virtual unsigned long frsize() const override { return PAGE_SIZE; }
|
||||||
|
virtual fsblkcnt_t blocks() const override { return m_max_pages; }
|
||||||
|
virtual fsblkcnt_t bfree() const override { return m_max_pages - m_used_pages; }
|
||||||
|
virtual fsblkcnt_t bavail() const override { return m_max_pages - m_used_pages; }
|
||||||
|
virtual fsfilcnt_t files() const override { return PAGE_SIZE * blocks() / sizeof(TmpDirectoryEntry); }
|
||||||
|
virtual fsfilcnt_t ffree() const override { return PAGE_SIZE * bfree() / sizeof(TmpDirectoryEntry); }
|
||||||
|
virtual fsfilcnt_t favail() const override { return PAGE_SIZE * bavail() / sizeof(TmpDirectoryEntry); }
|
||||||
|
virtual unsigned long fsid() const override { return reinterpret_cast<uintptr_t>(this); }
|
||||||
|
virtual unsigned long flag() const override { return 0; }
|
||||||
|
virtual unsigned long namemax() const override { return PAGE_SIZE; }
|
||||||
|
|
||||||
static BAN::ErrorOr<TmpFileSystem*> create(size_t max_pages, mode_t, uid_t, gid_t);
|
static BAN::ErrorOr<TmpFileSystem*> create(size_t max_pages, mode_t, uid_t, gid_t);
|
||||||
~TmpFileSystem();
|
~TmpFileSystem();
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ namespace Kernel
|
||||||
static BAN::ErrorOr<BAN::RefPtr<TmpInode>> create_from_existing(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
static BAN::ErrorOr<BAN::RefPtr<TmpInode>> create_from_existing(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
||||||
~TmpInode();
|
~TmpInode();
|
||||||
|
|
||||||
|
virtual const FileSystem* filesystem() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TmpInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
TmpInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,22 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
class VirtualFileSystem : public FileSystem
|
class VirtualFileSystem final : public FileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual unsigned long bsize() const override { return 0; }
|
||||||
|
virtual unsigned long frsize() const override { return 0; }
|
||||||
|
virtual fsblkcnt_t blocks() const override { return 0; }
|
||||||
|
virtual fsblkcnt_t bfree() const override { return 0; }
|
||||||
|
virtual fsblkcnt_t bavail() const override { return 0; }
|
||||||
|
virtual fsfilcnt_t files() const override { return 0; }
|
||||||
|
virtual fsfilcnt_t ffree() const override { return 0; }
|
||||||
|
virtual fsfilcnt_t favail() const override { return 0; }
|
||||||
|
virtual unsigned long fsid() const override { return 0; }
|
||||||
|
virtual unsigned long flag() const override { return 0; }
|
||||||
|
virtual unsigned long namemax() const override { return 0; }
|
||||||
|
|
||||||
|
|
||||||
static void initialize(BAN::StringView);
|
static void initialize(BAN::StringView);
|
||||||
static VirtualFileSystem& get();
|
static VirtualFileSystem& get();
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
|
@ -147,6 +148,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_fsync(int fd);
|
BAN::ErrorOr<long> sys_fsync(int fd);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_fstatat(int fd, const char* path, struct stat* buf, int flag);
|
BAN::ErrorOr<long> sys_fstatat(int fd, const char* path, struct stat* buf, int flag);
|
||||||
|
BAN::ErrorOr<long> sys_fstatvfsat(int fd, const char* path, struct statvfs* buf);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_realpath(const char* path, char* buffer);
|
BAN::ErrorOr<long> sys_realpath(const char* path, char* buffer);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,18 @@ namespace Kernel
|
||||||
return superblock.magic == Ext2::Enum::SUPER_MAGIC;
|
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)
|
BAN::ErrorOr<BAN::RefPtr<Ext2FS>> Ext2FS::create(BAN::RefPtr<BlockDevice> block_device)
|
||||||
{
|
{
|
||||||
auto ext2fs = TRY(BAN::RefPtr<Ext2FS>::create(block_device));
|
auto ext2fs = TRY(BAN::RefPtr<Ext2FS>::create(block_device));
|
||||||
|
|
|
@ -47,6 +47,11 @@ namespace Kernel
|
||||||
dwarnln("Could not cleanup inode from FS: {}", ret.error());
|
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)
|
BAN::ErrorOr<BAN::Optional<uint32_t>> Ext2Inode::block_from_indirect_block(uint32_t block, uint32_t index, uint32_t depth)
|
||||||
{
|
{
|
||||||
if (block == 0)
|
if (block == 0)
|
||||||
|
|
|
@ -64,6 +64,18 @@ namespace Kernel
|
||||||
return validate_bpb(bpb_span.as<const FAT::BPB>());
|
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)
|
BAN::ErrorOr<BAN::RefPtr<FATFS>> FATFS::create(BAN::RefPtr<BlockDevice> block_device)
|
||||||
{
|
{
|
||||||
// support only block devices with sectors at least 512 bytes
|
// support only block devices with sectors at least 512 bytes
|
||||||
|
@ -226,7 +238,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
if (index >= root_sector_count())
|
if (index >= root_sector_count())
|
||||||
return BAN::Error::from_errno(ENOENT);
|
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));
|
TRY(m_block_device->read_blocks(first_root_sector + index, 1, buffer));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ namespace Kernel
|
||||||
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
|
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)
|
BAN::ErrorOr<void> FATInode::for_each_directory_entry(BAN::ConstByteSpan entry_span, BAN::Function<BAN::Iteration(const FAT::DirectoryEntry&)> callback)
|
||||||
{
|
{
|
||||||
ASSERT(mode().ifdir());
|
ASSERT(mode().ifdir());
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace Kernel
|
||||||
|
|
||||||
/* GENERAL INODE */
|
/* GENERAL INODE */
|
||||||
|
|
||||||
|
const FileSystem* TmpInode::filesystem() const
|
||||||
|
{
|
||||||
|
return &m_fs;
|
||||||
|
}
|
||||||
|
|
||||||
dev_t TmpInode::dev() const
|
dev_t TmpInode::dev() const
|
||||||
{
|
{
|
||||||
return m_fs.dev();
|
return m_fs.dev();
|
||||||
|
|
|
@ -1496,6 +1496,35 @@ namespace Kernel
|
||||||
return 0;
|
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)
|
BAN::ErrorOr<long> Process::sys_realpath(const char* path, char* buffer)
|
||||||
{
|
{
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
|
|
|
@ -32,6 +32,7 @@ set(LIBC_SOURCES
|
||||||
sys/select.cpp
|
sys/select.cpp
|
||||||
sys/socket.cpp
|
sys/socket.cpp
|
||||||
sys/stat.cpp
|
sys/stat.cpp
|
||||||
|
sys/statvfs.cpp
|
||||||
sys/time.cpp
|
sys/time.cpp
|
||||||
sys/utsname.cpp
|
sys/utsname.cpp
|
||||||
sys/wait.cpp
|
sys/wait.cpp
|
||||||
|
|
|
@ -48,6 +48,7 @@ __BEGIN_DECLS
|
||||||
O(SYS_FCNTL, fcntl) \
|
O(SYS_FCNTL, fcntl) \
|
||||||
O(SYS_NANOSLEEP, nanosleep) \
|
O(SYS_NANOSLEEP, nanosleep) \
|
||||||
O(SYS_FSTATAT, fstatat) \
|
O(SYS_FSTATAT, fstatat) \
|
||||||
|
O(SYS_FSTATVFSAT, fstatvfsat) \
|
||||||
O(SYS_SYNC, sync) \
|
O(SYS_SYNC, sync) \
|
||||||
O(SYS_MMAP, mmap) \
|
O(SYS_MMAP, mmap) \
|
||||||
O(SYS_MUNMAP, munmap) \
|
O(SYS_MUNMAP, munmap) \
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
static int fstatvfsat(int fildes, const char* path, struct statvfs* buf)
|
||||||
|
{
|
||||||
|
return syscall(SYS_FSTATVFSAT, fildes, path, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fstatvfs(int fildes, struct statvfs* buf)
|
||||||
|
{
|
||||||
|
return fstatvfsat(fildes, nullptr, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int statvfs(const char* __restrict path, struct statvfs* __restrict buf)
|
||||||
|
{
|
||||||
|
return fstatvfsat(AT_FDCWD, path, buf);
|
||||||
|
}
|
Loading…
Reference in New Issue