Kernel: Changed stat values from func to be field

- Removed virtual functions for all of the stat stuff.
This did however introduce some issues, mainly with /proc
becoming out of sync if you changed your ID. I propose we
do the linux thing and just have a stat update function
which is optional, but allows dynamic updates of stat fields
for cases such as those in uid/gid in /proc.
- Simplified the API, although still kind of annoying
it is a bit simpler.
- Moved some of the FS structure from having the FS inode inside
the in memory inode to a Serialise <-> Deserialise model where
Inodes are deserialised from disk into in memory ones and then
back into on disk ones when it comes time for syncing.
This makes it semantically better in my opinion, as it explicitly
separates disk and non-disk functionality.
This commit is contained in:
2026-05-15 20:39:51 +03:00
committed by Bananymous
parent bf2121e166
commit 647d6a273d
47 changed files with 393 additions and 419 deletions

View File

@@ -14,7 +14,6 @@ namespace Kernel
public:
static BAN::ErrorOr<void> create(PCI::Device& pci_device);
dev_t rdev() const override { return m_rdev; }
BAN::StringView name() const override { return m_name; }
protected:
@@ -51,7 +50,6 @@ namespace Kernel
snd_volume_info m_volume_info {};
private:
const dev_t m_rdev;
char m_name[10] {};
};

View File

@@ -8,15 +8,14 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<DebugDevice>> create(mode_t, uid_t, gid_t);
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return "debug"_sv; }
protected:
DebugDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev)
: CharacterDevice(mode, uid, gid)
, m_rdev(rdev)
{ }
{
m_rdev = rdev;
}
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override { return 0; }
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override;
@@ -25,9 +24,6 @@ namespace Kernel
virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
const dev_t m_rdev;
};
}

View File

@@ -22,8 +22,6 @@ namespace Kernel
return BAN::Error::from_errno(ENOTSUP);
}
virtual dev_t rdev() const override = 0;
virtual BAN::StringView name() const = 0;
protected:
@@ -45,7 +43,7 @@ namespace Kernel
BlockDevice(mode_t mode, uid_t uid, gid_t gid)
: Device(mode, uid, gid)
{
m_inode_info.mode |= Inode::Mode::IFBLK;
m_mode |= Inode::Mode::IFBLK;
}
};
@@ -55,7 +53,7 @@ namespace Kernel
CharacterDevice(mode_t mode, uid_t uid, gid_t gid)
: Device(mode, uid, gid)
{
m_inode_info.mode |= Inode::Mode::IFCHR;
m_mode |= Inode::Mode::IFCHR;
}
};

View File

@@ -30,7 +30,6 @@ namespace Kernel
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t, int status_flags) override;
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name.sv(); }
protected:
@@ -50,7 +49,6 @@ namespace Kernel
private:
const BAN::String m_name;
const dev_t m_rdev;
vaddr_t m_video_memory_vaddr { 0 };
const paddr_t m_video_memory_paddr;

View File

@@ -10,15 +10,14 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<NullDevice>> create(mode_t, uid_t, gid_t);
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return "null"_sv; }
protected:
NullDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev)
: CharacterDevice(mode, uid, gid)
, m_rdev(rdev)
{ }
{
m_rdev = rdev;
}
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override { return 0; }
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); };
@@ -28,8 +27,6 @@ namespace Kernel
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
const dev_t m_rdev;
};
}

View File

@@ -8,15 +8,14 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<RandomDevice>> create(mode_t, uid_t, gid_t);
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return "random"_sv; }
protected:
RandomDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev)
: CharacterDevice(mode, uid, gid)
, m_rdev(rdev)
{ }
{
m_rdev = rdev;
}
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); };
@@ -25,9 +24,6 @@ namespace Kernel
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
const dev_t m_rdev;
};
}

View File

@@ -8,15 +8,14 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<ZeroDevice>> create(mode_t, uid_t, gid_t);
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return "zero"_sv; }
protected:
ZeroDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev)
: CharacterDevice(mode, uid, gid)
, m_rdev(rdev)
{ }
{
m_rdev = rdev;
}
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); };
@@ -25,9 +24,6 @@ namespace Kernel
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
const dev_t m_rdev;
};
}

View File

@@ -21,23 +21,23 @@ namespace Kernel
void notify(BAN::RefPtr<Inode> inode, uint32_t event);
private:
Epoll() = default;
Epoll() {
m_ino = 0;
m_mode = Mode::IRUSR | Mode::IWUSR;
m_nlink = 0;
m_uid = 0;
m_gid = 0;
m_size = 0;
m_atime = {};
m_mtime = {};
m_ctime = {};
m_blksize = PAGE_SIZE;
m_blocks = 0;
m_dev = 0;
m_rdev = 0;
}
public:
ino_t ino() const override { return 0; }
Mode mode() const override { return { Mode::IRUSR | Mode::IWUSR }; }
nlink_t nlink() const override { return 0; }
uid_t uid() const override { return 0; }
gid_t gid() const override { return 0; }
off_t size() const override { return 0; }
timespec atime() const override { return {}; }
timespec mtime() const override { return {}; }
timespec ctime() const override { return {}; }
blksize_t blksize() const override { return PAGE_SIZE; }
blkcnt_t blocks() const override { return 0; }
dev_t dev() const override { return 0; }
dev_t rdev() const override { return 0; }
bool is_epoll() const override { return true; }
const FileSystem* filesystem() const override { return nullptr; }

View File

@@ -11,20 +11,6 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<Inode>> create(uint64_t initval, bool semaphore);
ino_t ino() const override { return 0; }
Mode mode() const override { return { Mode::IFCHR | Mode::IRUSR | Mode::IWUSR }; }
nlink_t nlink() const override { return ref_count(); }
uid_t uid() const override { return 0; }
gid_t gid() const override { return 0; }
off_t size() const override { return 0; }
timespec atime() const override { return {}; }
timespec mtime() const override { return {}; }
timespec ctime() const override { return {}; }
blksize_t blksize() const override { return 8; }
blkcnt_t blocks() const override { return 0; }
dev_t dev() const override { return 0; }
dev_t rdev() const override { return 0; }
const FileSystem* filesystem() const override { return nullptr; }
protected:
@@ -41,7 +27,21 @@ namespace Kernel
EventFD(uint64_t initval, bool is_semaphore)
: m_is_semaphore(is_semaphore)
, m_value(initval)
{ }
{
m_ino = 0;
m_mode = { Mode::IFCHR | Mode::IRUSR | Mode::IWUSR };
m_nlink = 0;
m_uid = 0;
m_gid = 0;
m_size = 0;
m_atime = {};
m_mtime = {};
m_ctime = {};
m_blksize = 8;
m_blocks = 0;
m_dev = 0;
m_rdev = 0;
}
private:
const bool m_is_semaphore;

View File

@@ -79,6 +79,12 @@ namespace Kernel::Ext2
uint8_t __reserved[12];
};
struct InodeBlocks {
uint32_t block[15];
};
struct Osd2 {
uint32_t osd2[3];
};
struct Inode
{
uint16_t mode;
@@ -93,12 +99,12 @@ namespace Kernel::Ext2
uint32_t blocks;
uint32_t flags;
uint32_t osd1;
uint32_t block[15];
InodeBlocks block;
uint32_t generation;
uint32_t file_acl;
uint32_t dir_acl;
uint32_t faddr;
uint32_t osd2[3];
Osd2 osd2;
};
struct LinkedDirectoryEntry

View File

