Commit graph

191 commits

Author SHA1 Message Date
Brian Gianforcaro
f05086a5d2 Kernel: Harden Ext2FileSystem Vector usage against OOM. 2021-05-01 09:10:30 +02:00
Andreas Kling
cd9be1733c Kernel: Make Inode::set_{a,c,m}time return KResult
This exposed some missing error propagation, which this patch also
takes care of.
2021-04-30 15:51:06 +02:00
Andreas Kling
3d4afe7614 Everywhere: "indexes" => "indices"
I've wasted a silly amount of time in the past fretting over which
of these words to use. Let's just choose one and use it everywhere. :^)
2021-04-29 22:23:52 +02:00
Brian Gianforcaro
8d6e9fad40 Kernel: Remove the now defunct LOCKER(..) macro. 2021-04-25 09:38:27 +02:00
Andreas Kling
b91c49364d AK: Rename adopt() to adopt_ref()
This makes it more symmetrical with adopt_own() (which is used to
create a NonnullOwnPtr from the result of a naked new.)
2021-04-23 16:46:57 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Andreas Kling
3f5c934ea6 Ext2FS: Put bg_used_dirs_count debug logging behind EXT2_DEBUG 2021-04-20 15:08:56 +02:00
Andreas Kling
acebc9beaf Ext2FS: Use if-with-initializer a lot more
This pattern felt really cluttery:

auto result = something();
if (result.is_error())
    return result;

Since it leaves "result" lying around in the no-error case.
Let's use some C++17 if initializer expressions to improve this:

if (auto result = something(); result.is_error())
    return result;

Now the "result" goes out of scope if we don't need it anymore.
This is doubly nice since we're also free to reuse the "result"
name later in the same function.
2021-04-11 00:33:16 +02:00
Andreas Kling
642b428793 Ext2FS: Support reading from file holes
It's perfectly valid for ext2 inodes to have blocks with index 0.
It means that no physical block was allocated for that area of an inode
and we should treat it as if it's filled with zeroes.

Fixes #6139.
2021-04-10 11:09:43 +02:00
Andreas Kling
b5b38d372c Ext2FS: Clarify error handling in Ext2FSInode::read_bytes() somewhat 2021-04-10 10:58:19 +02:00
Andreas Kling
5001b71c42 Kernel: Reading past the end of an Ext2FSInode should return 0
Fixes #5763.
2021-04-04 17:21:07 +02:00
Jean-Baptiste Boric
eea5a5ed5d Kernel: Make block-based file system code 64 bit ready 2021-03-19 09:15:19 +01:00
Jean-Baptiste Boric
71b433a6f9 Kernel: Add 64 bit file size support to Ext2FS 2021-03-17 23:22:42 +01:00
Jean-Baptiste Boric
aeef14ae28 Kernel: Rationalize logs inside Ext2Fs 2021-03-17 23:22:42 +01:00
Jean-Baptiste Boric
800dca3834 Kernel: Implement triply indirect block support in Ext2FSInode 2021-03-13 09:27:18 +01:00
Jean-Baptiste Boric
facd18113b Kernel: Modify block lists in place for Ext2FSInode::resize()
This significantly reduces the number of allocations/deallocations
inside the kernel when growing files as well as reducing spam in the
kernel logs.
2021-03-13 09:27:18 +01:00
Andreas Kling
e58a600d52 Kernel: Remove VLA usage in Ext2FS block traversal code
This was using up to 12KB of kernel stack in the triply indirect case
and looks generally spooky. Let's just allocate a ByteBuffer for now
and take the performance hit (of heap allocation). Longer term we can
reorganize the code to reduce the majority of the heap churn.
2021-03-10 16:33:47 +01:00
Andreas Kling
10f10abaa3 Kernel: Convert klog() => dmesgln() in filesystem code 2021-03-09 22:10:41 +01:00
Andreas Kling
2871df6f0d Kernel: Stop trying to keep InodeVMObject in sync with disk changes
As it turns out, Dr. POSIX doesn't require that post-mmap() changes
to a file are reflected in the memory mappings. So we don't actually
have to care about the file size changing (or the contents.)

IIUC, as long as all the MAP_SHARED mappings that refer to the same
inode are in sync, we're good.

This means that VMObjects don't need resizing capabilities. I'm sure
there are ways we can take advantage of this fact.
2021-03-04 15:42:51 +01:00
Andreas Kling
a1d1a3b50b Kernel: Use BitmapView instead of Bitmap::wrap() 2021-03-04 11:25:45 +01:00
Ben Wiederhake
336303bda4 Kernel: Make kgettimeofday use AK::Time 2021-03-02 08:36:08 +01:00
Andreas Kling
69a30f95cc Ext2FS: Make block list flushing a bit less aggressive
We don't need to flush the on-disk inode struct multiple times while
writing out its block list. Just mark the in-memory Inode as having
dirty metadata and the SyncTask will flush it eventually.
2021-02-26 18:24:40 +01:00
Andreas Kling
c3a0fd4b7a Ext2FS: Move block list computation from Ext2FS to Ext2FSInode
Since the inode is the logical owner of its block list, let's move the
code that computes the block list there, and also stop hogging the FS
lock while we compute the block list, as there is no need for it.
2021-02-26 18:14:02 +01:00
Andreas Kling
c09921b9be Ext2FS: Don't hog FS lock while reading/writing inodes
There are two locks in the Ext2FS implementation:

* The FS lock (Ext2FS::m_lock)
  This governs access to the superblock, block group descriptors,
  and the block & inode bitmap blocks. It's held while allocating
  or freeing blocks/inodes.

