Commit graph

239 commits

Author SHA1 Message Date
Andreas Kling 06a80bcf69 Kernel+SystemMonitor: Publish can_read/write state for open files
The can_read() and can_write() states for file descriptions are now
published in /proc, allowing SystemMonitor to display it.
2019-11-09 22:42:19 +01:00
Andreas Kling 083c5f8b89 Kernel: Rework Process::Priority into ThreadPriority
Scheduling priority is now set at the thread level instead of at the
process level.

This is a step towards allowing processes to set different priorities
for threads. There's no userspace API for that yet, since only the main
thread's priority is affected by sched_setparam().
2019-11-06 16:30:06 +01:00
Andreas Kling 1c8f017730 Kernel: Remove unused SynthFS filesystem
This used to be the base class of ProcFS and DevPtsFS but not anymore.
2019-11-06 11:36:24 +01:00
Andreas Kling 59ed235c85 Kernel: Implement O_DIRECT open() flag to bypass disk caches
Files opened with O_DIRECT will now bypass the disk cache in read/write
operations (though metadata operations will still hit the disk cache.)

This will allow us to test actual disk performance instead of testing
disk *cache* performance, if that's what we want. :^)

There's room for improvment here, we're very aggressively flushing any
dirty cache entries for the specific block before reading/writing that
block. This is done by walking the entire cache, which may be slow.
2019-11-05 19:35:12 +01:00
Andreas Kling f215f0c226 ProcFS: Fix Clang build (or really, Qt Creator syntax highlighting)
The Clang parser used by Qt Creator kept getting confused by this code.
2019-11-04 18:14:04 +01:00
Andreas Kling 721585473b Ext2FS: Don't uncache inodes while they are being watched
If an inode is observed by watch_file(), we won't uncache it.
This allows a program to watch a file without keeping it open.
2019-11-04 17:25:44 +01:00
Andreas Kling 1b2ef8582c Kernel: Make File's can_read/can_write take a const FileDescription&
Asking a File if we could possibly read or write it will never mutate
the asking FileDescription&, so it should be const.
2019-11-04 14:03:14 +01:00
Andreas Kling e8fee92357 Kernel: Don't update fd offset on read/write error
If something goes wrong with a read or write operation, we don't want
to add the error number to the fd's offset. :^)
2019-11-04 13:58:28 +01:00
Andreas Kling c538648465 Ext2FS: Uncache unused Inodes after flushing contents to disk
Don't keep Inodes around in memory forever after we've interacted with
them once. This is a slight performance pessimization when accessing
the same file repeatedly, but closing it for a while in between.

Longer term we should find a way to keep a limited number of unused
Inodes cached, whichever ones we think are likely to be used again.
2019-11-04 12:23:19 +01:00
Alexander 9e03f3ce20 ProcFS: Identify virtual filesystems' device in df (#728) 2019-11-03 20:58:10 +01:00
Andreas Kling 7e56cf1800 Ext2FS: Lock the filesystem during initialization and during sync
If we get preempted during initialization, we really don't want to try
doing a sync on a partially-initialized filesystem.
2019-11-03 13:56:55 +01:00
Andreas Kling c1d3ac7108 Ext2FS: Fix unpopulated block list cache after mkdir()
When creating a new directory, we set the initial size to 1 block.
This meant that we were allocating a block up front, but the Inode's
internal block list cache was not populated with this block.

This broke write_bytes() on a new directory, since it assumed that
the block list cache would be up to date if the call to write_bytes()
would not change the directory's size.

This patch fixes the issue in two ways: First, we cache the initial
block list created for new directories.
Second, we now repopulate the block list cache in write_bytes() if it
is empty when we get there. This is basically just a safety fallback
to avoid having this kind of bug in the future.
2019-11-03 10:22:09 +01:00
Andreas Kling dcf8d359f3 Kernel: Fick infinite recursion when filling up disk cache
We can't be calling the virtual FS::flush_writes() in order to flush
the disk cache from within the disk cache, since an FS subclass may
try to do cache stuff in its flush_writes() implementation.

