Skip to content

Commit

Permalink
Add sync() syscall and a /bin/sync.
Browse files Browse the repository at this point in the history
It walks all the live Inode objects and flushes pending metadata changes
wherever needed.

This could be optimized by keeping a separate list of dirty Inodes,
but let's not get ahead of ourselves.
  • Loading branch information
awesomekling committed Dec 19, 2018
1 parent d0f06e5 commit ed7ae6c
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 24 deletions.
1 change: 0 additions & 1 deletion Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,6 @@ int Process::sys$utime(const char* pathname, const Unix::utimbuf* buf)
}
inode.set_atime(atime);
inode.set_mtime(mtime);
inode.flush_metadata();
return 0;
}

Expand Down
8 changes: 8 additions & 0 deletions Kernel/Syscall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ void initialize()
kprintf("syscall: int 0x80 handler installed\n");
}

static int sync()
{
VFS::the().sync();
return 0;
}

static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, dword arg3)
{
ASSERT_INTERRUPTS_ENABLED();
Expand Down Expand Up @@ -179,6 +185,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
return current->sys$times((Unix::tms*)arg1);
case Syscall::SC_utime:
return current->sys$utime((const char*)arg1, (const Unix::utimbuf*)arg2);
case Syscall::SC_sync:
return sync();
default:
kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
break;
Expand Down
1 change: 1 addition & 0 deletions Kernel/Syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
__ENUMERATE_SYSCALL(mkdir) \
__ENUMERATE_SYSCALL(times) \
__ENUMERATE_SYSCALL(utime) \
__ENUMERATE_SYSCALL(sync) \


#define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function))
Expand Down
3 changes: 1 addition & 2 deletions Kernel/sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ cp -v ../Userland/cat mnt/bin/cat
cp -v ../Userland/uname mnt/bin/uname
cp -v ../Userland/clear mnt/bin/clear
cp -v ../Userland/tst mnt/bin/tst
cp -v ../Userland/ft mnt/bin/ft
cp -v ../Userland/ft2 mnt/bin/ft2
cp -v ../Userland/mm mnt/bin/mm
cp -v ../Userland/kill mnt/bin/kill
cp -v ../Userland/tty mnt/bin/tty
cp -v ../Userland/strsignal mnt/bin/strsignal
cp -v ../Userland/mkdir mnt/bin/mkdir
cp -v ../Userland/touch mnt/bin/touch
cp -v ../Userland/sync mnt/bin/sync
sh sync-local.sh
cp -v kernel.map mnt/
ln -s dir_a mnt/dir_cur
Expand Down
5 changes: 5 additions & 0 deletions LibC/unistd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,9 @@ void _exit(int status)
assert(false);
}

void sync()
{
Syscall::invoke(Syscall::SC_sync);
}

}
1 change: 1 addition & 0 deletions LibC/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern char** environ;
inline int getpagesize() { return 4096; }
pid_t fork();
int execve(const char* filename, const char** argv, const char** envp);
void sync();
void _exit(int status);
pid_t getsid(pid_t);
pid_t setsid();
Expand Down
1 change: 1 addition & 0 deletions Userland/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ strsignal
fgrep
mkdir
touch
sync
6 changes: 5 additions & 1 deletion Userland/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ APPS = \
fgrep \
tty \
mkdir \
touch
touch \
sync

ARCH_FLAGS =
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc
Expand Down Expand Up @@ -130,6 +131,9 @@ mkdir: mkdir.o
touch: touch.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a

sync: sync.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a

.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<

Expand Down
8 changes: 8 additions & 0 deletions Userland/sync.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <stdio.h>
#include <unistd.h>

int main(int, char**)
{
sync();
return 0;
}
1 change: 1 addition & 0 deletions VirtualFileSystem/Ext2FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ void Ext2FSInode::populate_metadata() const

