Willscott/go-NFS: Golang NFSv3 server
github.com
github.com
This turned out easier than i was expecting it to be. It's nice to be able to mount a VFS without needing privileges on the server side. The main intention for this code is to eventually use it to replace fuse on mac, since nfs is a valid mount time for mac clients to consume.
Thanks for your contribution!
Instead though, you can translate the exotic file system types to nfs, and use the existing kernel drivers that already exist for mounting an NFS mount.
Not criticizing the projet here, which is very cool. But don't get too hasty.
This is an _untested_ (per the docs), _unoptimized_, _read only_, _server only_, NFS v3 only, implementation.
optimization and testing are ongoing :)
Fuse is a really great idea & project, but sadly today impls require a lot of install steps in some platforms, and some have painful bugs/UX. Amazing if we can mount VFSes from Go without those hurdles.
- Under Linux and FreeBSD, bazil fuse offers a nice low dependency path to supporting FUSE. It is all pure Go code.
- Under Windows, you can use WinFSP, which is a rock solid usermode filesystem driver with FUSE support. Despite its name, you can use this with Cgofuse to get FUSE on Windows without CGo.
Combining the two above gets you pretty far already (though if you want to actually avoid a CGo dependency you do need to explicitly disable it.)
I think the next level would be to have a general filesystem interface (there are several options in the ecosystem already) that can be used as a common ground between different usermode filesystem and network filesystem server implementations. Then ideally, a magic Go library can exist that gives you the best possible setup with switchable backends depending on the platform and build configuration.
Right now Go itself is possibly standardizing a read-only filesystem interface, an extension of this with write support might serve as a decent jumping point for getting toward an idealized pluggable filesystem library.
That's starting to take shape: https://old.reddit.com/r/golang/comments/hv976o/qa_iofs_draf...
It won't be enough for the likes of FUSE, though. Some extensions might be enough to bridge that gap, it's too early to tell. FUSE is pretty particular about things like rename(2) preserving node identity.
Fairmount, an app DVD ripping on MacOS, uses WebDAV: https://github.com/BoxOfSnoo/Fairmount
Even though it started its life as a component of Plan9, 9p is getting through a renaissance period right now: qemu, WSL, gVisor, ChromeOS VMs (crostini)... all use 9p!
Not saying that would be ideal from a technical perspective (WebDAV at least has some issues), just surprised the ability to access remote filesystems from the browser hasn't been a bigger driver.
For example, there are a lot of interesting apps built on top of Google Drive as the storage backend, but overall the concept doesn't seem to have gained much traction.
Custom protocol over UDP is the fastest, which NFS supports, so NFS is basically the fastest (unless you get into wonky multiplex-streamed custom apps). However, UDP apps do not often work well through firewalls.
I don't think it's a trade-off thing. It's conceptual; FS over HTTP is not bigger than it is because filesystems are a much more stateful concept that often has to support coordinative transactions (like locks) whereas HTTP is a stateless protocol by design, so there's fundamentally a mismatch. That's why HTTP is better matched for an object system like S3 which is capable of being transported over stateless links and gives fewer coordination guarantees and is only eventually consistent.
You don't have to implement all the semantics of a filesystem in order to benefit. The main benefit comes from making a filesystem-like construct accessible in the browser. As I said before, Google Drive is a good example of this (and it's an object system, so that's an orthogonal issue), but it's a complicated protocol (as is S3) in a walled garden.
Widespread adoption of QUIC may make more firewalls become UDP-friendly.
Implementation-wise HTTP has the advantage that the apps can tune the client code because the protocol client implementation isn't in the kernel.
In addition HTTP security (transport & user authentication) is works and everyone understands it, whereas on NFS it's a huge mess and enemy of interoperability.
In practical popularity NFS fares extremely poorly eg on AWS (how many apps use EFS vs S3).
Yes EFS is 30¢ per GB and S3 is 2.3¢.
But S3 also charges $5/million object writes (and 40¢ for reads), but EFS is "free" (factoring burst capacity, per-instance maximum throughput limits, etc).
Couple that with EFS' lifecycle migration allowing you to get storage costs as low as 2.5¢/GB for many write-once-read-(almost)never after 7 day applications, things get a lot more complicated.
In terms of low-urgency storage though, the Dropbox/Google Drive/Syncthing model of directory replication largely has supplanted SFTP, though.
There is probably some middle group of S3/B2 type storage backing some FUSE-style integrated filesystem, but I'd suspect the same problem that makes WebDAV unpopular hampers that, namely that it almost invariably sucks horribly on Windows when it works at all.
I don't really understand why people want network filesystems most of the time. If you try to pretend it's like real local i/o, and it's not on a perfect network, you will have a bad time. Protocols designed specifically just to transfer a file tend to be more resilient and also not expose people to the problems of programs trying to do file i/o.
But just having a standardized way to do directory listings, uploads, partial writes, auth, etc over HTTP would be useful to me.
It’s basically a shell component that abstracts over file selection for open/save and an api for providing the list of files, reading or writing files/parts of files, and shims around common fs operations like copy and move.
Implementing on top of HTTP is usually to make things easier for users behind firewalls, squid proxies, and the like. In my experience, those environments (schools, offices) usually had to open port 21 and/or 22 for FTP/SFTP for a web maintainer anyway...
https://github.com/unfs3/unfs3
This has the benefits of being tested and having a working read-write implementation (along with still being user-space).
Edit: Thank you!
This layer eschews responsibility for multiple concurrent clients for simplicity. No promises you'll get either decent performance or proper cache invalidation when using it that way. It tends to be conservative in not filling in all the opportunistic caches.
There's a hook the backing application can use to tune reads and write sizes that becomes much more relevant in a network case. How those should be set in practice isn't something I've spent time on.