Commit Graph
8174 Commits
Author SHA1 Message Date
Jakob BorgandGitHub 328d910aee fix(api): correctly return metrics, support bundle (fixes #10847) (#10849)
Our faked request wasn't good enough; improve it, adding a test.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-08-05 18:35:17 +00:00
Jakob BorgandGitHub d7df27a367 fix(model): correctly handle receive-only changed directories (fixes #8004) (#10843)
When adding a folder in receive-only mode where the contents were
already identical to a remote device, directories would remain as
locally changed when everything else had consolidated. The reason this
happened is that we only did the matching between locally changed files
and their global equivalent for changed items, but directories are
typically not "changed" much as we don't track their mtime, so they
wouldn't pass through this stage when scanning.

Now, instead, do the check when we're anyway walking all the files in
phase two of scanning. This catches all cases of identical items, files
or directories, regardless of how they came to be in the index.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-08-05 20:23:53 +02:00
Jakob BorgandGitHub 8ea09c0094 chore: style fixes from go fix (#10846)
Just `go fix ./...`

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-08-05 20:23:22 +02:00
Jakob BorgandGitHub 946e2b83a1 fix(db, model): better handle db connections, puller concurrency, avoid deadlock (fixes #10841) (#10842)
There is a danger of deadlock wherever we have database operations
inside a database iterator. The iterator itself pins a connection, so
the nested operations need another connection; if we've reached
maxOpenConns then it blocks until a connection is released. If all
connections are consumed by such iterators then none can make progress.

Luckily, we have limited concurrency for most such iterator loops. They
are part of scanning, pulling, reverting, etc where there is only ever
one such routine per folder. The exception is block reuse in the copier
routine, which is limited by the `Copiers` setting per folder. This
could in practice deadlock since you could set copiers to eight and end
up with six `AllLocalBlocksWithHash` iterators when `maxDBConns=6`, all
of which need to make additional database calls inside the loop.

This PR fixes the problem twice;

- The problematic loop does not need to be reentrant. The set of blocks
that may be returned by the iterator is finite so we can easily just
collect them to a slice before we start processing them. This avoids the
problem entirely.
- We do not need to limit database connections as strictly as we
currently do. Increase the maximum allowed, while reducing the number of
held-open idle connections slightly. This is not an exact science, but
ideally we want "most" operations to be able to use the pinned
connections to avoid cache churn. Most operations are short lived
queries, or single-goroutine iterators with short lived queries inside,
so four connections seems like it should usually be enough. 🤷
- Additionally, set a cap on Copiers. Currently you could set it to an
arbitrarily large number, which is not advantageous. Limit it to
2*NumCPU which scales somewhat with system performance.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-08-03 23:36:05 +02:00
Syncthing Release Automation 13f38e9abf chore(gui, man, authors): update docs, translations, and contributors 2026-08-03 04:54:49 +00:00
Jakob BorgandGitHub bcef5c5bc6 chore(syncthing): include local db entries in perfstats (#10839)
As used by the latest few PRs with graphs in them

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-27 10:23:18 +00:00
Jakob BorgandGitHub 952da4224b chore(model): optimise fsync calls (#10831)
This improves performance when running with fsync enabled. The key
observation is that the OS may coalesce multiple concurrent fsyncs, so
we gain some performance by issuing them in parallell. Since they run
from the finisher routine, a simple fix is to run multiple finisher
routines. That's the `after` line in the graph below. The other step is
to do the same for the directory fsyncs, issuing them concurrently with
a limiter. In both cases I used the Copiers value as the concurrency
factor. Additionally, add some buffering to the channels between
routines to minimise stalls where a routine needs to wait for another.
This is the `after2` line.

All in all, this speeds up syncing 25k tiny files from 190s to 130s, a
30% improvement.

<img width="821" height="540" alt="Screenshot 2026-07-25 at 22 58 34"
src="https://github.com/user-attachments/assets/18272c89-a99e-4ee4-9b5e-b278967ea7c6"
/>

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-27 12:13:05 +02:00
Jakob BorgandGitHub b2092b188f chore(fs): optimise casefs caching performance (#10830)
This tweaks the casefs cache to do in-place updates for modifications we
perform, instead of dropping the entire cache. That is, we add, remove
and rename things in the cache after having done the corresponding
operation.

We still drop the cache entirely on larger operations like MkdirAll, and
before Walk, and the 1s expiry is unchanged.

The result is performance much closer to the original. I set up a device
with 150 000 tiny files and measured the time it took for a blank device
to come online and sync all the files, with default settings apart from
`fsync` being disabled, as it otherwise dominated the benchmark...

There are three runs, all are identical in the first 40 seconds which is
the index transmission & reception, then we can see the `sensitive` run
(casefs disabled) finishes at 137 seconds (137-40 = 97s spent syncing);
the `before` run finishes at 238s (198s spent syncing); the `after` run
finishes at 142 seconds (102s spent syncing). So, effectively the sync
time is cut in half, and is now very close to having case sensitive
enabled.

<img width="812" height="476" alt="Screenshot 2026-07-25 at 23 22 22"
src="https://github.com/user-attachments/assets/0aa39712-9fd7-46cf-969e-b6a20f150a3c"
/>

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-27 12:05:20 +02:00
Simon FreiandGitHub ed6b56d48f chore(model): don't check existing file twice in rename detection (#10833)
This is related to and lessens issue:

https://github.com/syncthing/syncthing/issues/10777

@SoongVilda found that a recent change to track already deleted or
existing files only in the scope of a batch, also stopped tracking
already existing files. Thus the osutil.IsDeleted check can be executed
many times if lots of identical files get picked up in a scan:


https://github.com/syncthing/syncthing/issues/10777#issuecomment-4991039201

The change in question:

chore(model): more efficient tracking of renames during scan (#10653)
2721b7b522

---------

Signed-off-by: Simon Frei <freisim93@gmail.com>
2026-07-27 08:28:04 +02:00
Syncthing Release Automation f145da2613 chore(gui, man, authors): update docs, translations, and contributors 2026-07-27 04:56:41 +00:00
Jakob BorgandGitHub 2f55d28b5c fix(api): handle empty path in static request (#10837)
The panic would be recovered by the HTTP server, but this is cleaner.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-26 18:54:45 +00:00
Jakob BorgandGitHub 733f63592f fix(versioner): handle invalid empty command (#10836)
Same same

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-26 18:51:53 +00:00
Jakob BorgandGitHub b8a255cc96 fix(ignore): handle pattern resulting in empty string (#10835)
Minor fix to avoid a panic in ignore matching.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-26 20:50:14 +02:00
Jakob BorgandGitHub 703b185982 fix(upnp): guard against out of index string access (#10834)
Broken responses may have empty path component.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-26 18:37:28 +00:00
Jakob BorgandGitHub 119d5e72ef chore: deflake TestRecvOnlyRevertNeeds (#10827)
There was a rare, tricky race condition in the setup, where a pull could
get started, find the blocks from the file we injected in
updateLocalsFromScanning, copy them into a temp file, then fail the pull
because the file was already in place. Then later, after the revert,
another pull would start, find the temp file and reuse it, making it so
needed=0 instead of the expected needed>0 the test checks for.

This avoids all that by setting the local index data prior to getting it
from the "remote" device, thus avoiding the initial pull and temp file
creation etc.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-25 08:47:42 +00:00
tbodtandGitHub 3993f62beb chore(gui): better describe when a pending folder/device notification will reappear (#10808)
The tooltip on the dismiss button for notifications confused me a bit
(wdym mean "may" recur?) so here is an attempt at a clearer message.

Signed-off-by: tbodt <tbodt@tbodt.com>
2026-07-25 10:01:32 +02:00
Rohit TanwarandGitHub 130850097d fix(gui): add bottom margin to folder action buttons for wrapped spacing (#10728)
adds a bottom margin to buttons inside panel footers, ensuring a
comfortable gap between wrapped button rows. (Fixes #10689 )

Signed-off-by: rohitanwar <mst10041967@gmail.com>
2026-07-25 09:54:46 +02:00
Jakob BorgandGitHub ec35a95318 chore: slightly optimise rename detection (ref #10777) (#10819)
Only run rename detection for new files. This skips an expensive check
for all updates to existing files. The tradeoff is that we no longer
immediately detect renames on top of another file as a rename -- this
may instead become a copy+delete operation on the destination.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-25 07:46:56 +00:00
Jakob BorgandGitHub b15ff42d52 chore: remove ignore file caching entirely (#10813)
Effectively nobody uses it, it cost more than it was worth, the code
doesn't carry its weight. Remove it and let any similar mechanism in the
future be an internal implementation detail.

Closes #10812

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-25 09:43:22 +02:00
Jakob Borg 2f81bf5d34 chore(fs): casefs keep first instead of last mapping
Closes #10823, closes #10825.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-25 09:36:39 +02:00
Jakob BorgandGitHub 39b0bd20d0 chore: new code contribution guidelines (#10821)
Reflecting current challenges.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-25 09:33:38 +02:00
Jakob BorgandGitHub 977f790143 build(deps): update dependencies (#10824)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-24 08:09:47 +02:00
tbodtandGitHub 5fa3d9f418 fix(gui): fix expanding one folder not collapsing others in group (#10809)
Regression introduced after folder groups were added in
6a26d56ad9

Signed-off-by: tbodt <tbodt@tbodt.com>
2026-07-21 04:45:07 +00:00
FredericandGitHub d73c00799b chore(gui): lazy-render collapsed panels to reduce watcher count (#10772)
Adds a `lazyCollapse` directive that renders panel body content only
while expanded. Collapsed panels contribute zero watchers — content is
added to the DOM on expand (`show.bs.collapse`) and removed after the
collapse animation completes (`hidden.bs.collapse`).


Signed-off-by: Finomosec <1665799+Finomosec@users.noreply.github.com>
2026-07-20 21:03:53 +00:00
Jakob BorgandGitHub 9f7b4d4104 fix(model): properly health-check up-to-date folders (fixes #10546) (#10773)
Previously we'd skip the health check for an up-to-date folder, so it
would continue looking up-to-date even when the folder path missing.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-20 22:54:31 +02:00
Jakob BorgandGitHub d710874903 chore: fix a couple of unclosed http connections (#10806)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-20 20:22:40 +00:00
Syncthing Release Automation 578cc5a165 chore(gui, man, authors): update docs, translations, and contributors 2026-07-20 04:56:12 +00:00
Andrew GunnersonandGitHub a0171e3a9b build: allow inotify on Android amd64 (ref #8710) (#10783)
ad0044fec8 previously disabled it due to
seccomp crashes. This was caused by `golang.org/x/sys`'s
`unix.EpollWait` function using the `epoll_wait` syscall instead of the
`epoll_pwait` syscall. bionic libc implements the `epoll_wait` C wrapper
function in terms of the `epoll_pwait` syscall, so this never affected C
code.

`golang.org/x/sys` switched to the `epoll_pwait` syscall in 2016, but
only for arm64. As of v0.47.0, it now uses `epoll_pwait` for all
architectures.

Upstream bug: https://github.com/golang/go/issues/80080
Upstream fix: https://go-review.googlesource.com/c/sys/+/792700
Upstream arm64 fix from 2016:
https://go-review.googlesource.com/c/sys/+/21971

---

With this change, Syncthing no longer crashes when inotify is allowed
and enabled in the Android emulator when run inside an app context. (The
seccomp policies do not affect execution under `adb shell`.)

This is the crash that occurs if inotify is enabled without the v0.47.0
update:
```
2026-07-08 10:59:36.711202 -0400 F/DEBUG   (16538): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2026-07-08 10:59:36.711219 -0400 F/DEBUG   (16538): Build fingerprint: 'google/sdk_gphone16k_x86_64/emu64xa16k:17/CE2A.260420.019/15611780:userdebug/dev-keys'
2026-07-08 10:59:36.711224 -0400 F/DEBUG   (16538): Kernel Release: '6.12.58-android16-6-gccafb60de224-ab14828483'
2026-07-08 10:59:36.711226 -0400 F/DEBUG   (16538): Revision: '0'
2026-07-08 10:59:36.711228 -0400 F/DEBUG   (16538): ABI: 'x86_64'
2026-07-08 10:59:36.711230 -0400 F/DEBUG   (16538): Timestamp: 2026-07-08 10:59:36.617348693-0400
2026-07-08 10:59:36.711232 -0400 F/DEBUG   (16538): Process uptime: 2s
2026-07-08 10:59:36.711234 -0400 F/DEBUG   (16538): Page size: 16384 bytes
2026-07-08 10:59:36.711236 -0400 F/DEBUG   (16538): Executable: /system/bin/app_process64
2026-07-08 10:59:36.711239 -0400 F/DEBUG   (16538): Cmdline: com.chiller3.basicsync.debug
2026-07-08 10:59:36.711241 -0400 F/DEBUG   (16538): pid: 16502, ppid: 436, tid: 16531, name: Thread-6  >>> com.chiller3.basicsync.debug <<<
2026-07-08 10:59:36.711243 -0400 F/DEBUG   (16538): uid: 10231
2026-07-08 10:59:36.711886 -0400 F/DEBUG   (16538): signal 31 (SIGSYS), code 1 (SYS_SECCOMP), fault addr --------
2026-07-08 10:59:36.711899 -0400 F/DEBUG   (16538): Cause: seccomp prevented call to disallowed x86_64 system call 232
2026-07-08 10:59:36.711908 -0400 F/DEBUG   (16538):     rax 00000000000000e8  rbx 0000000000000078  rcx 00007372d956826e  rdx 0000000000000001
2026-07-08 10:59:36.711912 -0400 F/DEBUG   (16538):     r8  0000000000000000  r9  0000000000000000  r10 ffffffffffffffff  r11 0000000000000206
2026-07-08 10:59:36.712123 -0400 F/DEBUG   (16538):     r12 0000737291cc5d00  r13 000025897adcad20  r14 000025897abc7c20  r15 ffffffffffffffff
2026-07-08 10:59:36.712134 -0400 F/DEBUG   (16538):     rdi 0000000000000078  rsi 000025897af9ef7c
2026-07-08 10:59:36.712137 -0400 F/DEBUG   (16538):     rbp 000025897af9ee28  rsp 000025897af9ede8  rip 00007372d956826e  err 0000000000000000
2026-07-08 10:59:36.712139 -0400 F/DEBUG   (16538): 1 total frames
2026-07-08 10:59:36.712141 -0400 F/DEBUG   (16538): backtrace:
2026-07-08 10:59:36.712145 -0400 F/DEBUG   (16538):       #00 pc 0000000000d2826e  /data/app/~~s99umF1bl81-VDLSDwy30g==/com.chiller3.basicsync.debug-5Lq8YsTwbMz_SXt-F_uHaQ==/base.apk (offset 0x2e4c000)
2026-07-08 10:59:36.712431 -0400 F/DEBUG   (16538): Note: To display stack pointer information, use the pbtombstone tool:
2026-07-08 10:59:36.712443 -0400 F/DEBUG   (16538):         pbtombstone --display-sp tombstone_XX.pb
```

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-07-16 16:08:55 +00:00
Jakob BorgandGitHub 1722f0a7b2 fix(strelaypoolsrv): locking correctness (#10801)
Fixes a couple of races on relay handling in the pool server.

Fixes #10799.
Closes #10800.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-16 16:01:47 +00:00
Jakob BorgandGitHub c904140b3c fix: avoid warning on does-not-exist scan error (fixes #10465) (#10791)
We never need to treat these as warnings from a scan.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-16 09:20:33 +08:00
Jakob BorgandGitHub c1d8045d86 fix(ignore, fs): allow loading ignore patterns behind symlink (fixes #10785) (#10786)
The recent change to disallow following symlinks by default conflicts
with the expected behavior of .stignore. This adds a new flag which may
be passed to OpenFile to skip default symlink-forbidding open flag.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-16 09:19:13 +08:00
Syncthing Release Automation d4cffd848e chore(gui, man, authors): update docs, translations, and contributors 2026-07-13 04:53:32 +00:00
Syncthing Release Automation 5277033906 chore(gui, man, authors): update docs, translations, and contributors 2026-07-06 05:07:17 +00:00
Jakob BorgandGitHub ef4629ea56 chore(model): simplify FileInfoBatch size computation (#10776)
We used a size computation to generate reasonably sized batches, but the
ProtoSize call is fairly expensive as it requires a conversion to a wire
type etc. We don't need that much precision. Instead, just limit to 1000
files or 5000 blocks, which is likely approximately that much data
anyway.

Closes #10707

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-01 16:01:46 +00:00
Jakob Borg 35576881ff chore(stcrashreceiver): the "internal" directory exists
Closes #10729

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-07-01 17:43:26 +02:00
Syncthing Release Automation 466d30bd70 chore(gui, man, authors): update docs, translations, and contributors 2026-06-29 05:17:21 +00:00
2775f424f2 chore(fs): use x/sys/windows where possible (#10766)
Gets rid of an import of "unsafe".

---------

Signed-off-by: greatroar <61184462+greatroar@users.noreply.github.com>
Signed-off-by: Jakob Borg <jakob@kastelo.net>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-06-28 08:00:08 +02:00
Jakob BorgandGitHub 44cbfcad56 fix(sqlite): update last migration to set schema version, counts (#10768)
The counts needs to be modified manually since we're not running
triggers during migrations. The schema version needed to be bumped.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-26 07:22:40 +02:00
Jakob BorgandGitHub e4d08b336e fix(config): remove extraneous defaults setting while unmarshalling folder options (fixes #10746, fixes #10389) (#10763)
This broke PATCH on folders. Any place that needs the defaults should
set them prior to unmarshal.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-23 07:57:36 +02:00
Jakob BorgandGitHub 97cb72a608 chore(versioner): attempt to prevent blatantly unsafe external versioner commands (fixes #10721) (#10722)
While preparing the command, attempt to verify that the template
expansion happens in a way that will result in a non-shell-injection
command. I don't presume to say that this is a 100% prevention, and the
script itself can always do dumb shit with the file path later.
Nonetheless, we should make a best-effort attempt.

Equally, this could generate false positives for commands that are
strangely written but in fact safe. I think this is acceptable; external
versioning is currently used by approximately 0.02% of users, and
presumably most of them have a setup that is sane.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-23 07:48:53 +02:00
Simon FreiandGitHub c9236b1adc chore: stop treating dirs as having size 128 (#10750)
Resp. directories for the database, and both dirs and symlinks for
`FileInfo.FileSize`. Instead handle it in the UI progress percentage. We
even already have special cases there for deletions, might as well
handle directories just like any other zero-sized needed item there.

This went through the very thorough testing of running it on my laptop,
the migration was applied and it seemed to be working fine after.

---------

Signed-off-by: Simon Frei <freisim93@gmail.com>
2026-06-22 20:32:03 +02:00
Jakob BorgandGitHub 5313c75eba chore(model): increase default value for num hashers (#10761) 2026-06-22 12:53:03 +02:00
Syncthing Release Automation 40febaa811 chore(gui, man, authors): update docs, translations, and contributors 2026-06-22 05:29:45 +00:00
Jakob BorgandGitHub 92ff9ac078 chore(osutil): fixup test for symlinked folder root (#10758)
This test was incorrectly rewritten to use fakefs, which doesn't really
test what it's supposed to test.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-21 19:48:15 +02:00
Henrik BråthenandGitHub f7f2e7c70b fix(folder): check if context canceled when scanning (fixes #10363) (#10757)
During initial folder scan and the scan is interrupted with a
context.Canceled error, it was previously logged as a "Failed initial
scan" error, which can be misleading

The change adds a explicit check for context.Canceled and silently
ignores it (fixes #10363)

Signed-off-by: Henrik Bråthen <henrikbs@proton.me>
2026-06-21 18:23:37 +02:00
Syncthing Release Automation 3d168d6e44 chore(gui, man, authors): update docs, translations, and contributors 2026-06-15 05:28:39 +00:00
Jakob BorgandGitHub 8cc4c4ffb3 build: use Go 1.26 for Windows as well (#10744)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-13 14:01:46 +02:00
Jakob BorgandGitHub f1d631d66e fix(protocol): loosen restriction on size of directory entries (#10743)
The synthetic directory size must be permitted.

Ref #10737.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-13 06:31:26 +00:00
Jakob BorgandGitHub ee275fee65 build(deps): update dependencies (#10740)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-12 08:59:50 +02:00
Jakob BorgandGitHub 6606e6b4d3 fix(protocol): be more stringent about blocks in non-file entries (#10737)
Directories, but also symlinks, should not have blocks or a size.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-06-11 18:52:24 +02:00