@@ -16,6 +16,7 @@ namespace Kernel
public:
~Ext2Inode();
#if 0
virtual ino_t ino() const override { return m_ino; };
virtual Mode mode() const override { return { m_inode.mode }; }
virtual nlink_t nlink() const override { return m_inode.links_count; }
@@ -29,6 +30,7 @@ namespace Kernel
virtual blkcnt_t blocks() const override;
virtual dev_t dev() const override { return 0; }
virtual dev_t rdev() const override { return 0; }
#endif
virtual const FileSystem* filesystem() const override;
@@ -84,11 +86,8 @@ namespace Kernel
BAN::ErrorOr<void> cleanup_from_fs_no_lock();
private:
Ext2Inode(Ext2FS& fs, Ext2::Inode inode, uint32_t ino)
: m_fs(fs)
, m_inode(inode)
, m_ino(ino)
{}
Ext2Inode(Ext2FS& fs, Ext2::Inode inode, uint32_t ino);
static BAN::ErrorOr<BAN::RefPtr<Ext2Inode>> create(Ext2FS&, uint32_t);
private:
@@ -96,28 +95,35 @@ namespace Kernel
{
ScopedSync(Ext2Inode& inode)
: inode(inode)
, inode_info(inode.m_inode)
{ }
~ScopedSync()
{
if (memcmp(&inode.m_inode, &inode_info, sizeof(Ext2::Inode)) == 0)
return;
// TODO: there was some memcmp smarty pants stuff here.
// How do we wanna approach it?
if (auto ret = inode.sync_no_lock(); ret.is_error())
dwarnln("failed to sync inode: {}", ret.error());
}
Ext2Inode& inode;
Ext2::Inode inode_info;
};
private:
Ext2FS& m_fs;
Ext2::Inode m_inode;
const uint32_t m_ino;
RWLock m_lock;
Ext2::InodeBlocks m_ext2_blocks;
// NOTE: some fields from the original disk inode
// that we do not use, but we keep for serialise.
const uint32_t m_og_dtime;
const uint32_t m_og_flags;
const uint32_t m_og_osd1;
const uint32_t m_og_generation;
const uint32_t m_og_file_acl;
const uint32_t m_og_dir_acl;
const uint32_t m_og_faddr;
const Ext2::Osd2 m_og_osd2;
friend class Ext2FS;
friend class BAN::RefPtr<Ext2Inode>;
};

View File

@@ -15,20 +15,6 @@ namespace Kernel
class FATInode final : public Inode, public BAN::Weakable<FATInode>
{
public:
virtual ino_t ino() const override { return m_ino; };
virtual Mode mode() const override { return Mode { ((m_entry.attr & FAT::FileAttr::DIRECTORY) ? Mode::IFDIR : Mode::IFREG) | 0777 }; }
virtual nlink_t nlink() const override { return 1; }
virtual uid_t uid() const override { return 0; }
virtual gid_t gid() const override { return 0; }
virtual off_t size() const override { return m_entry.file_size; }
virtual timespec atime() const override;
virtual timespec mtime() const override;
virtual timespec ctime() const override;
virtual blksize_t blksize() const override;
virtual blkcnt_t blocks() const override { return m_block_count; }
virtual dev_t dev() 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; }
@@ -53,12 +39,8 @@ namespace Kernel
virtual bool has_hungup_impl() const override { return false; }
private:
FATInode(FATFS& fs, const FAT::DirectoryEntry& entry, ino_t ino, uint32_t block_count)
: m_fs(fs)
, m_entry(entry)
, m_ino(ino)
, m_block_count(block_count)
{ }
FATInode(FATFS& fs, const FAT::DirectoryEntry& entry, ino_t ino, uint32_t block_count);
~FATInode() {}
BAN::ErrorOr<void> for_each_directory_entry(BAN::ConstByteSpan, BAN::Function<BAN::Iteration(const FAT::DirectoryEntry&)>);
@@ -67,7 +49,6 @@ namespace Kernel
private:
FATFS& m_fs;
FAT::DirectoryEntry m_entry;
const ino_t m_ino;
uint32_t m_block_count;
friend class Ext2FS;

View File

@@ -69,19 +69,19 @@ namespace Kernel
bool operator==(const Inode& other) const { return dev() == other.dev() && ino() == other.ino(); }
virtual ino_t ino() const = 0;
virtual Mode mode() const = 0;
virtual nlink_t nlink() const = 0;
virtual uid_t uid() const = 0;
virtual gid_t gid() const = 0;
virtual off_t size() const = 0;
virtual timespec atime() const = 0;
virtual timespec mtime() const = 0;
virtual timespec ctime() const = 0;
virtual blksize_t blksize() const = 0;
virtual blkcnt_t blocks() const = 0;
virtual dev_t dev() const = 0;
virtual dev_t rdev() const = 0;
ino_t ino() const { return m_ino; }
Mode mode() const { return Mode(m_mode); }
nlink_t nlink() const { return m_nlink; }
uid_t uid() const { return m_uid; }
gid_t gid() const { return m_gid; }
off_t size() const { return m_size; }
timespec atime() const { return m_atime; }
timespec mtime() const { return m_mtime; }
timespec ctime() const { return m_ctime; }
blksize_t blksize() const { return m_blksize; }
blkcnt_t blocks() const { return m_blocks; }
dev_t dev() const { return m_dev; }
dev_t rdev() const { return m_rdev; }
virtual bool is_device() const { return false; }
virtual bool is_epoll() const { return false; }
@@ -182,6 +182,21 @@ namespace Kernel
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); }
protected:
BAN::Atomic<ino_t> m_ino;
BAN::Atomic<mode_t> m_mode;
BAN::Atomic<nlink_t> m_nlink;
BAN::Atomic<uid_t> m_uid;
BAN::Atomic<gid_t> m_gid;
BAN::Atomic<off_t> m_size;
// TODO: make these guys atomic :)
timespec m_atime;
timespec m_mtime;
timespec m_ctime;
BAN::Atomic<blksize_t> m_blksize;
BAN::Atomic<blkcnt_t> m_blocks;
BAN::Atomic<dev_t> m_dev;
BAN::Atomic<dev_t> m_rdev;
private:
SpinLock m_shared_region_lock;
BAN::WeakPtr<SharedFileData> m_shared_region;

View File

@@ -18,20 +18,6 @@ namespace Kernel
void on_close(int status_flags) override;
void on_clone(int status_flags) override;
virtual ino_t ino() const override { return 0; } // FIXME
virtual Mode mode() const override { return { Mode::IFIFO | Mode::IRUSR | Mode::IWUSR }; }
virtual nlink_t nlink() const override { return 1; }
virtual uid_t uid() const override { return m_uid; }
virtual gid_t gid() const override { return m_gid; }
virtual off_t size() const override { return 0; }
virtual timespec atime() const override { return m_atime; }
virtual timespec mtime() const override { return m_mtime; }
virtual timespec ctime() const override { return m_ctime; }
virtual blksize_t blksize() const override { return 4096; }
virtual blkcnt_t blocks() const override { return 0; }
virtual dev_t dev() const override { return 0; } // FIXME
virtual dev_t rdev() const override { return 0; } // FIXME
virtual const FileSystem* filesystem() const override { return nullptr; }
protected:
@@ -50,12 +36,6 @@ namespace Kernel
Pipe(const Credentials&);
private:
const uid_t m_uid;
const gid_t m_gid;
timespec m_atime {};
timespec m_mtime {};
timespec m_ctime {};
Mutex m_mutex;
ThreadBlocker m_thread_blocker;

View File

