3 ms·
Yes, in theory, any filesystem could trivially add a feature of "ref-counted immutable extents" — where a special syscall equivalent to `cat a b c > d` could be
by derefr 2y ago
Yes, in theory, any filesystem could trivially add a feature of "ref-counted immutable extents" — where a special syscall equivalent to `cat a b c > d` could be implemented that creates an inode d that consists of references to the existing extents of a+b+c.
(The shared extents have to be immutable, because on non-CoW filesystems, filesystem locks apply to "byte ranges of inodes", not to extents or slices thereof; so extents could only be safely shared between inodes if they forced the inodes referencing them to act as if they were always reader-locked.)
You could even implement this on e.g. Linux ext4 today — you could consider extents immutable if they're part of an immutable (chattr +i) file that has no additional hard links; and you could prevent any files that are "sharing" immutable extents from being made non-immutable (where in the above, the syscall would create a file that is immediately immutable.)
This would basically result in the same semantics + efficiencies that you get with "composite uploads" in an object store.
---
Given a CoW filesystem, you could probably extend this concept to allow arbitrary CoW blocks to be explicitly referenced from file A into file B without any need for immutability — it'd just be an explicit "partial" reflink. (This is already possible for the simple A->B case, by starting with a CoW clone, and then overwriting the blocks that shouldn't be shared. But more complex cases like A+B+C->D above, aren't possible; nor is having those shared blocks be in a different position in the clone than they are in the original; and so forth.)
It wouldn't quite work like you're imagining with sendfile(2), though, because the CoW sharing could only occur at filesystem-block boundaries. You still wouldn't be able to use partial reflinking to optimize the operation of e.g. adding three bytes of header to a file (unless you also added BLKSZ-3 bytes of padding.)