Commit graph

147 commits

Author SHA1 Message Date
Andreas Kling
dbb668ddd3 Ext2FS: Propagate error codes from write_directory() 2021-02-02 18:58:26 +01:00
Peter Elliott
c0e88b9710 Kernel: Add FIBMAP ioctl to Ext2FileSystem
FIBMAP is a linux ioctl that gives the location on disk of a specific
block of a file
2021-01-30 22:54:51 +01:00
asynts
7cf0c7cc0d Meta: Split debug defines into multiple headers.
The following script was used to make these changes:

    #!/bin/bash
    set -e

    tmp=$(mktemp -d)

    echo "tmp=$tmp"

    find Kernel \( -name '*.cpp' -o -name '*.h' \) | sort > $tmp/Kernel.files
    find . \( -path ./Toolchain -prune -o -path ./Build -prune -o -path ./Kernel -prune \) -o \( -name '*.cpp' -o -name '*.h' \) -print | sort > $tmp/EverythingExceptKernel.files

    cat $tmp/Kernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/Kernel.macros
    cat $tmp/EverythingExceptKernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/EverythingExceptKernel.macros

    comm -23 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/Kernel.unique
    comm -1 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/EverythingExceptKernel.unique

    cat $tmp/Kernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/Kernel.header
    cat $tmp/EverythingExceptKernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/EverythingExceptKernel.header

    for macro in $(cat $tmp/Kernel.unique)
    do
        cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.new-includes ||:
    done
    cat $tmp/Kernel.new-includes | sort > $tmp/Kernel.new-includes.sorted

    for macro in $(cat $tmp/EverythingExceptKernel.unique)
    do
        cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.old-includes ||:
    done
    cat $tmp/Kernel.old-includes | sort > $tmp/Kernel.old-includes.sorted

    comm -23 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.new
    comm -13 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.old
    comm -12 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.mixed

    for file in $(cat $tmp/Kernel.includes.new)
    do
        sed -i -E 's/#include <AK\/Debug\.h>/#include <Kernel\/Debug\.h>/' $file
    done

    for file in $(cat $tmp/Kernel.includes.mixed)
    do
        echo "mixed include in $file, requires manual editing."
    done
2021-01-26 21:20:00 +01:00
asynts
eea72b9b5c Everywhere: Hook up remaining debug macros to Debug.h. 2021-01-25 09:47:36 +01:00
asynts
acdcf59a33 Everywhere: Remove unnecessary debug comments.
It would be tempting to uncomment these statements, but that won't work
with the new changes.

This was done with the following commands:

    find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec awk -i inplace '$0 !~ /\/\/#define/ { if (!toggle) { print; } else { toggle = !toggle } } ; $0 ~/\/\/#define/ { toggle = 1 }' {} \;

    find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec awk -i inplace '$0 !~ /\/\/ #define/ { if (!toggle) { print; } else { toggle = !toggle } } ; $0 ~/\/\/ #define/ { toggle = 1 }' {} \;
2021-01-25 09:47:36 +01:00
Andreas Kling
bfb254ed14 Ext2FS: Assert that create_directory() is called with valid mode 2021-01-23 16:45:05 +01:00
Andreas Kling
f2ea6c3d4c Ext2FS: Don't create a directory when asked to create a socket file
(mode & S_IFDIR) is not enough to check if "mode" is a directory,
we have to check all the bits in the S_IFMT mask.

Use the is_directory() helper to fix this bug.
2021-01-23 16:45:05 +01:00
Andreas Kling
1f53dd0943 Ext2FS: Propagate I/O errors from Ext2FSInode::write_bytes() 2021-01-21 00:14:56 +01:00
Andreas Kling
19d3f8cab7 Kernel+LibC: Turn errno codes into a strongly typed enum
..and allow implicit creation of KResult and KResultOr from ErrnoCode.
This means that kernel functions that return those types can finally
do "return EINVAL;" and it will just work.

There's a handful of functions that still deal with signed integers
that should be converted to return KResults.
2021-01-20 23:20:02 +01:00
Andreas Kling
e279b45aed Kernel: Make BlockBasedFS read/write functions return a KResult
This way, if something goes wrong, we get to keep the actual error.
Also, KResults are nodiscard, so we have to deal with that in Ext2FS
instead of just silently ignoring I/O errors(!)
2021-01-20 22:57:36 +01:00
Andreas Kling
6613cef2f8 Ext2FS: Update block group directory count after directory removal
When freeing an inode, we were checking if it's a directory *after*
wiping the inode metadata. This caused us to forget updating the block
group descriptor with the new directory count.
2021-01-17 16:56:07 +01:00
Andreas Kling
77656aed8e Ext2FS: Zero out new space when growing an inode
Before this change, truncating an Ext2FS inode to a larger size than it
was before would give you uninitialized on-disk data.

