Commit Graph
483 Commits
Author SHA1 Message Date
nvrl f24ac8a429 feat(fuse,core,cli): report what the daemon is doing, for the next hang
On 2026-09-18 the daemon hung: 43 minutes of CPU over 20 hours, 5.2 GiB
resident, silent from 17:10 until a manual restart the next day, and no
panic. Nothing in the journal said what it had been waiting on, and
nothing in the daemon could be asked.

- The worker pool publishes per-thread state: whether the thread is busy,
  how long it has been in that state, and the label of the job in hand.
  Every FUSE handler that hands work to the pool now names its job
  (`read`, `lookup`, `rename`), so a stuck worker is named rather than
  merely counted. Queue depths and per-lane completion counts are
  mirrored outside the queue lock.
- `Request::Diagnostics` / `pdfs diagnostics` reports those, plus
  resident size, the control handler count against its limit, the
  in-flight control requests with their ages, and the pending-op count.
- Built to answer while the daemon is wedged: atomics and `try_lock`
  only, and the one field that needs the database reads it on a throwaway
  thread with a 500 ms deadline.
2026-09-19 14:40:26 +02:00
nvrl f78f663740 feat(core,fuse): restore the whole trashed tree, and bump the SDK to 0.6.5
The trash is a flat list of uids, but a delete has a shape: a folder, and
often items inside it that were trashed separately beforehand. Restoring
one of those in isolation is not what it means — a folder came back
without the contents deleted with it, and a file came back inside a
folder that is still trashed, which is to say nowhere the user can see.

- Schema 29: `trash.parent_uid`, filled by the trash refresh from the
  node's parent, plus an index for the walk.
- `expand_restore` takes the connected piece of the trashed tree around
  what was asked for (every trashed descendant, every trashed ancestor)
  and orders it into waves, shallowest first: the server cannot put a
  node back under a parent that is still trashed. A uid the listing does
  not know about is restored on its own, because the listing is
  materialised in chunks and can be stale.
- `Core::restore` restores wave by wave, still streaming per-node
  outcomes, so one node the server refuses leaves the rest restored.

The SDK bump brings the 6cbf2f44 port: permanent API errors are no
longer retried on block transfers, expired block URLs are re-minted on
the whole-file and public-link download paths, and a server-supplied
Retry-After is capped at 120 s.
2026-09-19 14:31:40 +02:00
nvrl 470948c191 chore(version) bumped to 1.10.2 v1.10.2 2026-09-16 23:05:09 +02:00
nvrl b095b9f6b0 fix(core,fuse): never stat a foreign mount from the local-file indexer
The "This computer" indexer walks $HOME, and `default_excludes` only kept it
out of the Drive mountpoint and our own state/cache dirs. A home directory
that also holds third-party FUSE mounts (sshfs, rclone) got walked into.

`scan` does ask for `same_file_system(true)`, which looks sufficient and is
not: `ignore` implements it as `is_same_file_system` -> `device_num(path)` ->
`path.metadata()`, run after the directory is queued. Learning that a mount is
foreign requires stat'ing it first, and against a mount whose server is gone
that stat never returns.

The consequence is worse than a stalled scan. The blocked thread sits in
uninterruptible FUSE wait, so it ignores SIGKILL: the daemon can never exit,
systemd's stop times out, and the unreapable process keeps the cache.db lock
the next start needs, turning one dead mount into a permanent restart loop.
No userspace recovery exists once a thread is in that state, so the fix has to
be to never enter it.

Exclude every mountpoint strictly below the scan root, read by path from
/proc/self/mounts (octal-unescaped, so a path with a space still matches).
`filter_entry` runs before the device stat, so the walker never touches them.
Re-read per scan rather than cached at startup: a mount that appeared since
the daemon started is the likeliest to be half-alive.

This does not change what is indexed — a nested mount is a different device,
so it was already going to be skipped. Only the stat in front of that decision
goes away.

Refs: docs/BUGS.md B90
2026-09-16 23:05:06 +02:00
nvrl f4d6580cd3 chore(version) bumped to 1.10.1 v1.10.1 2026-09-15 15:13:22 +02:00
nvrl b2f62f70e1 chore(deps,core,gui): upgrade dependencies to latest
- keyring 3 -> keyring-core 1 + dbus-secret-service-keyring-store 1
  (crypto-rust). Same libdbus Secret Service backend; with no target the
  store matches items keyring 3 wrote, so stored sessions survive.