@@ -9,34 +9,27 @@ namespace Kernel
class ProcPidInode final : public TmpDirectoryInode
{
// FIXME: dynamically update ruid/rgid.
// Possibly just have a magic uid/gid of -1 or something
// which means use current process ID
public:
static BAN::ErrorOr<BAN::RefPtr<ProcPidInode>> create_new(Process&, TmpFileSystem&, mode_t);
~ProcPidInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
void cleanup();
protected:
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override { return BAN::Error::from_errno(EPERM); }
private:
ProcPidInode(Process&, TmpFileSystem&, const TmpInodeInfo&);
private:
Process& m_process;
};
class ProcROProcessInode final : public TmpInode
{
//FIXME: dynamically update ruid/rgid
public:
static BAN::ErrorOr<BAN::RefPtr<ProcROProcessInode>> create_new(Process&, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, TmpFileSystem&, mode_t);
~ProcROProcessInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
@@ -59,13 +52,11 @@ namespace Kernel
class ProcSymlinkProcessInode final : public TmpInode
{
//FIXME: dynamically update ruid/rgid
public:
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkProcessInode>> create_new(Process& process, BAN::ErrorOr<BAN::String> (Process::*callback)() const, TmpFileSystem&, mode_t);
~ProcSymlinkProcessInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
@@ -132,13 +123,10 @@ namespace Kernel
class ProcFDDirectoryInode final : public TmpInode
{
//FIXME: dynamically update ruid/rgid
public:
static BAN::ErrorOr<BAN::RefPtr<ProcFDDirectoryInode>> create_new(Process&, TmpFileSystem&, mode_t);
~ProcFDDirectoryInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
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;

View File

@@ -30,31 +30,19 @@ namespace Kernel
};
public:
ino_t ino() const final override { ASSERT_NOT_REACHED(); }
Mode mode() const final override { return Mode(m_info.mode); }
nlink_t nlink() const final override { ASSERT_NOT_REACHED(); }
uid_t uid() const final override { return m_info.uid; }
gid_t gid() const final override { return m_info.gid; }
off_t size() const final override { ASSERT_NOT_REACHED(); }
timespec atime() const final override { ASSERT_NOT_REACHED(); }
timespec mtime() const final override { ASSERT_NOT_REACHED(); }
timespec ctime() const final override { ASSERT_NOT_REACHED(); }
blksize_t blksize() const final override { ASSERT_NOT_REACHED(); }
blkcnt_t blocks() const final override { ASSERT_NOT_REACHED(); }
dev_t dev() const final override { ASSERT_NOT_REACHED(); }
dev_t rdev() const final override { ASSERT_NOT_REACHED(); }
const FileSystem* filesystem() const final override { return nullptr; }
protected:
Socket(const Info& info)
: m_info(info)
{}
{
m_mode = info.mode;
m_uid = info.uid;
m_gid = info.gid;
}
BAN::ErrorOr<void> fsync_impl() final override { return {}; }
private:
const Info m_info;
};
}

View File

@@ -11,18 +11,8 @@
namespace Kernel
{
struct TmpInodeInfo
struct TmpBlocks
{
mode_t mode { 0 };
uid_t uid { 0 };
gid_t gid { 0 };
timespec atime { 0, 0 };
timespec ctime { 0, 0 };
timespec mtime { 0, 0 };
nlink_t nlink { 0 };
size_t size { 0 };
blkcnt_t blocks { 0 };
#if ARCH(x86_64)
// 2x direct blocks
// 1x singly indirect
@@ -41,8 +31,23 @@ namespace Kernel
#else
#error
#endif
};
struct TmpInodeInfo
{
mode_t mode { 0 };
uid_t uid { 0 };
gid_t gid { 0 };
timespec atime { 0, 0 };
timespec ctime { 0, 0 };
timespec mtime { 0, 0 };
nlink_t nlink { 0 };
size_t size { 0 };
blkcnt_t blocks { 0 };
TmpBlocks tmp_blocks;
static constexpr size_t max_size =
direct_block_count * PAGE_SIZE +
TmpBlocks::direct_block_count * PAGE_SIZE +
(PAGE_SIZE / sizeof(paddr_t)) * PAGE_SIZE +
(PAGE_SIZE / sizeof(paddr_t)) * (PAGE_SIZE / sizeof(paddr_t)) * PAGE_SIZE +
(PAGE_SIZE / sizeof(paddr_t)) * (PAGE_SIZE / sizeof(paddr_t)) * (PAGE_SIZE / sizeof(paddr_t)) * PAGE_SIZE;

View File

@@ -24,21 +24,6 @@ namespace Kernel
class TmpInode : public Inode
{
public:
virtual ino_t ino() const override { return m_ino; }
virtual Mode mode() const override { return Mode(m_inode_info.mode); }
virtual nlink_t nlink() const override { return m_inode_info.nlink; }
virtual uid_t uid() const override { return m_inode_info.uid; }
virtual gid_t gid() const override { return m_inode_info.gid; }
virtual off_t size() const override { return m_inode_info.size; }
virtual timespec atime() const override { return m_inode_info.atime; }
virtual timespec mtime() const override { return m_inode_info.mtime; }
virtual timespec ctime() const override { return m_inode_info.ctime; }
virtual blksize_t blksize() const override { return PAGE_SIZE; }
virtual blkcnt_t blocks() const override { return m_inode_info.blocks; }
virtual dev_t dev() const override;
virtual dev_t rdev() const override { return 0; }
public:
static BAN::ErrorOr<BAN::RefPtr<TmpInode>> create_from_existing(TmpFileSystem&, ino_t, const TmpInodeInfo&);
~TmpInode();
@@ -47,7 +32,6 @@ namespace Kernel
protected:
TmpInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) override;
virtual BAN::ErrorOr<void> utimens_impl(const timespec[2]) override;
@@ -67,8 +51,7 @@ namespace Kernel
protected:
TmpFileSystem& m_fs;
TmpInodeInfo m_inode_info;
const ino_t m_ino;
TmpBlocks m_tmp_blocks;
// TODO: try to reduce locking or replace this with rwlock(?)
Mutex m_lock;

View File

@@ -22,8 +22,6 @@ namespace Kernel
InputDevice(Type type);
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
protected:
void add_event(BAN::ConstByteSpan);
@@ -38,8 +36,7 @@ namespace Kernel
BAN::ErrorOr<size_t> read_non_block(BAN::ByteSpan);
private:
const dev_t m_rdev;
const BAN::String m_name;
BAN::String m_name;
const Type m_type;
@@ -77,10 +74,8 @@ namespace Kernel
bool has_hungup_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
private:
const dev_t m_rdev;
const BAN::StringView m_name;
ThreadBlocker m_thread_blocker;
@@ -104,10 +99,7 @@ namespace Kernel
bool has_hungup_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
private:
const dev_t m_rdev;
const BAN::StringView m_name;
ThreadBlocker m_thread_blocker;

View File

@@ -57,7 +57,6 @@ namespace Kernel
virtual size_t payload_mtu() const = 0;
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name; }
BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan payload)
@@ -68,8 +67,6 @@ namespace Kernel
private:
const Type m_type;
const dev_t m_rdev;
char m_name[10];
BAN::IPv4Address m_ipv4_address { 0 };

View File

@@ -31,8 +31,6 @@ namespace Kernel
BAN::StringView model() const { return m_model; }
BAN::StringView name() const override { return m_name; }
dev_t rdev() const override { return m_rdev; }
protected:
ATABaseDevice();
BAN::ErrorOr<void> initialize(BAN::Span<const uint16_t> identify_data);
@@ -46,8 +44,6 @@ namespace Kernel
bool m_has_lba;
char m_model[41];
char m_name[4] {};
const dev_t m_rdev;
};
}

View File

@@ -20,7 +20,6 @@ namespace Kernel
NVMeQueue& io_queue() { return *m_io_queue; }
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name; }
protected:
@@ -51,7 +50,6 @@ namespace Kernel
BAN::Vector<BAN::RefPtr<NVMeNamespace>> m_namespaces;
char m_name[20];
const dev_t m_rdev;
};
}

View File

@@ -16,7 +16,6 @@ namespace Kernel
virtual uint32_t sector_size() const override { return m_block_size; }
virtual uint64_t total_size() const override { return m_block_size * m_block_count; }
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name; }
private:
@@ -35,7 +34,6 @@ namespace Kernel
const uint64_t m_block_count;
char m_name[10] {};
const dev_t m_rdev;
};
}

View File

@@ -45,8 +45,6 @@ namespace Kernel
public:
virtual bool is_partition() const override { return true; }
virtual dev_t rdev() const override { return m_rdev; }
protected:
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
@@ -56,7 +54,6 @@ namespace Kernel
virtual bool has_hungup_impl() const override { return false; }
private:
const dev_t m_rdev;
};
}

View File

@@ -13,7 +13,6 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<PseudoTerminalMaster>> create(mode_t, uid_t, gid_t);
dev_t rdev() const override { return m_rdev; }
BAN::StringView name() const override { return "<ptmx>"_sv; }
BAN::ErrorOr<BAN::RefPtr<PseudoTerminalSlave>> slave();
@@ -48,8 +47,6 @@ namespace Kernel
size_t m_buffer_tail { 0 };
size_t m_buffer_size { 0 };
const dev_t m_rdev;
friend class PseudoTerminalSlave;
friend class BAN::RefPtr<PseudoTerminalMaster>;
};

View File

@@ -51,8 +51,6 @@ namespace Kernel
virtual bool is_tty() const override { return true; }
virtual dev_t rdev() const final override { return m_rdev; }
virtual void clear() = 0;
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
@@ -84,8 +82,6 @@ namespace Kernel
termios get_termios();
private:
const dev_t m_rdev;
BAN::Atomic<pid_t> m_foreground_pgrp { 0 };
struct tty_ctrl_t

