Commit graph

106 commits

Author SHA1 Message Date
Ernest Wong
40ed4f8dde Filesystem: Simplify nlinks management across filesystems
Now that hard links aren't allowed across filesystems, it's ok to store
the relevant nlinks information within local inode.

For mountpoints (forwarder inodes that point to a root inode), it is
possible to bump the nlinks of the forwarder during link_under_dir and
unlink_from_dir so that this nlinks counter is modified independently
from the real inode's nlinks counter.

For divert(), it is actually ok to divert forwarder inodes that point to
hardlinked files, so I've relaxed the assertion predicate.
2020-08-30 19:29:54 -05:00
Ernest Wong
66cf97e0a7 Filesystem: Tidy comments, clarify nlinks special case. 2020-08-30 19:29:54 -05:00
Ernest Wong
6c61d48c8f Filesystem: Fix typo with path concatenation during Rename 2020-08-30 19:29:54 -05:00
Ernest Wong
c3739fc22a 9p: Disable filename tracking by default 2020-08-30 19:29:54 -05:00
Ernest Wong
c7dda46de1 Filesystem: Disallow hardlinks across filesystems
Although hardlinks across filesystems worked quite well in the current
implementation, we will run into problems when we try to implement
different backends for each sub-filesystem.

Note: EPERM is used instead of EXDEV since the mv command will silently
try to use copy-and-unlink when rename(2) fails with EXDEV.

The rules for linking has been reverted back:
 - Before commit: Any inode, including forwarders, could be linked as
long as the parent is not a forwarder and is a directory.
 - After commit: Only non-forwarders and root-forwarders are allowed to
be linked, and must be linked under a directory and not a forwarder.
2020-08-30 19:29:54 -05:00
Ernest Wong
1a7dc59f07 9p: Track filename during RENAMEAT 2020-08-30 19:29:54 -05:00
Ernest Wong
0d885e5e8c 9p: put dbg_name into state and document its limitations 2020-08-30 19:29:54 -05:00
Ernest Wong
2560394855 Filesystem: set unlinked status on the real inode
The real_inode's status is supposedly set to STATUS_UNLINKED when there
are no more references to the inode from other directories. Previously,
this status was incorrectly applied to the forwarder and not the actual
real_inode.
2020-08-30 19:29:54 -05:00
Ernest Wong
0595c11740 Filesystem: fix nlinks counting for mountpoints 2020-08-30 19:29:54 -05:00
Ernest Wong
8f4fcfa6f7 9p: return correct error code for link and unlink 2020-08-30 19:29:54 -05:00
Ernest Wong
5aa5c88bf8 Filesystem state: restore onto existing configuration
Don't create new filesystems based off from state file.
Don't overwrite fs.baseurl
2020-08-30 19:29:54 -05:00
Ernest Wong
5b456b64cb 9p: don't rely on inode.name for debug messages 2020-08-30 19:29:54 -05:00
Ernest Wong
d1519d4509 Filesystem: hard links, replace linked lists with Map.
Unfortunately, I didn't split this into multiple commits:

- Keeping track of nlinks is now all done by link_under_dir and
unlink_from_dir methods.

- Inodes are no longer associated with a name.

- Directory structure is now represented using a Map<name to idx>, so
the directory inode fully owns the directory entries instead a linked
list scattered across many inodes.

- The parameter order for FS#Link and FS#link_under_dir has been
modified to be consistent with 9p's: (dirid, fid, name)

- Allowed the movement of hardlinked files between filesystems
"vertically", as long as the target inode is reachable within the
filesystem and subfilesystems without ever having to traverse to the
parent filesystem.

- The methods FS#copy_inode and FS#divert does not put the filesystem in
an invalid state: FS#copy_inode does not modify inode.nlinks nor
inode.direntries, and FS#divert makes sure to delete the original nlinks
and direntries after it has been copied over to a new inode.

- Added extra assertions in FS#link_under_dir and FS#unlink_from_dir

- Forwarders should not be deleted upon unlink: the files are still
accessible.

- Non-root non-directory forwarders can now be linked under
non-forwarder directories for extra freedom for hardlinks. Now, the rule
for linking is: never link under a forwarder, and never link a directory
more than once.

Some tests and some 9p debug code is broken because they rely on
inode.name which no longer exists nor makes sense to exist.

Will fix in next commit.
2020-08-30 19:29:54 -05:00
Fabian
28ac891dc3 Filesystem: Load files via their sha256 2020-08-30 19:29:53 -05:00
Ernest Wong
6c55912a59 Fail early if unlink of destination failed for fs.Rename 2020-08-30 19:29:53 -05:00
Ernest Wong
7aa42c3418 Identify type of failure for fs.Unlink using -errno convention 2020-08-30 19:29:53 -05:00
Ernest Wong
fa3a961628 Handle unexpected error codes from filesystem 2020-08-30 19:29:53 -05:00
Ernest Wong
3a2ff7c47e Fix: fs.Rename should configure the correct filename
Specifically when moving a file from a mounted filesystem to the local
filesystem.
2020-08-30 19:29:53 -05:00
Ernest Wong
53edf989ea Fix: fs.divert should update children parentids
Otherwise, calling fs.divert leaves the filesystem in an invalid state.
2020-08-30 19:29:53 -05:00
Ernest Wong
e683e812fd Mount only onto non-existent paths, existent parent
If mountpoint already exists, then we're silently making its children
inaccessible which may not be what we expected/intended.

