This FIXME does not seem to apply anymore. Yes, symbolic links in all
filesystems appear to be slightly broken, but that has nothing to do
with File::absolute_path. Let's remove the wrong FIXME instead of adding
to the confusion.
Found due to smelly code in InodeFile::absolute_path.
In particular, this replaces the following misleading methods:
File::absolute_path
This method *never* returns an actual path, and if called on an
InodeFile (which is impossible), it would VERIFY_NOT_REACHED().
OpenFileDescription::try_serialize_absolute_path
OpenFileDescription::absolute_path
These methods do not guarantee to return an actual path (just like the
other method), and just like Custody::absolute_path they do not
guarantee accuracy. In particular, just renaming the method made a
TOCTOU bug obvious.
The new method signatures use KResultOr, just like
try_serialize_absolute_path() already did.
Forcing the formatting to go through `Formatter<FormatString>` is
completely unnecessary, increases code size, performs a String
allocation and prevents us from using the formatting options available
on that type.
This commit also removes explicit formatters from
`BlockBasedFileSystem::BlockIndex` and `Kernel::InodeIndex`, as those
are already covered by the blanket implementation for all
`DistinctNumeric` types.
ProcFSGlobalInode now calls `write_bytes()`, `truncate()` and
`set_mtime()` on its associated component. This allows us to write 0 or
1 to a ProcFSSystemBoolean component to toggle a boolean value.
The platform independent Processor.h file includes the shared processor
code and includes the specific platform header file.
All references to the Arch/x86/Processor.h file have been replaced with
a reference to Arch/Processor.h.
Normally, trying to truncate a SysFSInode should result in EPERM error.
However, as suggested by Ali (@alimpfard), we can allow the PowerState
node to be "truncated" so one can open that file with O_TRUNC option.
Likewise, we also need to provide a way to set modified time on SysFS
inodes. For most inodes, we should return ENOTIMPL error, but for the
power state switch, we ignore the modified time setting and just return
KSuccess.
These fixes allow to do "echo -n 1 > /sys/firmware/power_state" in Shell
after gaining root permissions, to switch the power state.
Previously there was a mix of returning plain strings and returning
explicit string views using `operator ""sv`. This change switches them
all to standardized on `operator ""sv` as it avoids a call to strlen.
This singleton simplifies many aspects that we struggled with before:
1. There's no need to make derived classes of Device expose the
constructor as public anymore. The singleton is a friend of them, so he
can call the constructor. This solves the issue with try_create_device
helper neatly, hopefully for good.
2. Getting a reference of the NullDevice is now being done from this
singleton, which means that NullDevice no longer needs to use its own
singleton, and we can apply the try_create_device helper on it too :)
3. We can now defer registration completely after the Device constructor
which means the Device constructor is merely assigning the major and
minor numbers of the Device, and the try_create_device helper ensures it
calls the after_inserting method immediately after construction. This
creates a great opportunity to make registration more OOM-safe.
Because we were holding a strong ref to the OpenFileDescription in
LocalSocket and a strong ref to the LocalSocket in Inode, we were
creating a reference cycle in the event of the socket being cleaned up
after the file description did (i.e. unlinking the file before closing
the socket), because the file description never got destructed.
Instead of doing so in the constructor, let's do immediately after the
constructor, so we can safely pass a reference of a Device, so the
SysFSDeviceComponent constructor can use that object to identify whether
it's a block device or a character device.
This allows to us to not hold a device in SysFSDeviceComponent with a
RefPtr.
Also, we also call the before_removing method in both SlavePTY::unref
and File::unref, so because Device has that method being overrided, it
can ensure the device is removed always cleanly.
We are no longer have a separate Inode object class for the pts
directory. With a small exception to this, all chmod and chown code
is now at one place.
It's now possible to create any name of a sub-directory in the
filesystem.
The current implementation of DevFS resembles the linux devtmpfs, and
not the traditional DevFS, so let's rename it to better represent the
direction of the development in regard to this filesystem.
The abbreviation for DevTmpFS is still "dev", because it doesn't add
value as a commandline option to make it longer.
In quick summary - DevFS in unix OSes is simply a static filesystem, so
device nodes are generated and removed by the kernel code. DevTmpFS
is a "modern reinvention" of the DevFS, so it is much more like a TmpFS
in the sense that not only it's stored entirely in RAM, but the userland
is responsible to add and remove devices nodes as it sees fit, and no
kernel code is directly being involved to keep the filesystem in sync.
In order to make this kind of operation simpler, we no longer use a
Vector to store pointers to DevFSDeviceInode, but an IntrusiveList is
used instead. Also, we only allow to remove device nodes for now, but
in theory we can allow to remove all kinds of files from the DevFS.
These files are not marked as block devices or character devices so they
are not meant to be used as device nodes. The filenames are formatted to
the pattern "major:minor", but a Userland program need to call the parse
these format and inspect the the major and minor numbers and create the
real device nodes in /dev.
Later on, it might be a good idea to ensure we don't create new
SysFSComponents on the heap for each Device, but rather generate
them only when required (and preferably to not create a SysFSComponent
at all if possible).
Don't create these device nodes in the Kernel, so we essentially enforce
userspace (SystemServer) to take control of this operation and to decide
how to create these device nodes.
This makes the DevFS to resemble linux devtmpfs, and allows us to remove
a bunch of unneeded overriding implementations of device name creation
in the Kernel.
This patch adds KBufferBuilder::try_create() and treats it like anything
else that can fail. And so, failure to allocate the initial internal
buffer of the builder will now propagate an ENOMEM to the caller. :^)
- Renamed try_create_absolute_path() => try_serialize_absolute_path()
- Use KResultOr and TRY() to propagate errors
- Don't call this when it's only for debug logging