Since the VFS renaming refactor, this function has only been used for
hardlinking, which isn't possible on FATFS since there's no real concept
of inodes or anything comparable to those.
Now we no longer compute the cluster list at the exact moment when an
in-memory inode is created, but rather defer doing that until we
actually need the cluster list. This distinction is important when
traversing directories, as we *are* interested in the inode, but not
really in its contents (though now we do have to resort to using the
file size to approximate the amount of allocated blocks, but this
shouldn't be an issue when working with well-formed filesystems.)
Plain resizes (that increase file size) are now much faster, as the
zeroing is now done in a more efficient way (rather than just looping
over `write_bytes_locked`.) Writes should also be faster, since we no
longer zero out the underlying bytes if we are going to write something
in that very same location anyway.
Previously, the VFS layer would try to handle renames more-or-less by
itself, which really only worked for ext2, and even that was only due to
the replace_child kludge existing specifically for this purpose. This
never worked properly for FATFS, since the VFS layer effectively
depended on filesystems having some kind of reference-counting for
inodes, which is something that simply doesn't exist on any FAT variant
we support.
To resolve various issues with the existing scheme, this commit makes
filesystem implementations themselves responsible for the actual rename
operation, while keeping all the existing validation inside the VFS
layer. The only intended behavior change here is that rename operations
should actually properly work on FATFS.
There were two separate issues at play which made this work incorrectly.
The first was that the newly allocated block was incorrectly computed,
because it was assumed that the cached block list was updated when a new
cluster was allocated. The second issue was that there was an off-by-one
in the loop that collected the newly allocated entries, which meant that
the resulting list had an entry less than what was requested.
The old overload still depended on m_entry being initialized, which
meant that (due to where this method is used) all inodes ended up
getting the same index.
This is a large commit because it implements a lot of stuff to make
add_child simpler to get working. This allows us to create new files
on a FAT partition.
This is the first part of write support, it allows for full file
modification, but no creating or removing files yet.
Co-Authored-By: implicitfield <114500360+implicitfield@users.noreply.github.com>
Caching the cluster list allows us to fill the two fields in the
InodeMetadata. While at it, don't cache the metadata as when we
have write support having to keep both InodeMetadata and FATEntry
correct is going to get very annoying.
This never was a logical block size, it always was a device specific
block size. Ideally the block size would change in accordance to
whatever the driver wants to use, but that is a change for the future.
For now, let's get rid of this confusing naming.
This has KString, KBuffer, DoubleBuffer, KBufferBuilder, IOWindow,
UserOrKernelBuffer and ScopedCritical classes being moved to the
Kernel/Library subdirectory.
Also, move the panic and assertions handling code to that directory.
Apparently we lacked this important check from the beginning of this
piece of code. This check is crucial to ensure we only give back data
being related to the FATInode data buffer and nothing beyond it.
* Fix bug where last character of a filename or extension would be
truncated (HELLO.TXT -> HELL.TX).
* Fix bug where additional NULL characters would be added to long
filenames that did not completely fill one of the Long Filename Entry
character fields.
Because the ".." entry in a directory is a separate inode, if a
directory is renamed to a new location, then we should update this entry
the point to the new parent directory as well.
Co-authored-by: Liav A <liavalb@gmail.com>