support lightweight copy (e.g. CoW in Btrfs)
Since Linux 4.5, system call FICLONE is supported, generalizing an earlier call specific to Btrfs, for support for efficient copy-on-write file operations. Since coreutils 8.26, calling cp will attempt this call if the --reflink argument is set to auto or always. Presently, if a gocryptfs file system sits above a file system with support for this operation, it is not possible to take advantage of such support from the underlying file system.
Following the older, closed discussion #62, occurring before some of the above changes, is this feature possible to consider at this time?
Looks like https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=88bc7d5097a1 has added copy_file_range support to FUSE in the Linux kernel. This may actually be possible now.
It is great that you think the enhancement is now possible. It would definitely help me not to lose the benefits of Btrfs lightweight copies simply because of the encrypted store above it.
Does this new copy_file_range call get mapped somehow to FICLONE? I am not experienced with file systems nor am I familiar with the FUSE architecture. I surely was not aware that FUSE has a separate operation set from the core kernel system calls, but, since applications are not generally aware of whether a file is on a FUSE-based FS, I must now assume that somewhere the fuse_opcode value gets mapped to a generic system call. In the case of cp, the FICLONE call is attempted if enabled by arguments, and, as I understand, graphical file managers are adding support. The comments refer to server-side copies, which is a similar idea to COW in some respects, but I am not aware that in practice it is handled by the same abstraction.
In your understanding, would an application calling FICLONE on a FUSE-based FS trigger the new FUSE operation if supported by that FS?
Does this new
copy_file_rangecall get mapped somehow toFICLONE?
I thought it does. But looking at the kernel code, FICLONE seems to only call clone_file_range.
The copy_file_range system call (manpage) exists since Linux 4.5 and is not fuse-specific. However, the cp tool from GNU coreutils does not seem to use it:
code/coreutils$ git grep copy_file_range
(empty)
:(
Somebody else noticing that cp does not use copy_file_range in April 2018: https://lkml.org/lkml/2018/4/27/995
I am becoming increasingly confused.
Since coreutils has used FICLONE since version 8.26, and if FICLONE as you say uses copy_file_range, then does not cp indirectly but effectively invoke copy_file_range?
No, FICLONE uses clone_file_range
Oops. I'm afraid that I fall far short of a compiler's capabilities with respect to consistently avoiding the conflation of non-identical symbol names.
Then, do I understand correctly the following?:
- Recently the kernel has added two new calls, capturing similar but distinct abstractions:
- The case of copy operations offloaded to a remote backend.
- The case of copy operations that utilize reflinks within a local store.
- At the snail's pace that new kernel features are supported by FUSE, the call relevant to this discussion is not now supported, though the other one has become supported.
Support for this feature would be useful. If adding support in FUSE is a simple change that the team has yet to include simply because of being unaware of the possibility, then it would be helpful to suggest this possibility to them.
In order for it to be possible to support reference-linked style copies in gocryptfs, what first needs to change outside of gocryptfs (e.g. kernel, FUSE), and what can gocryptfs users do to facilitate these changes?
I guess the first step is finding (or writing) a userspace tool that actually uses copy_file_range.
The building blocks in the kernel are there, I can add support to go-fuse.
My question relates to support with existing userspace tools, such as the copy command with the reflink feature. (See original comment.)
For example, if the current directory is on a btrfs mount, then the following command makes a lightweight (CoW) copy of file a:
% cp --reflink=auto a b
In most other contexts the auto option behaves the same as if the --reflink switch is omitted. Similarly, --reflink=always usually fails. However, in the case of the file system support being available, these commands create lightweight copies.
The issue is whether gocryptfs can be enhanced to support behavior similar to btrfs in the special case that the the gocryptfs system sits over btrfs (or in principle any fle system with support for lightweight copy).
In any case, it is good to keep the issue open, even if other issues currently take greater priority. I doubt little that as filesystems continue to improve, newer designs replacing older, that the use of lightweight copies will become increasingly common, and, eventually, universal. Meanwhile support in this project would contribute greatly to convenience for those who have come to rely both on the security afforded by this project as well as the convenience afforded by lightweight copies.
Has the feasibility or interest in this feature improved since the last time of discussion?
To be clear the request is that when existing userspace tools request a lightweight copy operation, as in cp --reflink=auto, on a gocryptfs file over btrfs, then the actual operation is indeed lightweight.
Trying to keep this feature open for consideration, I am continuing to add comments.
What is the main obstacle, if any currently exists, external to the project, that would prevent implementation, even if doing so interested a contributor?