- Rust 100%
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
gdrive-fuse-fs
FUSE filesystem for Google Drive, written in Rust, making use of the
gdrive4fs crate. Credentials come from
Gnome Online Accounts (supported by the crate's goa feature, on by
default on Linux); setting GDRIVE_TOKEN=<token> bypasses GOA for
short-lived sessions and tests.
Prerequisites
- Linux with
/dev/fuse(thefusermount/fusermount3helper for unmounting). - A Google account in Settings → Online Accounts with Files enabled
(GOA pre-scopes the token to the Drive scope), and a running GNOME session
D-Bus so the mount can reach
org.gnome.OnlineAccounts. - Rust 1.85+.
Build & install
cargo build --release
sudo install -m755 target/release/gdrive-fuse-fs /usr/local/bin/
Usage
mkdir -p ~/mnt/gdrive
gdrive-fuse-fs ~/mnt/gdrive
# ... use it like any filesystem ...
fusermount -u ~/mnt/gdrive
Full options (gdrive-fuse-fs --help):
usage: gdrive-fuse-fs <mountpoint> [options]
options:
--shared expose the `/Shared with me` folder
--delete=trash|permanent trash (default) or permanently delete
--exec=property|sidecar|heuristic
executable-bit policy (default property)
--duplicates=suffix|first-wins|rename-remote
duplicate-name policy (default suffix)
--account=<id|email> use this GOA account instead of auto-pick
--list-accounts list GOA Google accounts and exit
--allow-other allow other users (needs user_allow_other)
-h, --help show this help
Account handling:
gdrive-fuse-fs --list-accounts # show GOA Google accounts
gdrive-fuse-fs ~/mnt/gdrive --shared # also expose "Shared with me"
gdrive-fuse-fs ~/mnt/gdrive --account=bjorn.vildljung@gmail.com
GDRIVE_TOKEN=<token> gdrive-fuse-fs ~/mnt/gdrive # bypass GOA
With several Drive-enabled GOA accounts the mount refuses to guess — pass
--account=<id|email> (see --list-accounts). Logging is tunable via
RUST_LOG (info by default; debug traces every filesystem op); a session
summary (timings, byte totals, cache behaviour) is logged when the mount
drops.
How it works
gdrive4fs exposes an async, path/handle-based filesystem API (GDrive)
and stays FUSE-agnostic; this binary is the bridge (the pattern from the
crate's examples/fuse-mount.rs):
- one multithreaded tokio runtime (the FUSE callbacks are synchronous, so
each
block_ons the matchingGDrivecall — fuser worker threads, never runtime workers); - an inode → path map (inodes are deterministic per Drive id, so it fills
up naturally from
lookup/readdir, is pruned on delete and rewritten on rename); - an fh →
OpenFilemap for open handles.
Every gdrive4fs feature rides the same glue with no extra work: the
virtual /.Trash namespace (trash walk, restore-by-rename-out, permanent
delete in-trash), /Shared with me, exec-bit-only chmod, and the four
xattr callbacks over Drive appProperties. See the
gdrive4fs README and
USER_GUIDE.md for semantics and limitations
(whole-file uploads on flush, rmdir without ENOTEMPTY, slash-names
unreachable through kernel FUSE, xattr-removal tombstones, …).
Layout
gdrive-fuse-fs/
├── Cargo.toml # binary crate; gdrive4fs via path dep, fuser 0.18
└── src/main.rs # DriveFs (fuser::Filesystem over Arc<GDrive>) + CLI