mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 12:38:38 -10:00
For the moment, this only considers the size of files' content without counting the inodes' cost. While being imprecise, this should already give a pretty good estimate of the RAM usage caused by these filesystems. The value for LOGICAL_BLOCK_SIZE is quite arbitrary as the filesystem doesn't have blocks, so it's only used as a unit (counting in KiB instead of bytes). For the moment, the default maximum size is set to zero (disabled), so no limits are enforced, it just reports the number of used blocks.
100 lines
2.6 KiB
C++
100 lines
2.6 KiB
C++
/*
|
|
* Copyright (c) 2019-2020, Sergey Bugaev <[email protected]>
|
|
* Copyright (c) 2022-2024, Liav A. <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/FileSystem/RAMBackedFileType.h>
|
|
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
|
|
#include <Kernel/FileSystem/RAMFS/Inode.h>
|
|
|
|
namespace Kernel {
|
|
|
|
ErrorOr<NonnullRefPtr<FileSystem>> RAMFS::try_create(FileSystemSpecificOptions const&)
|
|
{
|
|
return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) RAMFS));
|
|
}
|
|
|
|
RAMFS::RAMFS() = default;
|
|
RAMFS::~RAMFS() = default;
|
|
|
|
ErrorOr<void> RAMFS::initialize()
|
|
{
|
|
set_logical_block_size(LOGICAL_BLOCK_SIZE);
|
|
set_fragment_size(LOGICAL_BLOCK_SIZE);
|
|
m_root_inode = TRY(RAMFSInode::try_create_root(*this));
|
|
return {};
|
|
}
|
|
|
|
Inode& RAMFS::root_inode()
|
|
{
|
|
VERIFY(!m_root_inode.is_null());
|
|
return *m_root_inode;
|
|
}
|
|
|
|
ErrorOr<void> RAMFS::rename(Inode& old_parent_inode, StringView old_basename, Inode& new_parent_inode, StringView new_basename)
|
|
{
|
|
MutexLocker locker(m_lock);
|
|
|
|
if (auto maybe_inode_to_be_replaced = new_parent_inode.lookup(new_basename); !maybe_inode_to_be_replaced.is_error()) {
|
|
VERIFY(!maybe_inode_to_be_replaced.value()->is_directory());
|
|
TRY(new_parent_inode.remove_child(new_basename));
|
|
}
|
|
|
|
auto old_inode = TRY(old_parent_inode.lookup(old_basename));
|
|
|
|
TRY(new_parent_inode.add_child(old_inode, new_basename, old_inode->mode()));
|
|
TRY(old_parent_inode.remove_child(old_basename));
|
|
|
|
return {};
|
|
}
|
|
|
|
unsigned RAMFS::next_inode_index()
|
|
{
|
|
MutexLocker locker(m_lock);
|
|
|
|
return m_next_inode_index++;
|
|
}
|
|
|
|
u8 RAMFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const
|
|
{
|
|
return ram_backed_file_type_to_directory_entry_type(entry);
|
|
}
|
|
|
|
ErrorOr<void> RAMFS::update_size(i64 delta)
|
|
{
|
|
SpinlockLocker locker(m_size_lock);
|
|
|
|
auto would_overflow = Checked<decltype(m_current_size)>::addition_would_overflow(m_current_size, delta);
|
|
if (m_maximum_size > 0 && (would_overflow || m_current_size + delta > m_maximum_size))
|
|
return Error::from_errno(ENOSPC);
|
|
|
|
m_current_size += delta;
|
|
return {};
|
|
}
|
|
|
|
u32 RAMFS::total_block_count_impl() const
|
|
{
|
|
VERIFY(m_size_lock.is_locked());
|
|
if (m_maximum_size == 0)
|
|
return ceil_div(m_current_size, LOGICAL_BLOCK_SIZE);
|
|
return ceil_div(m_maximum_size, LOGICAL_BLOCK_SIZE);
|
|
}
|
|
|
|
unsigned RAMFS::total_block_count() const
|
|
{
|
|
SpinlockLocker locker(m_size_lock);
|
|
return total_block_count_impl();
|
|
}
|
|
|
|
unsigned RAMFS::free_block_count() const
|
|
{
|
|
SpinlockLocker locker(m_size_lock);
|
|
if (m_maximum_size == 0)
|
|
return 0;
|
|
return total_block_count_impl() - ceil_div(m_current_size, LOGICAL_BLOCK_SIZE);
|
|
}
|
|
|
|
}
|