1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 06:04:57 +00:00

LibFileSystem: Add a helper to get the size of a block device

This commit is contained in:
implicitfield 2024-01-16 14:08:57 +04:00 committed by Andrew Kaster
parent a70d79ff98
commit 8384bb138e
2 changed files with 53 additions and 1 deletions

View file

@ -12,8 +12,12 @@
#include <LibFileSystem/FileSystem.h>
#include <limits.h>
#ifdef AK_OS_SERENITY
#if defined(AK_OS_SERENITY)
# include <serenity.h>
#elif defined(AK_OS_BSD_GENERIC)
# include <sys/disk.h>
#elif defined(AK_OS_LINUX)
# include <linux/fs.h>
#endif
// On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it
@ -362,6 +366,52 @@ ErrorOr<off_t> size_from_fstat(int fd)
return st.st_size;
}
ErrorOr<off_t> block_device_size_from_ioctl(StringView path)
{
if (!path.characters_without_null_termination())
return Error::from_syscall("ioctl"sv, -EFAULT);
ByteString path_string = path;
int fd = open(path_string.characters(), O_RDONLY);
if (fd < 0)
return Error::from_errno(errno);
off_t size = TRY(block_device_size_from_ioctl(fd));
if (close(fd) != 0)
return Error::from_errno(errno);
return size;
}
ErrorOr<off_t> block_device_size_from_ioctl(int fd)
{
#if defined(AK_OS_SERENITY)
u64 size = 0;
TRY(Core::System::ioctl(fd, STORAGE_DEVICE_GET_SIZE, &size));
return static_cast<off_t>(size);
#elif defined(AK_OS_MACOS)
u64 block_count = 0;
u32 block_size = 0;
TRY(Core::System::ioctl(fd, DKIOCGETBLOCKCOUNT, &block_count));
TRY(Core::System::ioctl(fd, DKIOCGETBLOCKSIZE, &block_size));
return static_cast<off_t>(block_count * block_size);
#elif defined(AK_OS_FREEBSD) || defined(AK_OS_NETBSD)
off_t size = 0;
TRY(Core::System::ioctl(fd, DIOCGMEDIASIZE, &size));
return size;
#elif defined(AK_OS_LINUX)
u64 size = 0;
TRY(Core::System::ioctl(fd, BLKGETSIZE64, &size));
return static_cast<off_t>(size);
#else
// FIXME: Add support for more platforms.
(void)fd;
return Error::from_string_literal("Platform does not support getting block device size");
#endif
}
bool can_delete_or_move(StringView path)
{
VERIFY(!path.is_empty());

View file

@ -73,6 +73,8 @@ ErrorOr<void> move_file(StringView destination_path, StringView source_path, Pre
ErrorOr<void> remove(StringView path, RecursionMode);
ErrorOr<off_t> size_from_stat(StringView path);
ErrorOr<off_t> size_from_fstat(int fd);
ErrorOr<off_t> block_device_size_from_ioctl(StringView path);
ErrorOr<off_t> block_device_size_from_ioctl(int fd);
bool can_delete_or_move(StringView path);
ErrorOr<ByteString> read_link(StringView link_path);