View File

@@ -15,7 +15,6 @@ namespace Kernel
uint32_t sector_size() const override { return m_block_size; }
uint64_t total_size() const override { return m_block_size * m_block_count; }
dev_t rdev() const override { return m_rdev; }
BAN::StringView name() const override { return m_name; }
private:
@@ -34,7 +33,6 @@ namespace Kernel
const uint64_t m_block_count;
const uint32_t m_block_size;
const dev_t m_rdev;
const char m_name[4];
friend class BAN::RefPtr<USBSCSIDevice>;

View File

@@ -15,8 +15,8 @@ namespace Kernel
AudioController::AudioController()
: CharacterDevice(0644, 0, 0)
, m_rdev(makedev(DeviceNumber::AudioController, s_next_audio_minor++))
{
m_rdev = makedev(DeviceNumber::AudioController, s_next_audio_minor++);
char* ptr = m_name;
BAN::Formatter::print([&ptr](char c) { *ptr++ = c; }, "audio{}", minor(m_rdev));
}

View File

@@ -52,13 +52,14 @@ namespace Kernel
FramebufferDevice::FramebufferDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev, paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp)
: CharacterDevice(mode, uid, gid)
, m_name(MUST(BAN::String::formatted("fb{}", minor(rdev))))
, m_rdev(rdev)
, m_video_memory_paddr(paddr)
, m_width(width)
, m_height(height)
, m_pitch(pitch)
, m_bpp(bpp)
{ }
{
m_rdev = rdev;
}
FramebufferDevice::~FramebufferDevice()
{

View File

@@ -281,7 +281,7 @@ namespace Kernel
auto& inode = inode_buffer.span().slice(inode_location.offset).as<Ext2::Inode>();
#if EXT2_VERIFY_NO_BLOCKS
static const char zero_buffer[sizeof(inode.block)] {};
ASSERT(memcmp(inode.block, zero_buffer, sizeof(inode.block)) == 0);
ASSERT(memcmp(inode.block.block, zero_buffer, sizeof(inode.block)) == 0);
#endif
bool is_directory = Inode::Mode(inode.mode).ifdir();
memset(&inode, 0x00, m_superblock.inode_size);

View File

@@ -10,14 +10,31 @@
namespace Kernel
{
blksize_t Ext2Inode::blksize() const
Ext2Inode::Ext2Inode(Ext2FS& fs, Ext2::Inode inode, uint32_t ino)
: m_fs(fs)
, m_ext2_blocks(inode.block)
, m_og_dtime(inode.dtime)
, m_og_flags(inode.flags)
, m_og_osd1(inode.osd1)
, m_og_generation(inode.generation)
, m_og_file_acl(inode.file_acl)
, m_og_dir_acl(inode.dir_acl)
, m_og_faddr(inode.faddr)
, m_og_osd2(inode.osd2)
{
return m_fs.block_size();
}
blkcnt_t Ext2Inode::blocks() const
{
return m_inode.blocks / (2 << m_fs.superblock().log_block_size);
m_ino = ino;
m_mode = inode.mode;
m_nlink = inode.links_count;
m_uid = inode.uid;
m_gid = inode.gid;
m_size = inode.size;
m_atime = timespec { .tv_sec = inode.atime, .tv_nsec = 0 };
m_mtime = timespec { .tv_sec = inode.mtime, .tv_nsec = 0 };
m_ctime = timespec { .tv_sec = inode.ctime, .tv_nsec = 0 };
m_dev = 0;
m_rdev = 0;
m_blksize = fs.block_size();
m_blocks = inode.blocks / (2 << fs.superblock().log_block_size);
}
uint32_t Ext2Inode::block_group() const
@@ -45,7 +62,7 @@ namespace Kernel
Ext2Inode::~Ext2Inode()
{
if (m_inode.links_count > 0)
if (m_nlink > 0)
return;
if (auto ret = cleanup_from_fs_no_lock(); ret.is_error())
dwarnln("Could not cleanup inode from FS: {}", ret.error());
@@ -58,7 +75,6 @@ namespace Kernel
BAN::ErrorOr<BAN::Optional<uint32_t>> Ext2Inode::block_from_indirect_block_no_lock(uint32_t& block, uint32_t index, uint32_t depth, bool allocate)
{
const uint32_t inode_blocks_per_fs_block = blksize() / 512;
const uint32_t indices_per_fs_block = blksize() / sizeof(uint32_t);
if (block == 0 && !allocate)
@@ -69,7 +85,7 @@ namespace Kernel
if (block == 0)
{
block = TRY(m_fs.reserve_free_block(block_group()));
m_inode.blocks += inode_blocks_per_fs_block;
m_blocks++;
auto block_buffer = TRY(m_fs.get_block_buffer());
memset(block_buffer.data(), 0x00, block_buffer.size());
@@ -88,7 +104,7 @@ namespace Kernel
else
{
block = TRY(m_fs.reserve_free_block(block_group()));
m_inode.blocks += inode_blocks_per_fs_block;
m_blocks++;
memset(block_buffer.data(), 0, block_buffer.size());
@@ -112,13 +128,12 @@ namespace Kernel
BAN::ErrorOr<BAN::Optional<uint32_t>> Ext2Inode::fs_block_of_data_block_index_no_lock(uint32_t data_block_index, bool allocate)
{
const uint32_t inode_blocks_per_fs_block = blksize() / 512;
const uint32_t indices_per_block = blksize() / sizeof(uint32_t);
if (data_block_index < 12)
{
if (m_inode.block[data_block_index] != 0)
return BAN::Optional<uint32_t>(m_inode.block[data_block_index]);
if (m_ext2_blocks.block[data_block_index] != 0)
return BAN::Optional<uint32_t>(m_ext2_blocks.block[data_block_index]);
if (!allocate)
return BAN::Optional<uint32_t>();
@@ -128,23 +143,23 @@ namespace Kernel
const auto block = TRY(m_fs.reserve_free_block(block_group()));
TRY(m_fs.write_block(block, block_buffer));
m_inode.block[data_block_index] = block;
m_inode.blocks += inode_blocks_per_fs_block;
m_ext2_blocks.block[data_block_index] = block;
m_blocks++;
return BAN::Optional<uint32_t>(block);
}
data_block_index -= 12;
if (data_block_index < indices_per_block)
return block_from_indirect_block_no_lock(m_inode.block[12], data_block_index, 1, allocate);
return block_from_indirect_block_no_lock(m_ext2_blocks.block[12], data_block_index, 1, allocate);
data_block_index -= indices_per_block;
if (data_block_index < indices_per_block * indices_per_block)
return block_from_indirect_block_no_lock(m_inode.block[13], data_block_index, 2, allocate);
return block_from_indirect_block_no_lock(m_ext2_blocks.block[13], data_block_index, 2, allocate);
data_block_index -= indices_per_block * indices_per_block;
if (data_block_index < indices_per_block * indices_per_block * indices_per_block)
return block_from_indirect_block_no_lock(m_inode.block[14], data_block_index, 3, allocate);
return block_from_indirect_block_no_lock(m_ext2_blocks.block[14], data_block_index, 3, allocate);
ASSERT_NOT_REACHED();
}
@@ -155,15 +170,15 @@ namespace Kernel
RWLockRDGuard _(m_lock);
if (m_inode.size < sizeof(m_inode.block))
if (static_cast<size_t>(m_size) < sizeof(m_ext2_blocks.block))
{
BAN::String result;
TRY(result.append(BAN::StringView(reinterpret_cast<const char*>(m_inode.block), m_inode.size)));
TRY(result.append(BAN::StringView(reinterpret_cast<const char*>(m_ext2_blocks.block), m_size)));
return result;
}
BAN::String result;
TRY(result.resize(m_inode.size));
TRY(result.resize(m_size));
TRY(read_impl(0, { reinterpret_cast<uint8_t*>(result.data()), result.size() }));
return BAN::move(result);
}
@@ -173,13 +188,13 @@ namespace Kernel
ASSERT(mode().iflnk());
RWLockWRGuard _(m_lock);
if (target.size() < sizeof(m_inode.block))
if (target.size() < sizeof(m_ext2_blocks.block))
{
if (m_inode.size >= sizeof(m_inode.block))
if (static_cast<size_t>(m_size) >= sizeof(m_ext2_blocks.block))
TRY(cleanup_data_blocks_no_lock());
memset(m_inode.block, 0, sizeof(m_inode.block));
memcpy(m_inode.block, target.data(), target.size());
m_inode.size = target.size();
memset(m_ext2_blocks.block, 0, sizeof(m_ext2_blocks.block));
memcpy(m_ext2_blocks.block, target.data(), target.size());
m_size = target.size();
TRY(sync_no_lock());
return {};
}
@@ -201,14 +216,14 @@ namespace Kernel
RWLockRDGuard _0(m_lock);
if (static_cast<BAN::make_unsigned_t<decltype(offset)>>(offset) >= m_inode.size)
if (static_cast<BAN::make_unsigned_t<decltype(offset)>>(offset) >= static_cast<size_t>(m_size))
return 0;
ScopedSync _1(*this);
uint32_t count = buffer.size();
if (offset + buffer.size() > m_inode.size)
count = m_inode.size - offset;
if (offset + buffer.size() > static_cast<size_t>(m_size))
count = m_size - offset;
const uint32_t block_size = blksize();
@@ -249,7 +264,7 @@ namespace Kernel
RWLockWRGuard _0(m_lock);
if (m_inode.size < offset + buffer.size())
if (static_cast<size_t>(m_size) < offset + buffer.size())
TRY(truncate_impl(offset + buffer.size()));
ScopedSync _(*this);
@@ -311,17 +326,17 @@ namespace Kernel
{
RWLockWRGuard _(m_lock);
if (m_inode.size == new_size)
if (static_cast<size_t>(m_size) == new_size)
return {};
// TODO: we should remove unused blocks on shrink
const auto old_size = m_inode.size;
const auto old_size = static_cast<size_t>(m_size);
m_inode.size = new_size;
m_size = new_size;
if (auto ret = sync_no_lock(); ret.is_error())
{
m_inode.size = old_size;
m_size = old_size;
return ret.release_error();
}
@@ -334,15 +349,15 @@ namespace Kernel
RWLockWRGuard _(m_lock);
if (m_inode.mode == mode)
if (m_mode == mode)
return {};
const auto old_mode = m_inode.mode;
const auto old_mode = m_mode.load();
m_inode.mode = (m_inode.mode & Inode::Mode::TYPE_MASK) | mode;
m_mode = (m_mode & Inode::Mode::TYPE_MASK) | mode;
if (auto ret = sync_no_lock(); ret.is_error())
{
m_inode.mode = old_mode;
m_mode = old_mode;
return ret.release_error();
}
@@ -353,18 +368,18 @@ namespace Kernel
{
RWLockWRGuard _(m_lock);
if (m_inode.uid == uid && m_inode.gid == gid)
if (m_uid == uid && m_gid == gid)
return {};
const auto old_uid = m_inode.uid;
const auto old_gid = m_inode.gid;
const auto old_uid = m_uid.load();
const auto old_gid = m_gid.load();
m_inode.uid = uid;
m_inode.gid = gid;
m_uid = uid;
m_gid = gid;
if (auto ret = sync_no_lock(); ret.is_error())
{
m_inode.uid = old_uid;
m_inode.gid = old_gid;
m_uid = old_uid;
m_gid = old_gid;
return ret.release_error();
}
@@ -376,19 +391,19 @@ namespace Kernel
RWLockWRGuard _(m_lock);
const uint32_t old_times[2] {
m_inode.atime,
m_inode.mtime,
static_cast<uint32_t>(m_atime.tv_sec),
static_cast<uint32_t>(m_mtime.tv_sec),
};
if (times[0].tv_nsec != UTIME_OMIT)
m_inode.atime = times[0].tv_sec;
m_atime.tv_sec = times[0].tv_sec;
if (times[1].tv_nsec != UTIME_OMIT)
m_inode.mtime = times[1].tv_sec;
m_mtime.tv_sec = times[1].tv_sec;
if (auto ret = sync_no_lock(); ret.is_error())
{
m_inode.atime = old_times[0];
m_inode.mtime = old_times[1];
m_atime.tv_sec = old_times[0];
m_mtime.tv_sec = old_times[1];
return ret.release_error();
}
@@ -432,25 +447,25 @@ namespace Kernel
BAN::ErrorOr<void> Ext2Inode::cleanup_data_blocks_no_lock()
{
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
if (mode().iflnk() && (size_t)size() < sizeof(m_ext2_blocks.block))
goto done;
// cleanup direct blocks
for (uint32_t i = 0; i < 12; i++)
if (m_inode.block[i])
TRY(m_fs.release_block(m_inode.block[i]));
if (m_ext2_blocks.block[i])
TRY(m_fs.release_block(m_ext2_blocks.block[i]));
// cleanup indirect blocks
if (m_inode.block[12])
TRY(cleanup_indirect_block_no_lock(m_inode.block[12], 1));
if (m_inode.block[13])
TRY(cleanup_indirect_block_no_lock(m_inode.block[13], 2));
if (m_inode.block[14])
TRY(cleanup_indirect_block_no_lock(m_inode.block[14], 3));
if (m_ext2_blocks.block[12])
TRY(cleanup_indirect_block_no_lock(m_ext2_blocks.block[12], 1));
if (m_ext2_blocks.block[13])
TRY(cleanup_indirect_block_no_lock(m_ext2_blocks.block[13], 2));
if (m_ext2_blocks.block[14])
TRY(cleanup_indirect_block_no_lock(m_ext2_blocks.block[14], 3));
done:
// mark blocks as deleted
memset(m_inode.block, 0x00, sizeof(m_inode.block));
memset(m_ext2_blocks.block, 0x00, sizeof(m_ext2_blocks.block));
TRY(sync_no_lock());
@@ -459,7 +474,7 @@ done:
BAN::ErrorOr<void> Ext2Inode::cleanup_from_fs_no_lock()
{
ASSERT(m_inode.links_count == 0);
ASSERT(m_nlink == 0);
TRY(cleanup_data_blocks_no_lock());
TRY(m_fs.delete_inode(ino()));
return {};
@@ -694,7 +709,7 @@ done:
if (name.size() > 255)
return BAN::Error::from_errno(ENAMETOOLONG);
if (m_inode.flags & Ext2::Enum::INDEX_FL)
if (m_og_flags & Ext2::Enum::INDEX_FL)
{
dwarnln("file creation to indexed directory not supported");
return BAN::Error::from_errno(ENOTSUP);
@@ -731,7 +746,7 @@ done:
new_entry.file_type = file_type;
memcpy(new_entry.name, name.data(), name.size());
inode.m_inode.links_count++;
inode.m_nlink++;
TRY(inode.sync_no_lock());
return {};
@@ -782,7 +797,7 @@ done:
needs_new_block:
block_index = TRY(fs_block_of_data_block_index_no_lock(data_block_count, true)).value();
m_inode.size += blksize();
m_size += blksize();
memset(block_buffer.data(), 0x00, block_buffer.size());
TRY(write_inode(0, block_size));
@@ -830,7 +845,7 @@ needs_new_block:
auto block_buffer = TRY(m_fs.get_block_buffer());
if (m_inode.flags & Ext2::Enum::INDEX_FL)
if (m_og_flags & Ext2::Enum::INDEX_FL)
{
dwarnln("deletion of indexed directory is not supported");
return BAN::Error::from_errno(ENOTSUP);
@@ -856,13 +871,13 @@ needs_new_block:
if (entry_name == "."_sv)
{
m_inode.links_count--;
m_nlink--;
TRY(sync_no_lock());
}
else if (entry_name == ".."_sv)
{
auto parent = TRY(Ext2Inode::create(m_fs, entry.inode));
parent->m_inode.links_count--;
parent->m_nlink--;
TRY(parent->sync_no_lock());
}
else
@@ -888,7 +903,7 @@ needs_new_block:
auto block_buffer = TRY(m_fs.get_block_buffer());
if (m_inode.flags & Ext2::Enum::INDEX_FL)
if (m_og_flags & Ext2::Enum::INDEX_FL)
{
dwarnln("deletion from indexed directory is not supported");
return BAN::Error::from_errno(ENOTSUP);
@@ -918,7 +933,7 @@ needs_new_block:
if (inode->nlink() == 0)
dprintln("Corrupted filesystem. Deleting inode with 0 links");
else
inode->m_inode.links_count--;
inode->m_nlink--;
TRY(sync_no_lock());
@@ -955,9 +970,29 @@ needs_new_block:
auto block_buffer = TRY(m_fs.get_block_buffer());
TRY(m_fs.read_block(inode_location.block, block_buffer));
if (memcmp(block_buffer.data() + inode_location.offset, &m_inode, sizeof(Ext2::Inode)))
Ext2::Inode inode {
.mode = static_cast<uint16_t>(m_mode),
.uid = static_cast<uint16_t>(m_uid),
.size = static_cast<uint32_t>(m_size),
.atime = static_cast<uint32_t>(m_atime.tv_sec),
.ctime = static_cast<uint32_t>(m_ctime.tv_sec),
.mtime = static_cast<uint32_t>(m_mtime.tv_sec),
.dtime = m_og_dtime,
.gid = static_cast<uint16_t>(m_gid),
.links_count = static_cast<uint16_t>(m_nlink),
.blocks = static_cast<uint32_t>(m_blocks * (blksize() / 512)),
.flags = m_og_flags,
.osd1 = m_og_osd1,
.block = m_ext2_blocks,
.generation = m_og_generation,
.file_acl = m_og_file_acl,
.dir_acl = m_og_dir_acl,
.faddr = m_og_faddr,
.osd2 = m_og_osd2
};
if (memcmp(block_buffer.data() + inode_location.offset, &inode, sizeof(Ext2::Inode)))
{
memcpy(block_buffer.data() + inode_location.offset, &m_inode, sizeof(Ext2::Inode));
memcpy(block_buffer.data() + inode_location.offset, &inode, sizeof(Ext2::Inode));
TRY(m_fs.write_block(inode_location.block, block_buffer));
}
@@ -996,5 +1031,4 @@ needs_new_block:
return BAN::Error::from_errno(ENOENT);
}
}

View File

@@ -23,27 +23,30 @@ namespace Kernel
return BAN::to_unix_time(ban_time);
}
blksize_t FATInode::blksize() const
static timespec fat_date_to_timespec(FAT::Date date, FAT::Time time)
{
return m_fs.inode_block_size(this);
}
timespec FATInode::atime() const
{
const time_t epoch = fat_date_to_epoch(m_entry.last_access_date, {});
const time_t epoch = fat_date_to_epoch(date, time);
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}
timespec FATInode::mtime() const
FATInode::FATInode(FATFS& fs, const FAT::DirectoryEntry& entry, ino_t ino, uint32_t block_count)
: m_fs(fs)
, m_entry(entry)
, m_block_count(block_count)
{
const time_t epoch = fat_date_to_epoch(m_entry.write_date, m_entry.write_time);
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}
timespec FATInode::ctime() const
{
const time_t epoch = fat_date_to_epoch(m_entry.creation_date, m_entry.creation_time);
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
m_ino = ino;
m_mode = ((m_entry.attr & FAT::FileAttr::DIRECTORY) ? Mode::IFDIR : Mode::IFREG) | 0777;
m_nlink = 1;
m_uid = 0;
m_gid = 0;
m_size = m_entry.file_size;
m_blksize = fs.inode_block_size(this);
m_atime = fat_date_to_timespec(m_entry.last_access_date, {});
m_mtime = fat_date_to_timespec(m_entry.write_date, m_entry.write_time);
m_ctime = fat_date_to_timespec(m_entry.creation_date, m_entry.creation_time);
m_blocks = m_block_count;
m_dev = 0;
m_rdev = 0;
}
const FileSystem* FATInode::filesystem() const

View File

@@ -5,14 +5,14 @@
namespace Kernel
{
BAN::ErrorOr<BAN::RefPtr<FileSystem>> FileSystem::from_block_device(BAN::RefPtr<BlockDevice> block_device)
{
if (auto res = Ext2FS::probe(block_device); !res.is_error() && res.value())
return BAN::RefPtr<FileSystem>(TRY(Ext2FS::create(block_device)));
if (auto res = FATFS::probe(block_device); !res.is_error() && res.value())
return BAN::RefPtr<FileSystem>(TRY(FATFS::create(block_device)));
dprintln("Unsupported filesystem");
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<BAN::RefPtr<FileSystem>> FileSystem::from_block_device(BAN::RefPtr<BlockDevice> block_device)
{
if (auto res = Ext2FS::probe(block_device); !res.is_error() && res.value())
return BAN::RefPtr<FileSystem>(TRY(Ext2FS::create(block_device)));
if (auto res = FATFS::probe(block_device); !res.is_error() && res.value())
return BAN::RefPtr<FileSystem>(TRY(FATFS::create(block_device)));
dprintln("Unsupported filesystem");
return BAN::Error::from_errno(ENOTSUP);
}
}

View File

@@ -23,13 +23,22 @@ namespace Kernel
}
Pipe::Pipe(const Credentials& credentials)
: m_uid(credentials.euid())
, m_gid(credentials.egid())
{
timespec current_time = SystemTimer::get().real_time();
m_atime = current_time;
m_mtime = current_time;
m_ctime = current_time;
m_uid = credentials.euid();
m_gid = credentials.egid();
m_ino = 0; // FIXME
m_mode = { Mode::IFIFO | Mode::IRUSR | Mode::IWUSR };
m_nlink = 1;
m_size = 0;
m_blksize = 4096;
m_blocks = 0;
m_dev = 0; // FIXME
m_rdev = 0; // FIXME
}
void Pipe::on_clone(int status_flags)

View File

@@ -28,8 +28,9 @@ namespace Kernel
ProcPidInode::ProcPidInode(Process& process, TmpFileSystem& fs, const TmpInodeInfo& inode_info)
: TmpDirectoryInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
, m_process(process)
{
m_uid = process.credentials().ruid();
m_gid = process.credentials().rgid();
}
void ProcPidInode::cleanup()
@@ -57,7 +58,9 @@ namespace Kernel
, m_process(process)
, m_callback(callback)
{
m_inode_info.mode |= Inode::Mode::IFREG;
m_mode |= Inode::Mode::IFREG;
m_uid = process.credentials().ruid();
m_gid = process.credentials().rgid();
}
BAN::ErrorOr<size_t> ProcROProcessInode::read_impl(off_t offset, BAN::ByteSpan buffer)
@@ -82,7 +85,9 @@ namespace Kernel
, m_process(process)
, m_callback(callback)
{
m_inode_info.mode |= Inode::Mode::IFLNK;
m_mode |= Inode::Mode::IFLNK;
m_uid = process.credentials().ruid();
m_gid = process.credentials().rgid();
}
BAN::ErrorOr<BAN::String> ProcSymlinkProcessInode::link_target_impl()
@@ -104,7 +109,7 @@ namespace Kernel
: TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
, m_callback(callback)
{
m_inode_info.mode |= Inode::Mode::IFREG;
m_mode |= Inode::Mode::IFREG;
}
BAN::ErrorOr<size_t> ProcROInode::read_impl(off_t offset, BAN::ByteSpan buffer)
@@ -130,7 +135,7 @@ namespace Kernel
, m_destructor(destructor)
, m_data(data)
{
m_inode_info.mode |= Inode::Mode::IFLNK;
m_mode |= Inode::Mode::IFLNK;
}
ProcSymlinkInode::~ProcSymlinkInode()
@@ -158,6 +163,8 @@ namespace Kernel
: TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
, m_process(process)
{
m_uid = process.credentials().ruid();
m_gid = process.credentials().rgid();
ASSERT(mode().ifdir());
}

View File

@@ -131,7 +131,7 @@ namespace Kernel
PageTable::with_fast_page(inode_location.paddr, [&] {
auto& inode_info = PageTable::fast_page_as_sized<TmpInodeInfo>(inode_location.index);
ASSERT(inode_info.nlink == 0);
for (auto paddr : inode_info.block)
for (auto paddr : inode_info.tmp_blocks.block)
ASSERT(paddr == 0);
inode_info = {};
});

View File

@@ -48,11 +48,6 @@ namespace Kernel
return &m_fs;
}
dev_t TmpInode::dev() const
{
return m_fs.rdev();
}
BAN::ErrorOr<BAN::RefPtr<TmpInode>> TmpInode::create_from_existing(TmpFileSystem& fs, ino_t ino, const TmpInodeInfo& info)
{
TmpInode* inode_ptr = nullptr;
@@ -74,9 +69,21 @@ namespace Kernel
TmpInode::TmpInode(TmpFileSystem& fs, ino_t ino, const TmpInodeInfo& info)
: m_fs(fs)
, m_inode_info(info)
, m_ino(ino)
{
m_ino = ino;
m_rdev = 0;
m_blksize = PAGE_SIZE;
m_mode = info.mode;
m_nlink = info.nlink;
m_uid = info.uid;
m_gid = info.gid;
m_size = info.size;
m_atime = info.atime;
m_mtime = info.mtime;
m_ctime = info.ctime;
m_blocks = info.blocks;
m_dev = fs.rdev();
m_tmp_blocks = info.tmp_blocks;
// FIXME: this should be able to fail
MUST(fs.add_to_cache(this));
}
@@ -96,16 +103,16 @@ namespace Kernel
{
// FIXME: make this atomic
ASSERT(!(new_mode & Inode::Mode::TYPE_MASK));
m_inode_info.mode &= Inode::Mode::TYPE_MASK;
m_inode_info.mode |= new_mode;
m_mode &= Inode::Mode::TYPE_MASK;
m_mode |= new_mode;
return {};
}
BAN::ErrorOr<void> TmpInode::chown_impl(uid_t new_uid, gid_t new_gid)
{
// FIXME: make this atomic
m_inode_info.uid = new_uid;
m_inode_info.gid = new_gid;
m_uid = new_uid;
m_gid = new_gid;
return {};
}
@@ -113,33 +120,45 @@ namespace Kernel
{
// FIXME: make this atomic
if (times[0].tv_nsec != UTIME_OMIT)
m_inode_info.atime = times[0];
m_atime = times[0];
if (times[1].tv_nsec != UTIME_OMIT)
m_inode_info.atime = times[1];
m_atime = times[1];
return {};
}
void TmpInode::sync()
{
m_fs.write_inode(m_ino, m_inode_info);
TmpInodeInfo info = {
.mode = m_mode.load(),
.uid = m_uid.load(),
.gid = m_gid.load(),
.atime = m_atime,
.ctime = m_ctime,
.mtime = m_mtime,
.nlink = m_nlink.load(),
.size = static_cast<size_t>(size()),
.blocks = m_blocks.load(),
.tmp_blocks = m_tmp_blocks,
};
m_fs.write_inode(m_ino, info);
}
void TmpInode::free_all_blocks()
{
LockGuard _(m_lock);
if (mode().iflnk() && m_inode_info.size <= sizeof(TmpInodeInfo::block))
if (mode().iflnk() && static_cast<size_t>(size()) <= sizeof(TmpBlocks::block))
goto free_all_blocks_done;
for (size_t i = 0; i < TmpInodeInfo::direct_block_count; i++)
if (m_inode_info.block[i])
m_fs.free_block(m_inode_info.block[i]);
if (size_t block = m_inode_info.block[TmpInodeInfo::direct_block_count + 0])
for (size_t i = 0; i < TmpBlocks::direct_block_count; i++)
if (m_tmp_blocks.block[i])
m_fs.free_block(m_tmp_blocks.block[i]);
if (size_t block = m_tmp_blocks.block[TmpBlocks::direct_block_count + 0])
free_indirect_blocks_no_lock(block, 1);
if (size_t block = m_inode_info.block[TmpInodeInfo::direct_block_count + 1])
if (size_t block = m_tmp_blocks.block[TmpBlocks::direct_block_count + 1])
free_indirect_blocks_no_lock(block, 2);
if (size_t block = m_inode_info.block[TmpInodeInfo::direct_block_count + 2])
if (size_t block = m_tmp_blocks.block[TmpBlocks::direct_block_count + 2])
free_indirect_blocks_no_lock(block, 3);
free_all_blocks_done:
for (auto& block : m_inode_info.block)
for (auto& block : m_tmp_blocks.block)
block = 0;
}
@@ -174,26 +193,26 @@ namespace Kernel
{
LockGuard _(m_lock);
if (data_block_index < TmpInodeInfo::direct_block_count)
if (data_block_index < TmpBlocks::direct_block_count)
{
if (m_inode_info.block[data_block_index] == 0)
if (m_tmp_blocks.block[data_block_index] == 0)
return {};
return m_inode_info.block[data_block_index];
return m_tmp_blocks.block[data_block_index];
}
data_block_index -= TmpInodeInfo::direct_block_count;
data_block_index -= TmpBlocks::direct_block_count;
const size_t indices_per_block = blksize() / sizeof(size_t);
if (data_block_index < indices_per_block)
return block_index_from_indirect_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 0], data_block_index, 1);
return block_index_from_indirect_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 0], data_block_index, 1);
data_block_index -= indices_per_block;
if (data_block_index < indices_per_block * indices_per_block)
return block_index_from_indirect_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 1], data_block_index, 2);
return block_index_from_indirect_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 1], data_block_index, 2);
data_block_index -= indices_per_block * indices_per_block;
if (data_block_index < indices_per_block * indices_per_block * indices_per_block)
return block_index_from_indirect_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 2], data_block_index, 3);
return block_index_from_indirect_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 2], data_block_index, 3);
ASSERT_NOT_REACHED();
}
@@ -228,29 +247,29 @@ namespace Kernel
{
LockGuard _(m_lock);
if (data_block_index < TmpInodeInfo::direct_block_count)
if (data_block_index < TmpBlocks::direct_block_count)
{
if (m_inode_info.block[data_block_index] == 0)
if (m_tmp_blocks.block[data_block_index] == 0)
{
m_inode_info.block[data_block_index] = TRY(m_fs.allocate_block());
m_inode_info.blocks++;
m_tmp_blocks.block[data_block_index] = TRY(m_fs.allocate_block());
m_blocks++;
}
return m_inode_info.block[data_block_index];
return m_tmp_blocks.block[data_block_index];
}
data_block_index -= TmpInodeInfo::direct_block_count;
data_block_index -= TmpBlocks::direct_block_count;
const size_t indices_per_block = blksize() / sizeof(size_t);
if (data_block_index < indices_per_block)
return block_index_from_indirect_with_allocation_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 0], data_block_index, 1);
return block_index_from_indirect_with_allocation_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 0], data_block_index, 1);
data_block_index -= indices_per_block;
if (data_block_index < indices_per_block * indices_per_block)
return block_index_from_indirect_with_allocation_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 1], data_block_index, 2);
return block_index_from_indirect_with_allocation_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 1], data_block_index, 2);
data_block_index -= indices_per_block * indices_per_block;
if (data_block_index < indices_per_block * indices_per_block * indices_per_block)
return block_index_from_indirect_with_allocation_no_lock(m_inode_info.block[TmpInodeInfo::direct_block_count + 2], data_block_index, 3);
return block_index_from_indirect_with_allocation_no_lock(m_tmp_blocks.block[TmpBlocks::direct_block_count + 2], data_block_index, 3);
ASSERT_NOT_REACHED();
}
@@ -260,7 +279,7 @@ namespace Kernel
if (block == 0)
{
block = TRY(m_fs.allocate_block());
m_inode_info.blocks++;
m_blocks++;
}
ASSERT(depth >= 1);
@@ -278,7 +297,7 @@ namespace Kernel
if (next_block == 0)
{
next_block = TRY(m_fs.allocate_block());
m_inode_info.blocks++;
m_blocks++;
m_fs.with_block_buffer(block, [&](BAN::ByteSpan block_buffer) {
block_buffer.as_span<size_t>()[(index / divisor) % indices_per_block] = next_block;
@@ -385,9 +404,7 @@ namespace Kernel
{
// FIXME: if size is decreased, we should probably free
// unused blocks
// FIXME: make this atomic
m_inode_info.size = new_size;
m_size = new_size;
return {};
}
@@ -446,12 +463,12 @@ namespace Kernel
LockGuard _(m_lock);
free_all_blocks();
m_inode_info.size = 0;
m_size = 0;
if (new_target.size() <= sizeof(TmpInodeInfo::block))
if (new_target.size() <= sizeof(TmpBlocks::block))
{
memcpy(m_inode_info.block.data(), new_target.data(), new_target.size());
m_inode_info.size = new_target.size();
memcpy(m_tmp_blocks.block.data(), new_target.data(), new_target.size());
m_size = new_target.size();
return {};
}
@@ -465,7 +482,7 @@ namespace Kernel
memcpy(bytespan.data(), new_target.data() + i * blksize(), byte_count);
});
m_inode_info.size += byte_count;
m_size += byte_count;
}
return {};
@@ -478,9 +495,9 @@ namespace Kernel
BAN::String result;
TRY(result.resize(size()));
if ((size_t)size() <= sizeof(TmpInodeInfo::block))
if ((size_t)size() <= sizeof(TmpBlocks::block))
{
memcpy(result.data(), m_inode_info.block.data(), size());
memcpy(result.data(), m_tmp_blocks.block.data(), size());
return result;
}
@@ -569,14 +586,14 @@ namespace Kernel
{
auto inode = TRY(m_fs.open_inode(dot_ino));
ASSERT(inode->nlink() > 0);
inode->m_inode_info.nlink--;
inode->m_nlink--;
}
if (dotdot_ino)
{
auto inode = TRY(m_fs.open_inode(dotdot_ino));
ASSERT(inode->nlink() > 0);
inode->m_inode_info.nlink--;
inode->m_nlink--;
}
return {};
@@ -754,7 +771,7 @@ namespace Kernel
if (cleanup)
TRY(inode->prepare_unlink_no_lock());
inode->m_inode_info.nlink--;
inode->m_nlink--;
if (inode->nlink() == 0)
m_fs.remove_from_cache(inode);
@@ -837,7 +854,7 @@ namespace Kernel
if (done)
{
// add link to linked inode
inode.m_inode_info.nlink++;
inode.m_nlink++;
return {};
}
}
@@ -866,10 +883,10 @@ namespace Kernel
});
// increase current size
m_inode_info.size += blksize();
m_size += blksize();
// add link to linked inode
inode.m_inode_info.nlink++;
inode.m_nlink++;
return {};
}

