Kernel: Add FIBMAP ioctl to Ext2FileSystem

FIBMAP is a linux ioctl that gives the location on disk of a specific
block of a file
This commit is contained in:
Peter Elliott 2021-01-30 13:12:49 -07:00 committed by Andreas Kling
parent e8aae033f1
commit c0e88b9710
Notes: sideshowbarker 2024-07-18 22:43:13 +09:00
6 changed files with 53 additions and 1 deletions

View File

@ -1694,6 +1694,19 @@ KResult Ext2FSInode::truncate(u64 size)
return KSuccess;
}
KResultOr<int> Ext2FSInode::get_block_address(int index)
{
LOCKER(m_lock);
if (m_block_list.is_empty())
m_block_list = fs().block_list_for_inode(m_raw_inode);
if (index < 0 || (size_t)index >= m_block_list.size())
return 0;
return m_block_list[index];
}
unsigned Ext2FS::total_block_count() const
{
LOCKER(m_lock);

View File

@ -77,6 +77,8 @@ private:
virtual KResult chown(uid_t, gid_t) override;
virtual KResult truncate(u64) override;
virtual KResultOr<int> get_block_address(int) override;
bool write_directory(const Vector<Ext2FSDirectoryEntry>&);
bool populate_lookup_cache() const;
KResult resize(u64);

View File

@ -85,6 +85,8 @@ public:
virtual KResult truncate(u64) { return KSuccess; }
virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0) const;
virtual KResultOr<int> get_block_address(int) { return -ENOTSUP; }
LocalSocket* socket() { return m_socket.ptr(); }
const LocalSocket* socket() const { return m_socket.ptr(); }
bool bind_socket(LocalSocket&);

View File

@ -32,6 +32,8 @@
#include <Kernel/Process.h>
#include <Kernel/VM/PrivateInodeVMObject.h>
#include <Kernel/VM/SharedInodeVMObject.h>
#include <LibC/errno_numbers.h>
#include <LibC/sys/ioctl_numbers.h>
namespace Kernel {
@ -69,6 +71,36 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, size_t offset,
return nwritten;
}
int InodeFile::ioctl(FileDescription& description, unsigned request, FlatPtr arg)
{
(void)description;
switch (request) {
case FIBMAP: {
if (!Process::current()->is_superuser())
return -EPERM;
int block_number = 0;
if (!copy_from_user(&block_number, (int*)arg))
return -EFAULT;
if (block_number < 0)
return -EINVAL;
auto block_address = inode().get_block_address(block_number);
if (block_address.is_error())
return block_address.error();
if (!copy_to_user((int*)arg, &block_address.value()))
return -EFAULT;
return 0;
}
default:
return -EINVAL;
}
}
KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& description, const Range& range, size_t offset, int prot, bool shared)
{
// FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec.

View File

@ -49,6 +49,7 @@ public:
virtual KResultOr<size_t> read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override;
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override;
virtual KResultOr<Region*> mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared) override;
virtual String absolute_path(const FileDescription&) const override;

View File

@ -67,7 +67,8 @@ enum IOCtlNumber {
SIOCGIFHWADDR,
SIOCSIFNETMASK,
SIOCADDRT,
SIOCDELRT
SIOCDELRT,
FIBMAP
};
#define TIOCGPGRP TIOCGPGRP
@ -92,3 +93,4 @@ enum IOCtlNumber {
#define SIOCSIFNETMASK SIOCSIFNETMASK
#define SIOCADDRT SIOCADDRT
#define SIOCDELRT SIOCDELRT
#define FIBMAP FIBMAP