Fix this by zeroing out all the new space when doing an inode resize.

This is pretty naively implemented via Inode::write_bytes() and there's
lots of room for cleverness here in the future.
2021-01-09 22:08:53 +01:00
Andreas Kling
f0093e5d59 Ext2FS: Convert dbg() to dbgln()
Also remove some dbg()'s that were printing incorrect information.
2021-01-09 21:54:27 +01:00
asynts
938e5c7719 Everywhere: Replace a bundle of dbg with dbgln.
These changes are arbitrarily divided into multiple commits to make it
easier to find potentially introduced bugs with git bisect.Everything:

The modifications in this commit were automatically made using the
following command:

    find . -name '*.cpp' -exec sed -i -E 's/dbg\(\) << ("[^"{]*");/dbgln\(\1\);/' {} \;
2021-01-09 21:11:09 +01:00
Tom
ae956edf6e Kernel: Improve some low-memory situations with ext2 2021-01-01 23:43:44 +01:00
Andreas Kling
43d9fe15f9 Revert "Kernel: Convert read_block method to get a reference instead of pointer"
This reverts commit 092a13211a.

Fixes #4611.
2020-12-29 00:06:52 +01:00
Liav A
092a13211a Kernel: Convert read_block method to get a reference instead of pointer
BlockBasedFileSystem::read_block method should get a reference of
a UserOrKernelBuffer.

If we need to force caching a block, we will call other method to do so.
2020-12-27 23:07:44 +01:00
Nathan Lanza
d1891f67ac
AK: Use direct-list-initialization for Vector::empend() (#4564)
clang trunk with -std=c++20 doesn't seem to properly look for an
aggregate initializer here when the type being constructed is a simple
aggregate (e.g. `struct Thing { int a; int b; };`). This template fails
to compile in a usage added 12/16/2020 in `AK/Trie.h`.

Both forms of initialization are supposed to call the
aggregate-initializers but direct-list-initialization delegating to
aggregate initializers is a new addition in c++20 that might not be
implemented yet.
2020-12-27 23:06:37 +01:00
Andreas Kling
8e79bde2b7 Kernel: Move KBufferBuilder to the fallible KBuffer API
KBufferBuilder::build() now returns an OwnPtr<KBuffer> and can fail.
Clients of the API have been updated to handle that situation.
2020-12-18 19:22:26 +01:00
Andreas Kling
47da86d136 Ext2FS: Fail the mount if BGD table cache allocation fails
Instead of asserting if we can't allocate enough memory for a BGD table
cache, just fail the mount instead.
2020-12-18 19:22:26 +01:00
Andreas Kling
76308c2e1f Kernel: Reduce ByteBuffer thrashing in inode block list generation
Instead of creating and destroying a new ByteBuffer for every block we
process during block list generation, just use stack memory instead.
2020-11-24 21:29:08 +01:00
Andreas Kling
3e3a72f2a2 Ext2FS: Oops, fix forgotten assignment in Ext2FSInode::resize()
If the inode's block list cache is empty, we forgot to assign the
result of computing the block list. The fact that this worked anyway
makes me wonder when we actually don't have a cache..

Thanks to szyszkienty for spotting this! :^)
2020-11-24 16:16:09 +01:00
Andreas Kling
20205708b9 Ext2FS: Use cached inode block list in resize() if available
If we have already cached the block list of an Ext2FSInode, we can save
a lot of time by not regenerating it.
2020-11-24 13:40:45 +01:00
Andreas Kling
bb9c705fc2 Ext2FS: Move some EXT2_DEBUG logging behind EXT2_VERY_DEBUG
This makes the build actually somewhat usable with EXT2_DEBUG. :^)
2020-11-23 16:08:42 +01:00
Andreas Kling
df758a5a51 Ext2FS: Clear out the direct block list when an inode is resized to 0
e2fsck was complaining about blocks being allocated in an inode's list
of direct blocks while at the same time being free in the block bitmap.