Instead, separate out the implementation of DiskBackedFS's flushing
logic into a flush_writes_impl() and call that from the cache code.
2019-11-03 00:21:17 +01:00
Andreas Kling 1e36d899f1 Ext2FS: Use KBuffers for the cached bitmap blocks
Also cache the block group descriptor table in a KBuffer on file system
initialization, instead of on first access.

This reduces pressure on the kmalloc heap somewhat.
2019-11-03 00:10:24 +01:00
Andreas Kling 94a6b248ca Ext2FS: Resizing an Inode to its current size should do nothing
We were writing out the full block list whenever Ext2FSInode::resize()
was called, even if the old and new sizes were identical.

This patch makes it a no-op, which drastically improves "cp" speed
since we now take full advantage of the up-front call to ftruncate().
2019-11-02 16:22:29 +01:00
Andreas Kling 5835569527 Ext2FS: Inode resizing should fail with ENOSPC if we lack blocks
If there are not enough free blocks in the filesystem to accomodate
growing an Inode, we should fail with ENOSPC before even starting to
allocate blocks.
2019-11-02 12:53:31 +01:00
Andreas Kling 2ad2210eb4 Ext2FS: Use the bitmap block caching for Inode bitmaps as well
Nothing really shows up on disk_benchmark for this change, but it is
obviously sensible to use the same mechanism here.
2019-11-02 12:34:18 +01:00
Andreas Kling e52b7eeccc Ext2FS: Rename get_block_bitmap() => get_bitmap_block()
This can be used for Inode bitmaps as well, so let's rename it.
2019-11-02 12:26:20 +01:00
Andreas Kling 1ae9d85de9 Ext2FS: Cache block bitmaps instead of always reading/writing disk
Add a simple cache to Ext2FS where we keep block bitmaps along with a
dirty bit. This allows us to coalesce bitmap flushes, giving us a nice
~3x improvement in disk_benchmark write speeds.
2019-11-02 12:18:43 +01:00
Andreas Kling 3a8b5b405c Ext2FS: Tidy up code related to the Ext2 super block a bit
Store the cached super block as an ext2_super_block member instead of
caching it in a ByteBuffer and using a casting helper everywhere.

This patch also combines reading/writing of the super block into a
single disk device operation (instead of two.)
2019-11-02 11:49:11 +01:00
Andreas Kling e4b7786b66 Ext2FS: Flush the super block and block group descriptors lazily
Keep dirty bits for these and override flush_writes() so that we can
coalesce writes. Looks like a ~5x write performance bump on the
disk_benchmark.
2019-11-02 11:36:56 +01:00
Andreas Kling 014f8ca8c4 AK: Allow JsonValue to store 64-bit integers internally
Add dedicated internal types for Int64 and UnsignedInt64. This makes it
a bit more straightforward to work with 64-bit numbers (instead of just
implicitly storing them as doubles.)
2019-10-29 16:36:50 +01:00
Andreas Kling 558c63a6f9 Kernel: FileDescription::is_directory() should not assert !is_fifo()
I have no idea why this was here. It makes no sense. If you're trying
to find out if something is a directory, why wouldn't you be allowed to
ask that about a FIFO? :^)

Thanks to Brandon for spotting this!

Also, while we're here, cache the directory state in a bool member so
we don't have to keep fetching inode metadata when checking this
repeatedly. This is important since sys$read() now calls it.
2019-10-25 09:23:38 +02:00
Drew Stratford 3014fdf3bd ProcFS: make procfs$pid_fds always returns a valid JSON array.
Previously, procfs$pid_fds would return nothing when called
for a process that had either no open files or a non-existent
handle. This could cause problems when a userspace program
expected a valid Json response.

Procfs$pid_fs now returns an empty array in the aforementioned
cases.
2019-10-23 07:45:13 +02:00
Drew Stratford d063734f69 ProcFS: Check for empty Optional in read_bytes()
In read_bytes() we now check that the Optional "data" actually
contains a value before use, avoiding a failing asserting in
kernel space.
2019-10-23 07:45:13 +02:00
Andreas Kling 0782c60fe5 Kernel: Update the mtime after a successful InodeFile::write()
Well this was pretty silly. We were not updating the modification time
of files.. after modifying them. :^)
2019-10-22 22:23:58 +02:00
Andreas Kling ec65b8db2e Revert "Kernel: Make DoubleBuffer use a KBuffer instead of kmalloc()ing"
This reverts commit 1cca5142af.

