There is a handful of options dealing with symlinks (follow_symlinks, contain_symlinks plus jail_symlinks on the FUSE side) but all of them except follow_symlinks are restrictive options that essentially hide remote symlinks from the remote machine. I see little benefit in these options (except for some extra security when connecting to unknown hosts) in practical terms.
And follow_symlinks is too broad. It effectively disables symlink support on the remote machine through SSHFS completely (even if the remote supports them just fine) which something not often usable as well.
The idea of -o follow_outside_symlinks is as follows:
- remote symlinks that resolve to an object within the mounted remote directory are presented as normal symlinks preserving all semantics (effectively what SSHFS already does without
follow_symlinks or any other symlink options).
- remote symlinks that resolve to an object outside the mounted remote directory are virtualised on the client side as non-symlink dirs and files (effectively what
follow_symlinks already does).
This appears to be a sweet spot that will preserve symlink semantics where possible and at the same time will make all content of the remote directory normally accessible to its respective local user accessible via SSHFS.
The implementation looks relatively straightforward (for outside symlinks, inside symlinks are processed normally):
stat() → stat() of the final remote target
lstat() → same as stat() (to hide `S_IFLNK` on the SSHFS side)
open() → open target
opendir() → opendir target
readdir() → target contents (replace `S_IFLNK` entries with `stat` results for outside symlinks)
readlink() → EINVAL
unlink(),
rmdir(),
rename() → EPERM
chmod(),
chown(),
etc → operate on target
EPERM for unlink and similar is needed because this operation is irreversible on the SSHFS side (it's impossible to create the same object that it was before since the contents outside the mounted directory is fundamentally inaccessible).
chmod and company is another story - changing the target is exactly the same which would happen locally and it's reversible, so SSHFS should expose it as is. And returning EPERM for those will break many apps so it's not the right thing to do.
Any FS operation on broken, circular and all other outside symlinks for which SFTP REALPATH returns a failure should result in EPERM too I believe.
There is a handful of options dealing with symlinks (
follow_symlinks,contain_symlinksplusjail_symlinkson the FUSE side) but all of them exceptfollow_symlinksare restrictive options that essentially hide remote symlinks from the remote machine. I see little benefit in these options (except for some extra security when connecting to unknown hosts) in practical terms.And
follow_symlinksis too broad. It effectively disables symlink support on the remote machine through SSHFS completely (even if the remote supports them just fine) which something not often usable as well.The idea of
-o follow_outside_symlinksis as follows:follow_symlinksor any other symlink options).follow_symlinksalready does).This appears to be a sweet spot that will preserve symlink semantics where possible and at the same time will make all content of the remote directory normally accessible to its respective local user accessible via SSHFS.
The implementation looks relatively straightforward (for outside symlinks, inside symlinks are processed normally):
EPERMforunlinkand similar is needed because this operation is irreversible on the SSHFS side (it's impossible to create the same object that it was before since the contents outside the mounted directory is fundamentally inaccessible).chmodand company is another story - changing the target is exactly the same which would happen locally and it's reversible, so SSHFS should expose it as is. And returningEPERMfor those will break many apps so it's not the right thing to do.Any FS operation on broken, circular and all other outside symlinks for which SFTP REALPATH returns a failure should result in EPERM too I believe.