void Ext2FSInode::flush_metadata()
{
dbgprintf("Ext2FSInode: flush_metadata for inode %u\n", index());
m_raw_inode.i_size = m_metadata.size;
m_raw_inode.i_mode = m_metadata.mode;
m_raw_inode.i_uid = m_metadata.uid;
Expand Down
45 changes: 35 additions & 10 deletions VirtualFileSystem/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,45 @@
#include "FileSystem.h"

static dword s_lastFileSystemID;
static HashMap<dword, FS*>* map;
static HashMap<dword, FS*>* s_fs_map;
static HashTable<Inode*>* s_inode_set;

static HashMap<dword, FS*>& fileSystems()
static HashMap<dword, FS*>& all_fses()
{
if (!map)
map = new HashMap<dword, FS*>();
return *map;
if (!s_fs_map)
s_fs_map = new HashMap<dword, FS*>();
return *s_fs_map;
}

static HashTable<Inode*>& all_inodes()
{
if (!s_inode_set)
s_inode_set = new HashTable<Inode*>();
return *s_inode_set;
}

void FS::initializeGlobals()
{
s_lastFileSystemID = 0;
map = 0;
s_fs_map = nullptr;
s_inode_set = nullptr;
}

FS::FS()
: m_fsid(++s_lastFileSystemID)
{
fileSystems().set(m_fsid, this);
all_fses().set(m_fsid, this);
}

FS::~FS()
{
fileSystems().remove(m_fsid);
all_fses().remove(m_fsid);
}

FS* FS::from_fsid(dword id)
{
auto it = fileSystems().find(id);
if (it != fileSystems().end())
auto it = all_fses().find(id);
if (it != all_fses().end())
return (*it).value;
return nullptr;
}
Expand Down Expand Up @@ -125,8 +134,16 @@ FS::DirectoryEntry::DirectoryEntry(const char* n, size_t nl, InodeIdentifier i,
name[nl] = '\0';
}

Inode::Inode(FS& fs, unsigned index)
: m_fs(fs)
, m_index(index)
{
all_inodes().set(this);
}

Inode::~Inode()
{
all_inodes().remove(this);
}

void Inode::will_be_destroyed()
Expand Down Expand Up @@ -167,3 +184,11 @@ int Inode::set_mtime(Unix::time_t ts)
m_metadata_dirty = true;
return 0;
}

void FS::sync()
{
for (auto* inode : all_inodes()) {
if (inode->is_metadata_dirty())
inode->flush_metadata();
}
}
7 changes: 2 additions & 5 deletions VirtualFileSystem/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class FS : public Retainable<FS> {

dword id() const { return m_fsid; }
static FS* from_fsid(dword);
static void sync();

virtual bool initialize() = 0;
virtual const char* class_name() const = 0;
Expand Down Expand Up @@ -98,11 +99,7 @@ class Inode : public Retainable<Inode> {
void will_be_destroyed();

protected:
Inode(FS& fs, unsigned index)
: m_fs(fs)
, m_index(index)
{
}
Inode(FS& fs, unsigned index);

virtual void populate_metadata() const = 0;
void set_metadata_dirty(bool b) { m_metadata_dirty = b; }
Expand Down
13 changes: 8 additions & 5 deletions VirtualFileSystem/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ VFS::~VFS()

auto VFS::makeNode(InodeIdentifier inode) -> RetainPtr<Vnode>
{
auto metadata = inode.metadata();
if (!metadata.isValid())
auto core_inode = inode.fs()->get_inode(inode);
if (!core_inode)
return nullptr;

auto core_inode = inode.fs()->get_inode(inode);
if (core_inode)
core_inode->m_metadata = metadata;
auto& metadata = core_inode->metadata();

InterruptDisabler disabler;

Expand Down Expand Up @@ -501,3 +499,8 @@ void VFS::for_each_mount(Function<void(const Mount&)> callback) const
callback(*mount);
}
}

void VFS::sync()
{
FS::sync();
}
2 changes: 2 additions & 0 deletions VirtualFileSystem/VirtualFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ class VFS {

InodeIdentifier root_inode_id() const;

void sync();

private:
friend class FileDescriptor;
friend class Vnode;
Expand Down

0 comments on commit ed7ae6c

Please sign in to comment.