summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem/Ext2FileSystem.cpp
AgeCommit message (Collapse)Author
2021-05-13Kernel: Replace make<T>() with adopt_own_if_nonnull() in Ext2FileSystemBrian Gianforcaro
The make<T> factory function allocates internally and immediately dereferences the pointer, and always returns a NonnullOwnPtr<T> making it impossible to propagate an error on OOM.
2021-05-12Kernel: Implement multi-watch InodeWatcher :^)sin-ack
This patch modifies InodeWatcher to switch to a one watcher, multiple watches architecture. The following changes have been made: - The watch_file syscall is removed, and in its place the create_iwatcher, iwatcher_add_watch and iwatcher_remove_watch calls have been added. - InodeWatcher now holds multiple WatchDescriptions for each file that is being watched. - The InodeWatcher file descriptor can be read from to receive events on all watched files. Co-authored-by: Gunnar Beutner <gunnar@beutner.name>
2021-05-08Kernel: Traverse ext2 directories blockwise.Mart G
Instead of reading in the entire contents of a directory into a large buffer, we can iterate block by block. This only requires a small buffer. Because directory entries are guaranteed to never span multiple blocks we do not have to handle any edge cases related to that.
2021-05-08Kernel: Place ext2 dir entries so they don't span multiple blocksMart G
Ext2 dir entries spanning multiple blocks are not allowed. If they do occur they are flagged as corrupt by e2fsck for example.
2021-05-07Kernel: Allow Ext2FSInode::write_bytes calls with a byte count of zeroMart G
write_bytes is called with a count of 0 bytes if a directory is being deleted, because in that case even the . and .. pseudo directories are getting removed. In this case write_bytes is now a no-op. Before write_bytes would fail because it would check to see if there were any blocks available to write in (even though it wasn't going to write in them anyway). This behaviour was uncovered because of a recent change where directories are correctly reduced in size. Which in this case results in all the blocks being removed from the inode, whereas previously there would be some stale blocks around to pass the check.
2021-05-07Kernel: Set unused block pointers in ext2 inodes to zeroMart G
e2fsck considers all blocks reachable through any of the pointers in m_raw_inode.i_block as part of this inode regardless of the value in m_raw_inode.i_size. When it finds more blocks than the amount that is indicated by i_size or i_blocks it offers to repair the filesystem by changing those values. That will actually cause further corruption. So we must zero all pointers to blocks that are now unused.
2021-05-06Kernel: Resize Ext2FSInode when writing directory contents (#6897)Mart G
Ext2 directory contents are stored in a linked list of ext2_dir_entry structs. There is no sentinel value to determine where the list ends. Instead the list fills the entirety of the allocated space for the inode. Previously the inode was not correctly resized when it became smaller. This resulted in stale data being interpreted as part of the linked list of directory entries.
2021-05-03Kernel: Fix some 64-bit portability issuesGunnar Beutner
2021-05-02Kernel: Change Inode::{read/write}_bytes interface to KResultOr<ssize_t>Brian Gianforcaro
The error handling in all these cases was still using the old style negative values to indicate errors. We have a nicer solution for this now with KResultOr<T>. This change switches the interface and then all implementers to use the new style.
2021-05-01Kernel: Harden Ext2FileSystem Vector usage against OOM.Brian Gianforcaro
2021-04-30Kernel: Make Inode::set_{a,c,m}time return KResultAndreas Kling
This exposed some missing error propagation, which this patch also takes care of.
2021-04-29Everywhere: "indexes" => "indices"Andreas Kling
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-25Kernel: Remove the now defunct `LOCKER(..)` macro.Brian Gianforcaro
2021-04-23AK: Rename adopt() to adopt_ref()Andreas Kling
This makes it more symmetrical with adopt_own() (which is used to create a NonnullOwnPtr from the result of a naked new.)
2021-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
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-20Ext2FS: Put bg_used_dirs_count debug logging behind EXT2_DEBUGAndreas Kling
2021-04-11Ext2FS: Use if-with-initializer a lot moreAndreas Kling
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-10Ext2FS: Support reading from file holesAndreas Kling
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-10Ext2FS: Clarify error handling in Ext2FSInode::read_bytes() somewhatAndreas Kling
2021-04-04Kernel: Reading past the end of an Ext2FSInode should return 0Andreas Kling
Fixes #5763.
2021-03-19Kernel: Make block-based file system code 64 bit readyJean-Baptiste Boric
2021-03-17Kernel: Add 64 bit file size support to Ext2FSJean-Baptiste Boric
2021-03-17Kernel: Rationalize logs inside Ext2FsJean-Baptiste Boric
2021-03-13Kernel: Implement triply indirect block support in Ext2FSInodeJean-Baptiste Boric
2021-03-13Kernel: Modify block lists in place for Ext2FSInode::resize()Jean-Baptiste Boric
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-10Kernel: Remove VLA usage in Ext2FS block traversal codeAndreas Kling
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-09Kernel: Convert klog() => dmesgln() in filesystem codeAndreas Kling
2021-03-04Kernel: Stop trying to keep InodeVMObject in sync with disk changesAndreas Kling
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-04Kernel: Use BitmapView instead of Bitmap::wrap()Andreas Kling
2021-03-02Kernel: Make kgettimeofday use AK::TimeBen Wiederhake
2021-02-26Ext2FS: Make block list flushing a bit less aggressiveAndreas Kling
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-26Ext2FS: Move block list computation from Ext2FS to Ext2FSInodeAndreas Kling
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-26Ext2FS: Don't hog FS lock while reading/writing inodesAndreas Kling
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-26Ext2FS: Remove unnecessary locking in find_block_containing_inode()Andreas Kling
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-26Ext2FS: Remove unnecessary lock in Ext2FS::write_ext2_node()Andreas Kling
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-26Revert "Ext2FS: Don't reload already-cached block list when freeing inode"Andreas Kling
This reverts commit 1e737a5c50837a9746bcbf8762f9f45caa332787. 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-26Ext2FS: Don't reload already-cached block list when freeing inodeAndreas Kling
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-26Ext2FS: Inode allocation improvementsAndreas Kling
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-26Ext2FS: Propagate errors from more placesAndreas Kling
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-26Ext2FS: Share some bitmap code between inode and block allocationAndreas Kling
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-23Everywhere: Rename ASSERT => VERIFYAndreas Kling
(...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-21Kernel: Use uniform initialization instead of memset for a few stack buffer.Brian Gianforcaro
Raw memset is relatively easy to mess up, avoid it when there are better alternatives provided by the compiler in modern C++.
2021-02-21Kernel: Use ByteBuffer::zero_fill() instead of raw memset in Ext2Brian Gianforcaro
There was a typo in one of the memsets, use the type safe wrapper instead. Fix EXt
2021-02-13Kernel: Use divide_rounded_up inside write_block_list_for_inodeJean-Baptiste Boric
2021-02-13Kernel: Support triply indirect blocks for BlockListShape computationJean-Baptiste Boric
2021-02-12Ext2FS: Make Ext2FS::GroupIndex a distinct integer typeAndreas Kling
2021-02-12Kernel: Make BlockBasedFS::BlockIndex a distinct integer typeAndreas Kling
2021-02-12Kernel: Add distinct InodeIndex typeAndreas Kling
Use the DistinctNumeric mechanism to make InodeIndex a strongly typed integer type.
2021-02-11Ext2FS: Convert #if EXT2_DEBUG => dbgln_if() and constexpr-ifAndreas Kling
2021-02-11Ext2FS: Shrink Ext2FSDirectoryEntry from 16 to 12 bytesAndreas Kling
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.