* The inode lock (Ext2FSInode::m_lock)
  This governs access to the inode metadata, including the block
  list, and to the content data as well. It's held while doing
  basically anything with the inode.

Once an on-disk block/inode is allocated, it logically belongs
to the in-memory Inode object, so there's no need for the FS lock
to be taken while manipulating them, the inode lock is all you need.

This dramatically reduces the impact of disk I/O on path resolution
and various other things that look at individual inodes.
2021-02-26 17:57:38 +01:00
Andreas Kling
c7c63727bf Ext2FS: Remove unnecessary locking in find_block_containing_inode()
This is just a bunch of index math based on immutable values in the
super block and block group descriptor. No need to lock here!
2021-02-26 17:24:39 +01:00
Andreas Kling
81e3ea29c3 Ext2FS: Remove unnecessary lock in Ext2FS::write_ext2_node()
Now that writing to the underlying storage is serialized, we don't
need to take the FS lock when writing out an inode struct.
2021-02-26 17:23:46 +01:00
Andreas Kling
65e083ed36 Revert "Ext2FS: Don't reload already-cached block list when freeing inode"
This reverts commit 1e737a5c50.

The cached block list does not include meta-blocks, so we'd end up
leaking those. There's definitely a nice way to avoid work here, but it
turns out it wasn't quite this trivial. Reverting for now.
2021-02-26 14:57:00 +01:00
Andreas Kling
1e737a5c50 Ext2FS: Don't reload already-cached block list when freeing inode
If we already have a cached copy of the inode's block list, we can use
that to free the blocks. No need to reload the list.
2021-02-26 14:05:18 +01:00
Andreas Kling
1f9409a658 Ext2FS: Inode allocation improvements
This patch combines inode the scan for an available inode with the
updating of the bit in the inode bitmap into a single operation.

We also exit the scan immediately when we find an inode, instead of
continuing until we've scanned all the eligible groups(!)

Finally, we stop holding the filesystem lock throughout the entire
operation, and instead only take it while actually necessary
(during inode allocation, flush, and inode cache update.)
2021-02-26 14:05:18 +01:00
Andreas Kling
19083fd760 Ext2FS: Propagate errors from more places
Improve a bunch of situations where we'd previously panic the kernel
on failure. We now propagate whatever error we had instead. Usually
that'll be EIO.
2021-02-26 14:05:18 +01:00
Andreas Kling
6352b4fd74 Ext2FS: Share some bitmap code between inode and block allocation
Both inode and block allocation operate on bitmap blocks and update
counters in the superblock and group descriptor.

Since we're here, also add some error propagation around this code.
2021-02-26 14:05:18 +01:00
Andreas Kling
5d180d1f99 Everywhere: Rename ASSERT => VERIFY
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)

Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.

We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
2021-02-23 20:56:54 +01:00
Brian Gianforcaro
cbd8f78cce Kernel: Use uniform initialization instead of memset for a few stack buffer.
Raw memset is relatively easy to mess up, avoid it when there are
better alternatives provided by the compiler in modern C++.
2021-02-21 11:52:47 +01:00
Brian Gianforcaro
7c950c2d01 Kernel: Use ByteBuffer::zero_fill() instead of raw memset in Ext2
There was a typo in one of the memsets, use the type safe wrapper instead.

Fix EXt
2021-02-21 11:52:47 +01:00
Jean-Baptiste Boric
9ce0639383 Kernel: Use divide_rounded_up inside write_block_list_for_inode 2021-02-13 19:56:49 +01:00
Jean-Baptiste Boric
869b33d6dd Kernel: Support triply indirect blocks for BlockListShape computation 2021-02-13 19:56:49 +01:00
Andreas Kling
c62c00e7db Ext2FS: Make Ext2FS::GroupIndex a distinct integer type 2021-02-12 13:33:58 +01:00
Andreas Kling
489317e573 Kernel: Make BlockBasedFS::BlockIndex a distinct integer type 2021-02-12 11:59:27 +01:00
Andreas Kling
e44c1792a7 Kernel: Add distinct InodeIndex type
Use the DistinctNumeric mechanism to make InodeIndex a strongly typed
integer type.
2021-02-12 10:26:29 +01:00
Andreas Kling
95064f8b58 Ext2FS: Convert #if EXT2_DEBUG => dbgln_if() and constexpr-if 2021-02-11 23:05:16 +01:00
Andreas Kling
a280cdf9ba Ext2FS: Shrink Ext2FSDirectoryEntry from 16 to 12 bytes
The way we read/write directories is very inefficient, and this doesn't
solve any of that. It does however reduce memory usage of directory
entry vectors by 25% which has nice immediate benefits.
2021-02-11 22:45:50 +01:00
Andreas Kling
4c0707e56c Kernel: Don't create a zero-length VLA in Ext2FS block list walk
Found by KUBSAN :^)
2021-02-05 21:23:11 +01:00
Andreas Kling
d4f40241f1 Ext2FS: Avoid unnecessary parent inode lookup during inode creation
Creation of new inodes is always driven by the parent inode, so we can
just refer directly to it instead of looking up the parent by ID.
2021-02-02 18:58:26 +01:00
Andreas Kling
9e4dd834ab Ext2FS: Simplify inode creation by always starting empty
We had two ways of creating a new Ext2FS inode. Either they were empty,
or they started with some pre-allocated size.

In practice, the pre-sizing code path was only used for new directories
and it didn't actually improve anything as far as I can tell.

This patch simplifies inode creation by simply always allocating empty
inodes. Block allocation and block list generation now always happens
on the same code path.
2021-02-02 18:58:26 +01:00
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