It was easy to reproduce by creating a file with non-zero length and
then truncating it. This fixes the issue by clearing out the direct
block list when resizing a file to 0.
2020-11-23 14:08:50 +01:00
Andreas Kling
1da828b8bf Ext2FS: Zero out inode metadata when deleting them
This isn't strictly necessary but it seems like a reasonable thing
to be doing. Note that we still populate the dtime field with the
time of deletion.
2020-11-07 17:48:22 +01:00
Andreas Kling
bab24ce34c Ext2FS: Deallocate block list meta blocks when freeing an inode
When computing the list of blocks to deallocate when freeing an inode,
we would stop collecting blocks after reaching the inode's block count.
Since we're getting rid of the inode, we need to also include the meta
blocks used by the on-disk block list itself.
2020-11-07 16:45:03 +01:00
Andreas Kling
eeffd5be07 Ext2FS: Fix block allocation ignoring the very last block group
The block group indices are 1-based for some reason. Because of that,
we were forgetting to check in the very last block group when doing
block allocation. This caused block allocation to fail even when the
superblock indicated that we had free blocks.

Fixes #3674.
2020-10-07 13:42:17 +02:00
Luke
d79194d87f Kernel: Return early in create_inode if name is too long 2020-09-28 21:52:31 +02:00
Andreas Kling
2cb32f8356 Kernel: Let InodeWatcher track child inode numbers instead of names
First of all, this fixes a dumb info leak where we'd write kernel heap
addresses (StringImpl*) into userspace memory when reading a watcher.

Instead of trying to pass names to userspace, we now simply pass the
child inode index. Nothing in userspace makes use of this yet anyway,
so it's not like we're breaking anything. We'll see how this evolves.
2020-09-19 16:39:52 +02:00
asynts
206dcd84a6 FileSystem: Use OutputMemoryStream instead of BufferStream. 2020-09-15 20:36:45 +02:00
Tom
c8d9f1b9c9 Kernel: Make copy_to/from_user safe and remove unnecessary checks
Since the CPU already does almost all necessary validation steps
for us, we don't really need to attempt to do this. Doing it
ourselves doesn't really work very reliably, because we'd have to
account for other processors modifying virtual memory, and we'd
have to account for e.g. pages not being able to be allocated
due to insufficient resources.

