mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 07:27:45 +00:00
Kernel+Userland: Implement mknod() syscall and add a /bin/mknod program.
This commit is contained in:
parent
abb5c890e0
commit
8b249bd09b
15 changed files with 107 additions and 14 deletions
|
@ -1064,7 +1064,7 @@ RetainPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const Strin
|
|||
|
||||
// NOTE: When creating a new directory, make the size 1 block.
|
||||
// There's probably a better strategy here, but this works for now.
|
||||
auto inode = create_inode(parent_id, name, mode, block_size(), error);
|
||||
auto inode = create_inode(parent_id, name, mode, block_size(), 0, error);
|
||||
if (!inode)
|
||||
return nullptr;
|
||||
|
||||
|
@ -1092,7 +1092,7 @@ RetainPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const Strin
|
|||
return inode;
|
||||
}
|
||||
|
||||
RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, int& error)
|
||||
RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, int& error)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
ASSERT(parent_id.fsid() == fsid());
|
||||
|
@ -1168,6 +1168,11 @@ RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& n
|
|||
e2inode.i_dtime = 0;
|
||||
e2inode.i_links_count = initial_links_count;
|
||||
|
||||
if (is_character_device(mode))
|
||||
e2inode.i_block[0] = dev;
|
||||
else if (is_block_device(mode))
|
||||
e2inode.i_block[1] = dev;
|
||||
|
||||
success = write_block_list_for_inode(inode_id, e2inode, blocks);
|
||||
ASSERT(success);
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ private:
|
|||
|
||||
virtual const char* class_name() const override;
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, int& error) override;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
|
||||
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
byte file_type { 0 };
|
||||
};
|
||||
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, int& error) = 0;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) = 0;
|
||||
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) = 0;
|
||||
|
||||
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const = 0;
|
||||
|
|
|
@ -754,7 +754,7 @@ const char* ProcFS::class_name() const
|
|||
return "ProcFS";
|
||||
}
|
||||
|
||||
RetainPtr<Inode> ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, int&)
|
||||
RetainPtr<Inode> ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int&)
|
||||
{
|
||||
kprintf("FIXME: Implement ProcFS::create_inode()?\n");
|
||||
return { };
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, int& error) override;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RetainPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override;
|
||||
|
||||
void add_sys_file(String&&, Function<ByteBuffer(ProcFSInode&)>&& read_callback, Function<ssize_t(ProcFSInode&, const ByteBuffer&)>&& write_callback);
|
||||
|
|
|
@ -138,7 +138,7 @@ InodeIdentifier SynthFS::root_inode() const
|
|||
return { fsid(), 1 };
|
||||
}
|
||||
|
||||
RetainPtr<Inode> SynthFS::create_inode(InodeIdentifier parentInode, const String& name, mode_t mode, off_t size, int& error)
|
||||
RetainPtr<Inode> SynthFS::create_inode(InodeIdentifier parentInode, const String& name, mode_t mode, off_t size, dev_t, int& error)
|
||||
{
|
||||
(void) parentInode;
|
||||
(void) name;
|
||||
|
|
|
@ -14,7 +14,7 @@ public:
|
|||
virtual bool initialize() override;
|
||||
virtual const char* class_name() const override;
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, int& error) override;
|
||||
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
|
||||
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
|
|
|
@ -195,6 +195,32 @@ KResultOr<Retained<FileDescriptor>> VFS::open(StringView path, int options, mode
|
|||
return FileDescriptor::create(*inode);
|
||||
}
|
||||
|
||||
KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Inode& base)
|
||||
{
|
||||
if (!is_regular_file(mode) && !is_block_device(mode) && !is_character_device(mode) && !is_fifo(mode) && !is_socket(mode))
|
||||
return KResult(-EINVAL);
|
||||
|
||||
RetainPtr<Inode> parent_inode;
|
||||
auto existing_file_or_error = resolve_path_to_inode(path, base, &parent_inode);
|
||||
if (!existing_file_or_error.is_error())
|
||||
return KResult(-EEXIST);
|
||||
if (!parent_inode)
|
||||
return KResult(-ENOENT);
|
||||
if (existing_file_or_error.error() != -ENOENT)
|
||||
return existing_file_or_error.error();
|
||||
if (!parent_inode->metadata().may_write(current->process()))
|
||||
return KResult(-EACCES);
|
||||
|
||||
FileSystemPath p(path);
|
||||
dbgprintf("VFS::mknod: '%s' mode=%o dev=%u in %u:%u\n", p.basename().characters(), mode, dev, parent_inode->fsid(), parent_inode->index());
|
||||
int error;
|
||||
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), mode, 0, dev, error);
|
||||
if (!new_file)
|
||||
return KResult(error);
|
||||
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
KResultOr<Retained<FileDescriptor>> VFS::create(StringView path, int options, mode_t mode, Inode& base)
|
||||
{
|
||||
(void)options;
|
||||
|
@ -218,7 +244,7 @@ KResultOr<Retained<FileDescriptor>> VFS::create(StringView path, int options, mo
|
|||
FileSystemPath p(path);
|
||||
dbgprintf("VFS::create_file: '%s' in %u:%u\n", p.basename().characters(), parent_inode->fsid(), parent_inode->index());
|
||||
int error;
|
||||
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), mode, 0, error);
|
||||
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), mode, 0, 0, error);
|
||||
if (!new_file)
|
||||
return KResult(error);
|
||||
|
||||
|
@ -469,7 +495,7 @@ KResult VFS::symlink(StringView target, StringView linkpath, Inode& base)
|
|||
FileSystemPath p(linkpath);
|
||||
dbgprintf("VFS::symlink: '%s' (-> '%s') in %u:%u\n", p.basename().characters(), target.characters(), parent_inode->fsid(), parent_inode->index());
|
||||
int error;
|
||||
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), 0120644, 0, error);
|
||||
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), 0120644, 0, 0, error);
|
||||
if (!new_file)
|
||||
return KResult(error);
|
||||
ssize_t nwritten = new_file->write_bytes(0, target.length(), (const byte*)target.characters(), nullptr);
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
KResult stat(StringView path, int options, Inode& base, struct stat&);
|
||||
KResult utime(StringView path, Inode& base, time_t atime, time_t mtime);
|
||||
KResult rename(StringView oldpath, StringView newpath, Inode& base);
|
||||
KResult mknod(StringView path, mode_t, dev_t, Inode& base);
|
||||
KResultOr<Retained<Inode>> open_directory(StringView path, Inode& base);
|
||||
|
||||
void register_device(Device&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue