mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 10:22:05 -05:00
631447da57
In particular, fstatvfs used to assume that a file that was earlier opened using some path will forever be at that path. This is wrong, and in the meantime new mounts and new filesystems could take up the filename or directories, leading to a completely inaccurate result. This commit improves the situation: - All filesystem information is now always accurate. - The mount flags *might* be erroneously zero, if the custody for the open file is not available. I don't know when that might happen, but it is definitely not the typical case.
69 lines
2 KiB
C++
69 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2021, Justin Mietzner <sw1tchbl4d3@sw1tchbl4d3.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/FileSystem/Custody.h>
|
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
|
#include <Kernel/Process.h>
|
|
|
|
namespace Kernel {
|
|
|
|
ErrorOr<FlatPtr> Process::do_statvfs(FileSystem const& fs, Custody const* custody, statvfs* buf)
|
|
{
|
|
statvfs kernelbuf = {};
|
|
|
|
kernelbuf.f_bsize = static_cast<u64>(fs.block_size());
|
|
kernelbuf.f_frsize = fs.fragment_size();
|
|
kernelbuf.f_blocks = fs.total_block_count();
|
|
kernelbuf.f_bfree = fs.free_block_count();
|
|
|
|
// FIXME: Implement "available blocks" into Filesystem
|
|
kernelbuf.f_bavail = fs.free_block_count();
|
|
|
|
kernelbuf.f_files = fs.total_inode_count();
|
|
kernelbuf.f_ffree = fs.free_inode_count();
|
|
kernelbuf.f_favail = fs.free_inode_count(); // FIXME: same as f_bavail
|
|
|
|
kernelbuf.f_fsid = 0; // FIXME: Implement "Filesystem ID" into Filesystem
|
|
|
|
kernelbuf.f_namemax = 255;
|
|
|
|
if (custody)
|
|
kernelbuf.f_flag = custody->mount_flags();
|
|
|
|
TRY(copy_to_user(buf, &kernelbuf));
|
|
return 0;
|
|
}
|
|
|
|
ErrorOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
|
|
{
|
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
|
REQUIRE_PROMISE(rpath);
|
|
auto params = TRY(copy_typed_from_user(user_params));
|
|
|
|
auto path = TRY(get_syscall_path_argument(params.path));
|
|
|
|
auto custody = TRY(VirtualFileSystem::the().resolve_path(path->view(), current_directory(), nullptr, 0));
|
|
auto& inode = custody->inode();
|
|
auto const& fs = inode.fs();
|
|
|
|
return do_statvfs(fs, custody, params.buf);
|
|
}
|
|
|
|
ErrorOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf)
|
|
{
|
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
|
REQUIRE_PROMISE(stdio);
|
|
|
|
auto description = TRY(fds().open_file_description(fd));
|
|
auto inode = description->inode();
|
|
if (inode == nullptr)
|
|
return ENOENT;
|
|
|
|
// FIXME: The custody that we pass in might be outdated. However, this only affects the mount flags.
|
|
return do_statvfs(inode->fs(), description->custody(), buf);
|
|
}
|
|
|
|
}
|