- ksni 0.2 -> 0.3 via the blocking API, with assume_sni_available so a
  tray that starts before the SNI watcher waits instead of failing. Drops
  the clap 2 / atty chain (Dependabot atty advisory).
- gtk4 0.11, libadwaita 0.9, webkit6 0.6, rusqlite 0.40, fuser 0.18,
  directories 6, sha1/sha2 0.11, base64 0.23.
2026-09-15 15:07:00 +02:00
nvrl dcb2ab7fac chore(version) bumped to 1.10.0 v1.10.0 2026-09-15 13:59:24 +02:00
nvrl eb56f4a1e0 feat(fuse,core,gui,cli): one-request move+rename drain, show who shared an item
- A queued rename that also changes folder now lands as one `move-multiple`
  request carrying the target name instead of rename-then-move, so there is
  no half-applied state and no second call for stale name requirements to
  hit (B46 follow-up). A destination name collision moves under a conflict
  name in one step; same-folder renames still use the rename endpoint.
- Shared with me shows the inviter and invite date (GUI subtitle, `pdfs
  shared-with-me`), with a warning when the invitation signature does not
  verify against the claimed inviter's keys. `DirEntry` gains `shared_by`,
  `shared_at` and `shared_by_unverified`, all serde-defaulted.
- Bump `proton-sdk` / `proton-drive-rs` to 0.6.3 (anonymous-node moves,
  `TrashTime` trashed detection).
2026-09-15 13:59:13 +02:00
nvrl c28803b037 chore(changelog) updated changelog for 1.9.2 and 1.9.3 2026-09-08 14:58:48 +02:00
nvrl cd8474954b chore(version) bumped to 1.9.3 v1.9.3 2026-09-01 17:00:43 +02:00
nvrl d7e07d042d Merge pull request #22 from kacperpaczos/fix/login-poll-backoff
fix(cli): back off while waiting for a stored session
2026-09-01 16:38:29 +02:00
nvrl 45852082c0 fix(cli,core): wake the parked login-wait daemon on sign-in
The login backoff had no wake-up path. A unit started at boot sits in
wait_for_session and reaches the ceiling within ~90s; the user then signs
in and `enable --now` is a no-op on an already-active unit, so the daemon
kept sleeping and the mount appeared up to a full interval late.

- service::enable_start now runs `enable` + `restart` instead of
  `enable --now`, so the GUI login and the tray's Connect interrupt the
  sleep immediately and still start a unit that is down.
- `pdfs login` restarts the unit when it is already active. It stays out
  of `enable` on purpose, so a headless setup driving `pdfs daemon` by
  hand is left alone.
- Lower the backoff ceiling from 60s to 15s. It is still an 80% cut in
  keyring/D-Bus wakeups (28,800/day -> 5,760/day) and it bounds the
  worst-case latency for paths that never touch systemd.

Also corrects the flat-3s-poll figure in the doc comment: 86400/3 is
28,800 checks a day, not 48,000.
2026-09-01 16:28:25 +02:00
nvrl 99ad3838e1 fix(GALLERY) fixed takeout date conversion + repair command v1.9.2 2026-08-28 13:06:50 +02:00
Kacper Paczos 637b512f6a fix(cli): back off while waiting for a stored session
The daemon's wait-for-login loop slept a flat 3 seconds between checks and
never gave up, so an enabled service with no saved session polled the keyring
28,800 times a day. Each check is more than a sleep: auth::load() builds a
fresh keyring::Entry, so every iteration opens a new D-Bus connection to the
Secret Service and negotiates a session on it.

Back off from 3s to a 60s ceiling and say "not logged in" once at INFO rather
than on every iteration, which also stops the journal filling with tens of
thousands of identical lines.

The wait is extracted into wait_for_session() taking the load and sleep calls
as parameters, so the schedule is testable without a keyring and without real
time passing.

