Previously the check for an empty part would happen before the
check for access and for the parent being a directory, and so an
error in those would not be detected.
If a symlink is not the last part of a path, the remaining part
of the path has to be further resolved against the symlink target.
With this, a path containing a symlink always resolves to the target
of the first (leftmost) symlink in it, for example any path of form
/proc/self/... resolves to the corresponding /proc/pid directory.
StringView character buffer is not guaranteed to be null-terminated;
in particular it will not be null-terminated when making a substring.
This means that the buffer can not be used with C functions that expect
a null-terminated string. Instead, StringView provides a convinient
operator == for comparing it with Strings and C stirngs, so use that.
This fixes /proc/self/... resolution failures in ProcFS, since the name
("self") passed to ProcFSInode::lookup() would not be null-terminated.
This significantly reduces the pressure on the kernel heap when
allocating a lot of pages.
Previously at about 250MB allocated, the free page list would outgrow
the kernel's heap. Given that there is no longer a page list, this does
not happen.
The next barrier will be the kernel memory used by the page records for
in-use memory. This kicks in at about 1GB.
After reading a bunch of POSIX specs, I've learned that a file descriptor
is the number that refers to a file description, not the description itself.
So this patch renames FileDescriptor to FileDescription, and Process now has
FileDescription* file_description(int fd).
Walk the custody cache and try to reuse an existing one when possible.
The VFS is responsible for updating them when something happens that would
cause the described relationship to change.
This is definitely not perfect but it does work for the basic scenarios like
renaming and removing directory entries.
When encountering a symlink, we abandon the custody chain we've been working
on and start over with a new one (by recursing into a new resolution call.)
Caching symlinks in the custody model would be incredibly difficult to get
right with all the extra invalidation it would require, so let's just not.
The current working directory is now stored as a custody. Likewise for a
process executable file. This unbreaks /proc/PID/fd which has not been
working since we made the filesystem bigger.
This still needs a bunch of work, for instance when renaming or removing
a file somewhere, we have to update the relevant custody links.
A custody is kind of a directory entry abstraction that represents a single
entry in a parent directory that tells us the name of a child inode.
The idea here is for path resolution to produce a chain of custody objects.
Also run it across the whole tree to get everything using the One True Style.
We don't yet run this in an automated fashion as it's a little slow, but
there is a snippet to do so in makeall.sh.