So change the copy_to/from_user (and associated helper functions)
to use the new safe_memcpy, which will return whether it succeeded
or not. The only manual validation step needed (which the CPU
can't perform for us) is making sure the pointers provided by user
mode aren't pointing to kernel mappings.

To make it easier to read/write from/to either kernel or user mode
data add the UserOrKernelBuffer helper class, which will internally
either use copy_from/to_user or directly memcpy, or pass the data
through directly using a temporary buffer on the stack.

Last but not least we need to keep syscall params trivial as we
need to copy them from/to user mode using copy_from/to_user.
2020-09-13 21:19:15 +02:00
Ben Wiederhake
737c9f0a14 Kernel: Explain correctness of reference to local lambda 2020-08-30 10:31:04 +02:00
Itamar
33138900de FileSystem: Convert file types to DT_* types at a later stage
A change introduced in 5e01234 made it the resposibility of each
filesystem to have the file types returned from
'traverse_as_directory' match up with the DT_* types.
However, this caused corruption of the Ext2FS file format because
the Ext2FS uses 'traverse_as_directory' internally when manipulating
 the file system. The result was a mixture between EXT2_FT_* and DT_*
file types in the internal Ext2FS structures.

Starting with this commit, the conversion from internal filesystem file
types to the user facing DT_* types happens at a later stage,
in the 'FileDescription::get_dir_entries' function which is directly
used by sys$get_dir_entries.
2020-08-29 20:54:06 +02:00
Itamar
b6c34c0521 Ext2FS: Make reported file_type values match up with those in dirent
This fixes an issue we had in the git port where git would not
recognize untracked files (for example in 'git status').
When git used readdir, the 'd_type' field in the dirent struct contained
bad values (Specifically, it contained the values defiend in
Kernel/FileSystem/ext2_fs.h instead of the ones in LibC/dirent.h).

After this fix, we can create a new git repository with 'git init', and
then stage and commit files as usual.
2020-08-28 16:06:55 +02:00
Andreas Kling
31d3eac651 Ext2FS: Fix build with EXT2_DEBUG 2020-08-23 01:25:29 +02:00
Andreas Kling
607e085823 Ext2FS: Fix inode link leak on all new inodes
The initial inode link count was wrong in Ext2FS, as the act of adding
new inodes to their new parent bumps the count.

This regressed in df66c28479.
2020-08-19 21:17:02 +02:00
Andreas Kling
6ad2d31952 Ext2FS: Stop using FS::DirectoryEntry
We were only using this as a temporary helper object while constructing
directories. Create a simpler Ext2FSDirectoryEntry instead for this.
2020-08-18 18:26:54 +02:00
Andreas Kling
eeaba41d13 Kernel: Add DirectoryEntryView for VFS directory traversal
Unlike DirectoryEntry (which is used when constructing directories),
DirectoryEntryView does not manage storage for file names. Names are
just StringViews.

This is much more suited to the directory traversal API and makes
it easier to implement this in file system classes since they no
longer need to create temporary name copies while traversing.
2020-08-18 18:26:54 +02:00
Brian Gianforcaro
946c96dd56 Kernel: Suppress remaining unobserved KResult return codes
These are all cases where there is no clear and easy fix,
I've left FIXME bread crumbs so that these can hopefully
be fixed over time.
2020-08-05 14:36:48 +02:00
Brian Gianforcaro
d67069d922 Kernel: Propagate a few KResults properly in FileSystem subsystems
Propagating un-obsevered KResults up the stack.
2020-08-05 14:36:48 +02:00
Brian Gianforcaro
e8c9b5e870 Kernel: Make Inode::directory_entry_count errors observable.
Certain implementations of Inode::directory_entry_count were calling
functions which returned errors, but had no way of surfacing them.
Switch the return type to KResultOr<size_t> and start observing these
error paths.
2020-08-05 10:26:29 +02:00
Tom
bc107d0b33 Kernel: Add SMP IPI support
We can now properly initialize all processors without
crashing by sending SMP IPI messages to synchronize memory
between processors.

We now initialize the APs once we have the scheduler running.
This is so that we can process IPI messages from the other
cores.

Also rework interrupt handling a bit so that it's more of a
1:1 mapping. We need to allocate non-sharable interrupts for
IPIs.

This also fixes the occasional hang/crash because all
CPUs now synchronize memory with each other.
2020-07-06 17:07:44 +02:00
Sergey Bugaev
187b785a05 Kernel: Split BlockBasedFileSystem off FileBackedFileSystem
FileBackedFileSystem is one that's backed by (mounted from) a file, in other
words one that has a "source" of the mount; that doesn't mean it deals in
blocks. The hierarchy now becomes:

* FS
  * ProcFS
  * DevPtsFS
  * TmpFS
  * FileBackedFS
    * (future) Plan9FS
    * BlockBasedFS
      * Ext2FS
2020-07-05 12:26:27 +02:00
Andreas Kling
0d577ab781 Kernel: Add "child added" and "child removed" InodeWatcher events
The child name is not yet accessible to userspace, but will be in a
future patch.
2020-07-04 13:37:51 +02:00
Sergey Bugaev
df66c28479 Kernel: Deemphasize inode identifiers
These APIs were clearly modeled after Ext2FS internals, and make perfect sense
in Ext2FS context. The new APIs are more generic, and map better to the
semantics exported to the userspace, where inode identifiers only appear in
stat() and readdir() output, but never in any input.

This will also hopefully reduce the potential for races (see commit c44b4d61f3).

Lastly, this makes it way more viable to implement a filesystem that only
synthesizes its inodes lazily when queried, and destroys them when they are no
longer in use. With inode identifiers being used to reference inodes, the only
choice for such a filesystem is to persist any inode it has given out the
identifier for, because it might be queried at any later time. With direct
references to inodes, the filesystem will know when the last reference is
dropped and the inode can be safely destroyed.
2020-06-25 15:49:04 +02:00
Brian Gianforcaro
6a74af8063 Kernel: Plumb KResult through FileDescription::read_entire_file() implementation.
Allow file system implementation to return meaningful error codes to
callers of the FileDescription::read_entire_file(). This allows both
Process::sys$readlink() and Process::sys$module_load() to return more
detailed errors to the user.
2020-05-26 10:15:40 +02:00
Andreas Kling
d63b6287f5 Kernel: Add missing casts when calling AK::min() 2020-05-23 15:25:43 +02:00
Yonatan Goldschmidt
3a90a01dd4 Ext2FS: Fix indirect-blocks iteration
For singly-indirect blocks, "callback" is just "add_block".
For doubly-indirect blocks, "callback" is the lambda function
iterating on singly-indirect blocks: so instead of adding itself to the
list, the doubly-indirect block will add all its childs, but they add
themselves again when they run the callback of singly-indirect blocks.
And nothing adds the doubly-indirect block itself :(

This leads to a double free of all child blocks of the doubly-indirect
block, which is the failed assert described in #1549.

Closes: #1549.
2020-05-22 10:50:41 +02:00
Sergey Bugaev
88e23113ae Kernel: Tweak FileBackedFS API to avoid intermediary copies
read_block() and write_block() now accept the count (how many bytes to read
or write) and offset (where in the block to start; defaults to 0). Using these
new APIs, we can avoid doing copies between intermediary buffers in a lot more
cases. Hopefully this improves performance or something.
2020-05-19 11:07:35 +02:00