Create a new forwarder inode upon mounting.
2020-08-30 19:29:53 -05:00
Ernest Wong
3fe75a9130 Identify type of failure for fs.Rename using -errno convention 2020-08-30 19:29:53 -05:00
Ernest Wong
c66731d55d Properly forward fs.Open/CloseInode 2020-08-30 19:29:53 -05:00
Ernest Wong
23080e2731 Isolate filesystem qid counting to each v86 instance 2020-08-30 19:29:53 -05:00
Ernest Wong
8cb6f23248 Fix filesystem mount state saving 2020-08-30 19:29:53 -05:00
Ernest Wong
ff11e9c00f Minor: better rename-failure logs, comments, & unnecessary return 2020-08-30 19:29:53 -05:00
Ernest Wong
a063962311 Handle forwarding and root inode in other api methods
Root inode dosn't have a parent. Methods should work fine with root
inodes too.
2020-08-30 19:29:53 -05:00
Ernest Wong
121b9c3b96 Incorperate mounted filesystems in statistics 2020-08-30 19:29:53 -05:00
Ernest Wong
b6b6b8cada Implement Rename - moving files between filesystems 2020-08-30 19:29:53 -05:00
Ernest Wong
d98ec5f37b Handle forwarding for our dummy fs.Link method 2020-08-30 19:29:53 -05:00
Ernest Wong
71cb654502 Partially handle forwarding for fs.FillDirectory
Unresolved bug:
Calling fs.FillDirectory on a mountpoint gives incorrect information.
".." entry should describe parent of mountpoint, but currently describes
itself.
2020-08-30 19:29:53 -05:00
Ernest Wong
687607569b Handle forwarding for open, close, read, and write 2020-08-30 19:29:53 -05:00
Ernest Wong
004182adc8 Handle forwarding for fs.Create* methods 2020-08-30 19:29:53 -05:00
Ernest Wong
d218b76994 Handle forwarding for fs events and file loading 2020-08-30 19:29:53 -05:00
Ernest Wong
b080b075bd Handle forwarding in fs.Unlink 2020-08-30 19:29:53 -05:00
Ernest Wong
3fcdf62eef Fix fs.GetFullPath and fs.FindPreviousID forwarding
Use this.GetInode(idx) to get metadata such as filename and size.
Use this.inodes to navigate about the filesystem graph
2020-08-30 19:29:53 -05:00
Ernest Wong
ce0bd6624f Abstract away procedure for unlinking and linking an inode 2020-08-30 19:29:53 -05:00
Ernest Wong
4e4c62bb2b Mount-aware accessors: GetInode/Parent/Children 2020-08-30 19:29:53 -05:00
Ernest Wong
1499b7dc6f Make inode qid numbers unique across filesystems
Storing the same global qid counter into every filesystem state is not ideal,
but not sure if there's a better place to store it for state saving and
restoring.
2020-08-30 19:29:53 -05:00
Ernest Wong
d78f722a38 Fix fs.SearchPath 2020-08-30 19:29:53 -05:00
Ernest Wong
e6ef68b334 Introduce forwarding inodes. Implement fs.Mount
Add forward_path info to fs.SearchPath.
Handle forwarding for fs.Search.
2020-08-30 19:29:53 -05:00
Ernest Wong
9e592dbd84 Decouple 9p and starter from fs's internal structure
Part of changes to support fs mounting on the host side.
Inode attributes are generally left untouched as field accesses.
2020-08-30 19:29:53 -05:00
Fabian
a30b5b7eb3 Filesystem: Make copy of restored files to avoid link to state buffer 2020-08-30 19:29:53 -05:00
Ernest Wong
2d234003b9 Fix 9p capabilities test: getxattr expects revision 2+ format
Even though some man pages say that linux continues to support
capabilities revision 1, it seems that when cap_inode_getsecurity
handles the retrieval of security.capability, it throws an EINVAL when
the revision number is not 2 nor 3.

At time of writing, the code of interest is at:
line 415 of linux/security/commoncap.c

Also watch out for when it converts revision 3 caps data into revision 2
caps data in certain situations.
2020-08-30 19:29:53 -05:00
Ernest Wong
8f0bba4b1f Fix hang during setxattr: send error instead of ignore write 2020-08-30 19:29:53 -05:00
Ernest Wong
ba8ab574b5 9P: Don't write xattr data into actual file contents
Wait for proper xattr support.
2020-08-30 19:29:53 -05:00
Ernest Wong
65f7b68185 Remove trailing spaces in lib/* 2020-08-30 19:29:13 -05:00
Fabian
99d50b6ba0 Fix atime/ctime/mtime of newly created nodes 2020-08-30 19:29:13 -05:00
Fabian
74f2756e08 Filesystem: Mark written files as dirty 2020-08-30 19:29:13 -05:00
Ernest Wong
bda133ba49 JSHint the lib directory 2020-08-30 19:29:13 -05:00
Ernest Wong
46d48c4070 RoundToDirentry - Use existing directory data 2020-08-30 19:29:13 -05:00