This appears to be causing intermittent triple-faults and I don't know
why yet, so I'll just revert it to keep the tree in decent shape.
2019-10-18 15:58:06 +02:00
Andreas Kling 1cca5142af Kernel: Make DoubleBuffer use a KBuffer instead of kmalloc()ing
Background: DoubleBuffer is a handy buffer class in the kernel that
allows you to keep writing to it from the "outside" while the "inside"
reads from it. It's used for things like LocalSocket and PTY's.
Internally, it has a read buffer and a write buffer, but the two will
swap places when the read buffer is exhausted (by reading from it.)

Before this patch, it was internally implemented as two Vector<u8>
that we would swap between when the reader side had exhausted the data
in the read buffer. Now instead we preallocate a large KBuffer (64KB*2)
on DoubleBuffer construction and use that throughout its lifetime.

This removes all the kmalloc heap traffic caused by DoubleBuffers :^)
2019-10-18 14:55:04 +02:00
Jesse Buhagiar 06b6af61c6 Kernel: Made DiskCache entries a KBuffer
The Cache entries found in `DiskBackedFileSystem` are now stored in a
`KBuffer` object, instead of relying on `kmalloc_eternal`. The number
of entries was exceeding that of the number of bytes allocated to
`kmalloc_eternal`, which in turn caused `mount()` to fail epically
when called.
2019-10-08 11:10:30 +02:00
Andreas Kling 35138437ef Kernel+SystemMonitor: Add fault counters
This patch adds three separate per-process fault counters:

- Inode faults

    An inode fault happens when we've memory-mapped a file from disk
    and we end up having to load 1 page (4KB) of the file into memory.

- Zero faults

    Memory returned by mmap() is lazily zeroed out. Every time we have
    to zero out 1 page, we count a zero fault.

- CoW faults

    VM objects can be shared by multiple mappings that make their own
    unique copy iff they want to modify it. The typical reason here is
    memory shared between a parent and child process.
2019-10-02 14:13:49 +02:00
Andreas Kling 5ab044beae Ext2FS: Make Ext2FSInode::is_directory() fast
This patch overloads Inode::is_directory() with a faster version that
doesn't require instantiating the whole InodeMetadata.

If you have an Ext2FSInode&, calling is_directory() should be instant
since we can just look directly at the raw inode bits.
2019-10-02 13:47:44 +02:00
Andreas Kling 8e775d241e Kernel: Make DiskBackedFS flush writes if cache is completely dirty
If we want to make a new entry in the disk cache when it's completely
full of dirty blocks, we'll now synchronously flush the writes at that
point. Maybe it's not ideal, but at least we can keep going.
2019-09-30 11:46:56 +02:00
Andreas Kling 922fd703c9 Kernel: Convert the DiskBackedFS write API to take "const u8*"
This way clients are not required to have instantiated ByteBuffers
and can choose whatever memory scheme works best for them.

Also converted some of the Ext2FS code to use stack buffers instead.
2019-09-30 11:23:36 +02:00
Andreas Kling 1fc2612667 Kernel: Make DiskBackedFS::read_block() write to client-provided memory
Instead of having DiskBackedFS allocate a ByteBuffer, leave it to each
client to provide buffer space.

This is significantly faster in many cases where we can use a stack
buffer and avoid heap allocation entirely.
2019-09-30 11:04:30 +02:00
Andreas Kling a61f6ccc27 Kernel: Implement a simpler, bigger cache for DiskBackedFS
The hashmap cache was ridiculously slow and hurt us more than it helped
us. This patch replaces it with a flat memory cache that keeps up to
10'000 blocks in cache with a simple dirty bit.