Refs #21
2026-08-25 13:24:46 +02:00
nvrl 16ad6548c8 chore(DOCS) updated changelog 2026-08-21 23:32:06 +02:00
nvrl 847ece17d7 version bumped to 1.9.1 v1.9.1 2026-08-21 22:48:28 +02:00
nvrl 50d2acdaba Merge pull request #20 from emptyname-org/feature/files-thumbnails-statusbar
feat(gui): add file thumbnails and a browser status bar
2026-08-21 22:44:58 +02:00
emptyname 53caf63ad4 Fix thumbnail lifecycle failures 2026-08-21 12:32:31 +01:00
nvrl 5176dd91e1 fixed icon 2026-08-21 04:13:11 +02:00
nvrl e88903d5ff chore(branding) added branding, best practice to repo 2026-08-21 04:09:58 +02:00
emptyname b3e6af1ae5 docs: document thumbnail runtime support 2026-08-18 13:06:40 +01:00
emptyname b0f9513915 feat(gui): show file thumbnails and browser status bar 2026-08-18 13:06:36 +01:00
emptyname 91b0864fce feat(thumbnails): generate cached previews for Drive files 2026-08-18 13:06:27 +01:00
nvrl 8bd9481902 fix(ui) improved ux v1.9.0 2026-08-18 12:50:49 +02:00
nvrl b2d5870834 fix(ui) improved ux 2026-08-18 12:06:28 +02:00
nvrl 078774f6a1 release(1.8.2) v1.8.2 2026-08-17 00:49:24 +02:00
nvrl 326a9b4e92 chore(docs) updated changelog + bug states 2026-08-17 00:04:54 +02:00
nvrl 78dc72a34d release(1.8.1) v1.8.1 2026-08-16 23:33:43 +02:00
nvrl 438b2b463e chore(docs) updated changelog v1.8.0 2026-08-16 22:03:55 +02:00
nvrl 4cd49168c4 fix(drain) failed attempts 2026-08-16 22:02:27 +02:00
nvrl 481c3fe0c7 version bump + bug docs 2026-08-16 21:34:55 +02:00
nvrl 098da2e97a fix(log) log unreachable nodes 2026-08-16 21:34:12 +02:00
nvrl d03d3eac3f fix(drive) locks + 1.7.1 2026-08-16 20:41:03 +02:00
nvrl 433e206203 chore(changelog) 2026-08-16 00:54:55 +02:00
nvrl 35418eea3f fix(perf) read-only connection pool, States doesn't write to db, search optimized v1.7.0 2026-08-16 00:33:27 +02:00
nvrl e48c4bb4b2 fix(fs) block fetch, sequential prefetch, in memory LRU 2026-08-15 23:44:13 +02:00
nvrl 7ad9231858 fix(fs) locks, vacuum, recover fsynced writes 2026-08-15 19:17:56 +02:00
nvrl e396c6b4d6 fix(fs) performance, locks 2026-08-15 18:49:07 +02:00
nvrl b37ab78451 version bump v1.6.0 2026-08-12 16:16:16 +02:00
nvrl 6e3d2c335e improved search prompt 2026-08-12 16:15:27 +02:00
nvrl 14b6df7bce fix(prompt) cached file open instead of actualy files v1.5.0 2026-08-11 14:22:13 +02:00
nvrl 4d76462e62 chore(versio) bumped to 1.4.0 v1.4.0 2026-08-10 15:35:59 +02:00
nvrl a5e03ad8da persistent entity cache, streaming batche 2026-08-10 15:22:04 +02:00
nvrl 2336ad9e87 added album to photos, renamed gallery view v1.3.0 2026-07-31 20:31:25 +02:00
nvrl d988236bfa wired new locations into gui, fuse acceptance with new permission based mounts 2026-07-31 19:37:12 +02:00
nvrl d78ddeab8e cargo fmt v1.2.1 2026-07-31 10:18:30 +02:00
nvrl b04cce3a23 fixed B78 2026-07-31 10:15:13 +02:00
nvrl 7e8403936b fixed permission error on on-demand mounts 2026-07-31 09:46:51 +02:00
nvrl 866a174c7a fixed rpm signing 2026-07-30 02:55:15 +02:00
nvrl 352117e806 fixed rpm signing 2026-07-30 02:23:49 +02:00