View File

@@ -86,11 +86,11 @@ namespace Kernel
InputDevice::InputDevice(Type type)
: CharacterDevice(0440, 0, 901)
, m_rdev(get_rdev(type))
, m_name(MUST(BAN::String::formatted(get_name_format(type), minor(m_rdev) - 1)))
, m_type(type)
, m_event_size(get_event_size(type))
{
m_rdev = get_rdev(type);
m_name = MUST(BAN::String::formatted(get_name_format(type), minor(m_rdev) - 1));
MUST(m_event_buffer.resize(m_event_size * m_max_event_count, 0));
switch (m_type)
@@ -270,9 +270,10 @@ namespace Kernel
KeyboardDevice::KeyboardDevice(mode_t mode, uid_t uid, gid_t gid)
: CharacterDevice(mode, uid, gid)
, m_rdev(makedev(DeviceNumber::Keyboard, 0))
, m_name("keyboard"_sv)
{}
{
m_rdev = makedev(DeviceNumber::Keyboard, 0);
}
void KeyboardDevice::notify()
{
@@ -326,9 +327,10 @@ namespace Kernel
MouseDevice::MouseDevice(mode_t mode, uid_t uid, gid_t gid)
: CharacterDevice(mode, uid, gid)
, m_rdev(makedev(DeviceNumber::Mouse, 0))
, m_name("mouse"_sv)
{}
{
m_rdev = makedev(DeviceNumber::Mouse, 0);
}
void MouseDevice::notify()
{

View File

@@ -200,7 +200,7 @@ namespace Kernel
rctrl |= RCTL_BAM;
rctrl |= RCTL_SECRC;
rctrl |= RCTL_BSIZE_8192;
write32(REG_RCTL, rctrl);
write32(REG_RCTL, rctrl);
return {};
}

View File

@@ -27,8 +27,8 @@ namespace Kernel
NetworkInterface::NetworkInterface(Type type)
: CharacterDevice(0400, 0, 0)
, m_type(type)
, m_rdev(get_rdev(type))
{
m_rdev = get_rdev(type);
switch (type)
{
case Type::Ethernet:

View File

@@ -12,8 +12,8 @@ namespace Kernel
{
detail::ATABaseDevice::ATABaseDevice()
: m_rdev(scsi_get_rdev())
{
m_rdev = scsi_get_rdev();
strcpy(m_name, "sda");
m_name[2] += minor(m_rdev);
}

View File

@@ -29,8 +29,8 @@ namespace Kernel
NVMeController::NVMeController(PCI::Device& pci_device)
: CharacterDevice(0600, 0, 0)
, m_pci_device(pci_device)
, m_rdev(makedev(DeviceNumber::NVMeController, get_ctrl_dev_minor()))
{
m_rdev = makedev(DeviceNumber::NVMeController, get_ctrl_dev_minor());
ASSERT(minor(m_rdev) < 10);
strcpy(m_name, "nvmeX");
m_name[4] = '0' + minor(m_rdev);

View File

@@ -29,8 +29,8 @@ namespace Kernel
, m_nsid(nsid)
, m_block_size(block_size)
, m_block_count(block_count)
, m_rdev(makedev(DeviceNumber::NVMeNamespace, get_ns_dev_minor()))
{
m_rdev = makedev(DeviceNumber::NVMeNamespace, get_ns_dev_minor());
ASSERT(minor(m_rdev) < 10);
ASSERT(m_controller.name().size() + 2 < sizeof(m_name));
memcpy(m_name, m_controller.name().data(), m_controller.name().size());

View File

@@ -24,8 +24,8 @@ namespace Kernel
, m_last_block(last_block)
, m_attributes(attr)
, m_name(MUST(BAN::String::formatted("{}{}", name_prefix, index)))
, m_rdev(makedev(major(device->rdev()), index))
{
m_rdev = makedev(major(device->rdev()), index);
memcpy(m_label, label, sizeof(m_label));
}

View File

@@ -65,8 +65,9 @@ namespace Kernel
PseudoTerminalMaster::PseudoTerminalMaster(BAN::UniqPtr<VirtualRange> buffer, mode_t mode, uid_t uid, gid_t gid)
: CharacterDevice(mode, uid, gid)
, m_buffer(BAN::move(buffer))
, m_rdev(makedev(DeviceNumber::PTSMaster, s_pts_master_minor++))
{ }
{
m_rdev = makedev(DeviceNumber::PTSMaster, s_pts_master_minor++);
}
PseudoTerminalMaster::~PseudoTerminalMaster()
{

View File

@@ -72,9 +72,9 @@ namespace Kernel
TTY::TTY(termios termios, mode_t mode, uid_t uid, gid_t gid)
: CharacterDevice(mode, uid, gid)
, m_rdev(next_tty_rdev())
, m_termios(termios)
{
m_rdev = next_tty_rdev();
m_output.buffer = MUST(ByteRingBuffer::create(PAGE_SIZE));
}
@@ -158,16 +158,15 @@ namespace Kernel
{
// FIXME: make this atomic
ASSERT((mode & Inode::Mode::TYPE_MASK) == 0);
m_inode_info.mode &= Inode::Mode::TYPE_MASK;
m_inode_info.mode |= mode;
m_mode &= Inode::Mode::TYPE_MASK;
m_mode |= mode;
return {};
}
BAN::ErrorOr<void> TTY::chown_impl(uid_t uid, gid_t gid)
{
// FIXME: make this atomic
m_inode_info.uid = uid;
m_inode_info.gid = gid;
m_uid = uid;
m_gid = gid;
return {};
}

View File

@@ -132,9 +132,10 @@ namespace Kernel
, m_lun(lun)
, m_block_count(block_count)
, m_block_size(block_size)
, m_rdev(scsi_get_rdev())
, m_name { 's', 'd', (char)('a' + minor(m_rdev)), '\0' }
{ }
{
m_rdev = scsi_get_rdev();
}
USBSCSIDevice::~USBSCSIDevice()
{