The syncd task will wake up periodically and call flush_writes() on all
file systems, which now causes us to traverse the cache and write all
dirty blocks to disk.

There's a ton of room for improvement here, but this itself is already
drastically better when doing repeated GCC invocations.
2019-09-30 10:34:50 +02:00
Andreas Kling 8f45a259fc ByteBuffer: Remove pointer() in favor of data()
We had two ways to get the data inside a ByteBuffer. That was silly.
2019-09-30 08:57:01 +02:00
Sergey Bugaev 9a41dda029 Kernel: Expose blocking and cloexec fd flags in ProcFS 2019-09-28 22:27:45 +02:00
Sergey Bugaev 3652bec746 Kernel: Make proper use of the new keep_empty argument 2019-09-28 18:29:42 +02:00
Conrad Pankoff 062218b4cf Kernel: Support writing doubly-indirect ext2 blocks 2019-09-28 09:29:10 +02:00
Andreas Kling e364846622 Ext2FS: Don't allocate blocks until we're committed to a new inode
Otherwise we would leak the blocks in case we returned earlier than
expected. :^)
2019-09-22 18:50:24 +02:00
Andreas Kling bd7c38e7b6 Ext2FS: Oops, fix wrong ENOSPC in create_inode() 2019-09-22 18:44:05 +02:00
Andreas Kling bff59eff4b Ext2FS: Fix two bugs in block allocation:
1) Off-by-one in block allocation when block size != 1 KB

Due to a quirk in the on-disk layout of ext2, file systems with a block
size of 1 KB have block #1 as their first block, while all others start
on block #0.

2) We had no fallback mechanism when the preferred group was full

We now allocate blocks from the preferred block group as long as it's
possible, and fall back to a simple scan through all groups when the
preferred one is full.
2019-09-22 18:37:17 +02:00
Sergey Bugaev e9dd94063f Kernel: Do not panic on fstat(fifo)
Instead, let's return an empty buffer with st_mode indicating it's a fifo.
2019-09-17 21:56:42 +02:00
Andreas Kling 5d491fa1cd Kernel: Add a simple slab allocator for small allocations
This is a freelist allocator with static size classes that works as a
complement to the generic kmalloc(). It's a lot faster than kmalloc()
since allocation just means popping from the freelist.

It's also significantly more compact when there are a lot of objects
smaller than the minimum kmalloc chunk size (32 bytes.)

This patch enables it for the Region and PhysicalPage classes.
In the PhysicalPage (8 bytes) case, it's a huge improvement since we
no longer waste 75% of the storage allocated.

There are also a number of ways this can be improved, so let's keep
working on it going forward.
2019-09-16 10:33:27 +02:00
Andreas Kling 1c692e87a6 Kernel: Move kmalloc() into a Kernel/Heap/ directory 2019-09-16 09:01:44 +02:00
Andreas Kling b9be6b7bb4 Ext2FS: Trying to create a too-long directory entry should ENAMETOOLONG
Also added some assertions to DirectoryEntry in case someone tries to
instantiate them with names that would overflow the name buffer.

DirectoryEntry is a crappy data structure, and the name buffer is also
crappy. Added a FIXME about replacing it with something nicer.

Before this patch, the DirectoryEntry::name buffer would overflow if
you did "touch extremely-long-file-name". Duh.

Fixes #538.
2019-09-10 21:04:27 +02:00
Andreas Kling 33e6cb8b80 Kernel: Remove spammy logging about absolute_path() on non-custodies 2019-09-08 09:37:28 +02:00
Andreas Kling 73fdbba59c AK: Rename <AK/AKString.h> to <AK/String.h>
This was a workaround to be able to build on case-insensitive file
systems where it might get confused about <string.h> vs <String.h>.

Let's just not support building that way, so String.h can have an
objectively nicer name. :^)
2019-09-06 15:36:54 +02:00
Andreas Kling e25ade7579 Kernel: Rename "vmo" to "vmobject" everywhere 2019-09-04 11:27:14 +02:00
Conrad Pankoff 41d113713d ProcFS: Expose ARP table 2019-09-02 09:42:27 +02:00