This commit is contained in:
Jakob Borg 2023-05-23 12:39:19 +02:00
parent a933bcfebc
commit da9726ddca
10 changed files with 429 additions and 135 deletions

View File

@ -37,7 +37,7 @@ func newFakeConnection(id protocol.DeviceID, model Model) *fakeConnection {
f.closeOnce.Do(func() {
close(f.closed)
})
model.Closed(id, err)
model.Closed(f.ConnectionID(), err)
f.ClosedReturns(f.closed)
})
return f

View File

@ -44,10 +44,10 @@ type Model struct {
arg1 string
arg2 string
}
ClosedStub func(protocol.DeviceID, error)
ClosedStub func(string, error)
closedMutex sync.RWMutex
closedArgsForCall []struct {
arg1 protocol.DeviceID
arg1 string
arg2 error
}
ClusterConfigStub func(protocol.DeviceID, protocol.ClusterConfig) error
@ -728,10 +728,10 @@ func (fake *Model) BringToFrontArgsForCall(i int) (string, string) {
return argsForCall.arg1, argsForCall.arg2
}
func (fake *Model) Closed(arg1 protocol.DeviceID, arg2 error) {
func (fake *Model) Closed(arg1 string, arg2 error) {
fake.closedMutex.Lock()
fake.closedArgsForCall = append(fake.closedArgsForCall, struct {
arg1 protocol.DeviceID
arg1 string
arg2 error
}{arg1, arg2})
stub := fake.ClosedStub
@ -748,13 +748,13 @@ func (fake *Model) ClosedCallCount() int {
return len(fake.closedArgsForCall)
}
func (fake *Model) ClosedCalls(stub func(protocol.DeviceID, error)) {
func (fake *Model) ClosedCalls(stub func(string, error)) {
fake.closedMutex.Lock()
defer fake.closedMutex.Unlock()
fake.ClosedStub = stub
}
func (fake *Model) ClosedArgsForCall(i int) (protocol.DeviceID, error) {
func (fake *Model) ClosedArgsForCall(i int) (string, error) {
fake.closedMutex.RLock()
defer fake.closedMutex.RUnlock()
argsForCall := fake.closedArgsForCall[i]

View File

@ -37,6 +37,7 @@ import (
"github.com/syncthing/syncthing/lib/ignore"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/scanner"
"github.com/syncthing/syncthing/lib/stats"
"github.com/syncthing/syncthing/lib/svcutil"
@ -143,6 +144,7 @@ type model struct {
fatalChan chan error
started chan struct{}
keyGen *protocol.KeyGenerator
promotionTimer *time.Timer
// fields protected by fmut
fmut sync.RWMutex
@ -159,9 +161,10 @@ type model struct {
// fields protected by pmut
pmut sync.RWMutex
conn map[protocol.DeviceID]protocol.Connection
conns map[string]protocol.Connection // connection ID -> connection
deviceConns map[protocol.DeviceID][]string // device -> connection IDs (invariant: if the key exists, the value is len >= 1, with the primary connection at the start of the slice)
connRequestLimiters map[protocol.DeviceID]*util.Semaphore
closed map[protocol.DeviceID]chan struct{}
closed map[string]chan struct{} // connection ID -> closed channel
helloMessages map[protocol.DeviceID]protocol.Hello
deviceDownloads map[protocol.DeviceID]*deviceDownloadState
remoteFolderStates map[protocol.DeviceID]map[string]remoteFolderState // deviceID -> folders
@ -227,6 +230,7 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
fatalChan: make(chan error),
started: make(chan struct{}),
keyGen: keyGen,
promotionTimer: time.NewTimer(0),
// fields protected by fmut
fmut: sync.NewRWMutex(),
@ -242,9 +246,10 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
// fields protected by pmut
pmut: sync.NewRWMutex(),
conn: make(map[protocol.DeviceID]protocol.Connection),
conns: make(map[string]protocol.Connection),
deviceConns: make(map[protocol.DeviceID][]string),
connRequestLimiters: make(map[protocol.DeviceID]*util.Semaphore),
closed: make(map[protocol.DeviceID]chan struct{}),
closed: make(map[string]chan struct{}),
helloMessages: make(map[protocol.DeviceID]protocol.Hello),
deviceDownloads: make(map[protocol.DeviceID]*deviceDownloadState),
remoteFolderStates: make(map[protocol.DeviceID]map[string]remoteFolderState),
@ -272,11 +277,15 @@ func (m *model) serve(ctx context.Context) error {
close(m.started)
for {
select {
case <-ctx.Done():
return ctx.Err()
case err := <-m.fatalChan:
return svcutil.AsFatalErr(err, svcutil.ExitError)
case <-m.promotionTimer.C:
m.promoteConnections()
}
}
}
@ -303,9 +312,9 @@ func (m *model) initFolders(cfg config.Configuration) error {
func (m *model) closeAllConnectionsAndWait() {
m.pmut.RLock()
closed := make([]chan struct{}, 0, len(m.conn))
for id, conn := range m.conn {
closed = append(closed, m.closed[id])
closed := make([]chan struct{}, 0, len(m.conns))
for connID, conn := range m.conns {
closed = append(closed, m.closed[connID])
go conn.Close(errStopped)
}
m.pmut.RUnlock()
@ -639,7 +648,7 @@ func (m *model) UsageReportingStats(report *contract.Report, version int, previe
// Transport stats
m.pmut.RLock()
for _, conn := range m.conn {
for _, conn := range m.conns {
report.TransportStats[conn.Transport()]++
}
m.pmut.RUnlock()
@ -718,7 +727,7 @@ type ConnectionInfo struct {
func (m *model) NumConnections() int {
m.pmut.RLock()
defer m.pmut.RUnlock()
return len(m.conn)
return len(m.deviceConns)
}
// ConnectionStats returns a map with connection statistics for each device.
@ -739,7 +748,8 @@ func (m *model) ConnectionStats() map[string]interface{} {
ClientVersion: strings.TrimSpace(versionString),
Paused: deviceCfg.Paused,
}
if conn, ok := m.conn[device]; ok {
if connIDs, ok := m.deviceConns[device]; ok {
conn := m.conns[connIDs[0]] // XXX: only accounts primary, should account all
ci.Type = conn.Type()
ci.IsLocal = conn.IsLocal()
ci.Crypto = conn.Crypto()
@ -1258,12 +1268,16 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
})
if len(tempIndexFolders) > 0 {
var connOK bool
var conn protocol.Connection
m.pmut.RLock()
conn, ok := m.conn[deviceID]
if connIDs, connIDOK := m.deviceConns[deviceID]; connIDOK {
conn, connOK = m.conns[connIDs[0]]
}
m.pmut.RUnlock()
// In case we've got ClusterConfig, and the connection disappeared
// from infront of our nose.
if ok {
if connOK {
m.progressEmitter.temporaryIndexSubscribe(conn, tempIndexFolders)
}
}
@ -1537,8 +1551,8 @@ func (m *model) sendClusterConfig(ids []protocol.DeviceID) {
ccConns := make([]protocol.Connection, 0, len(ids))
m.pmut.RLock()
for _, id := range ids {
if conn, ok := m.conn[id]; ok {
ccConns = append(ccConns, conn)
if connIDs, ok := m.deviceConns[id]; ok {
ccConns = append(ccConns, m.conns[connIDs[0]])
}
}
m.pmut.RUnlock()
@ -1774,26 +1788,40 @@ func (m *model) introduceDevice(device protocol.Device, introducerCfg config.Dev
}
// Closed is called when a connection has been closed
func (m *model) Closed(device protocol.DeviceID, err error) {
func (m *model) Closed(connID string, err error) {
m.pmut.Lock()
conn, ok := m.conn[device]
conn, ok := m.conns[connID]
if !ok {
m.pmut.Unlock()
return
}
delete(m.conn, device)
closed := m.closed[connID]
delete(m.closed, connID)
delete(m.conns, connID)
device := conn.ID()
removedIsPrimary := m.deviceConns[device][0] == connID
remainingConns := without(m.deviceConns[device], connID)
// XXX: all the below needs more thinking about when to remove what
if removedIsPrimary {
m.progressEmitter.temporaryIndexUnsubscribe(conn)
delete(m.indexHandlers, device)
delete(m.deviceDownloads, device)
m.scheduleConnectionPromotion()
}
if len(remainingConns) == 0 {
// All device connections closed
delete(m.deviceConns, device)
delete(m.connRequestLimiters, device)
delete(m.helloMessages, device)
delete(m.deviceDownloads, device)
delete(m.remoteFolderStates, device)
closed := m.closed[device]
delete(m.closed, device)
delete(m.indexHandlers, device)
m.pmut.Unlock()
m.progressEmitter.temporaryIndexUnsubscribe(conn)
m.deviceDidClose(device, time.Since(conn.EstablishedAt()))
} else {
// Some connections remain
m.deviceConns[device] = remainingConns
}
m.pmut.Unlock()
l.Infof("Connection to %s at %s closed: %v", device, conn, err)
m.evLogger.Log(events.DeviceDisconnected, map[string]string{
@ -2070,13 +2098,17 @@ func (m *model) GetMtimeMapping(folder string, file string) (fs.MtimeMapping, er
// Connection returns the current connection for device, and a boolean whether a connection was found.
func (m *model) Connection(deviceID protocol.DeviceID) (protocol.Connection, bool) {
var conn protocol.Connection
m.pmut.RLock()
cn, ok := m.conn[deviceID]
connID, ok := m.deviceConns[deviceID]
if ok {
conn = m.conns[connID[0]]
}
m.pmut.RUnlock()
if ok {
m.deviceWasSeen(deviceID)
}
return cn, ok
return conn, ok
}
// LoadIgnores loads or refreshes the ignore patterns from disk, if the
@ -2215,52 +2247,22 @@ func (m *model) GetHello(id protocol.DeviceID) protocol.HelloIntf {
// folder changes.
func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
deviceID := conn.ID()
device, ok := m.cfg.Device(deviceID)
deviceCfg, ok := m.cfg.Device(deviceID)
if !ok {
l.Infoln("Trying to add connection to unknown device")
return
}
// The slightly unusual locking sequence here is because we must acquire
// fmut before pmut. (The locks can be *released* in any order.)
m.fmut.RLock()
m.pmut.Lock()
if oldConn, ok := m.conn[deviceID]; ok {
l.Infoln("Replacing old connection", oldConn, "with", conn, "for", deviceID)
// There is an existing connection to this device that we are
// replacing. We must close the existing connection and wait for the
// close to complete before adding the new connection. We do the
// actual close without holding pmut as the connection will call
// back into Closed() for the cleanup.
closed := m.closed[deviceID]
m.fmut.RUnlock()
m.pmut.Unlock()
oldConn.Close(errReplacingConnection)
<-closed
// Again, lock fmut before pmut.
m.fmut.RLock()
m.pmut.Lock()
}
m.conn[deviceID] = conn
connID := conn.ConnectionID()
closed := make(chan struct{})
m.closed[deviceID] = closed
m.deviceDownloads[deviceID] = newDeviceDownloadState()
indexRegistry := newIndexHandlerRegistry(conn, m.deviceDownloads[deviceID], closed, m.Supervisor, m.evLogger)
for id, fcfg := range m.folderCfgs {
indexRegistry.RegisterFolderState(fcfg, m.folderFiles[id], m.folderRunners[id])
}
m.indexHandlers[deviceID] = indexRegistry
m.fmut.RUnlock()
// 0: default, <0: no limiting
switch {
case device.MaxRequestKiB > 0:
m.connRequestLimiters[deviceID] = util.NewSemaphore(1024 * device.MaxRequestKiB)
case device.MaxRequestKiB == 0:
m.connRequestLimiters[deviceID] = util.NewSemaphore(1024 * defaultPullerPendingKiB)
}
m.pmut.Lock()
m.conns[connID] = conn
m.closed[connID] = closed
m.helloMessages[deviceID] = hello
m.deviceConns[deviceID] = append(m.deviceConns[deviceID], connID)
event := map[string]string{
"id": deviceID.String(),
@ -2280,14 +2282,10 @@ func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
l.Infof(`Device %s client is "%s %s" named "%s" at %s`, deviceID, hello.ClientName, hello.ClientVersion, hello.DeviceName, conn)
conn.Start()
m.pmut.Unlock()
// Acquires fmut, so has to be done outside of pmut.
cm, passwords := m.generateClusterConfig(deviceID)
conn.SetFolderPasswords(passwords)
conn.ClusterConfig(cm)
if (device.Name == "" || m.cfg.Options().OverwriteRemoteDevNames) && hello.DeviceName != "" {
if (deviceCfg.Name == "" || m.cfg.Options().OverwriteRemoteDevNames) && hello.DeviceName != "" {
m.cfg.Modify(func(cfg *config.Configuration) {
for i := range cfg.Devices {
if cfg.Devices[i].DeviceID == deviceID {
@ -2301,6 +2299,50 @@ func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
}
m.deviceWasSeen(deviceID)
m.scheduleConnectionPromotion()
}
func (m *model) scheduleConnectionPromotion() {
m.promotionTimer.Reset(time.Second)
}
// promoteConnections checks for devices that have connections, but where
// the primary connection hasn't started index handlers etc. yet, and
// promotes the primary connection to be the index handling one. This should
// be called after adding new connections, and after closing a primary
// device connection.
func (m *model) promoteConnections() {
m.fmut.RLock() // for generateClusterConfigFRLocked called by promoteDeviceConnectionLocked
defer m.fmut.RUnlock()
m.pmut.Lock() // for most other things
defer m.pmut.Unlock()
for deviceID, connIDs := range m.deviceConns {
if _, ok := m.indexHandlers[deviceID]; !ok {
// Connected device lacks and index handler. We should promote
// the primary connection to be the index handling one.
l.Infoln("Promoting connection", connIDs[0], "to", deviceID)
m.promoteDeviceConnectionLocked(m.conns[connIDs[0]])
}
}
}
func (m *model) promoteDeviceConnectionLocked(conn protocol.Connection) {
deviceID := conn.ID()
connID := conn.ConnectionID()
m.deviceDownloads[deviceID] = newDeviceDownloadState()
indexRegistry := newIndexHandlerRegistry(conn, m.deviceDownloads[deviceID], m.closed[connID], m.Supervisor, m.evLogger)
for id, fcfg := range m.folderCfgs {
indexRegistry.RegisterFolderState(fcfg, m.folderFiles[id], m.folderRunners[id])
}
m.indexHandlers[deviceID] = indexRegistry
cm, passwords := m.generateClusterConfigFRLocked(deviceID)
conn.SetFolderPasswords(passwords)
conn.ClusterConfig(cm)
}
func (m *model) DownloadProgress(device protocol.DeviceID, folder string, updates []protocol.FileDownloadProgressUpdate) error {
@ -2346,17 +2388,27 @@ func (m *model) deviceDidClose(deviceID protocol.DeviceID, duration time.Duratio
}
func (m *model) requestGlobal(ctx context.Context, deviceID protocol.DeviceID, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
var conn protocol.Connection
var connOK bool
m.pmut.RLock()
nc, ok := m.conn[deviceID]
if connIDs, ok := m.deviceConns[deviceID]; ok {
connID := connIDs[0]
if len(connIDs) > 1 {
// Pick a random connection of the non-primary ones
idx := rand.Intn(len(connIDs)-1) + 1
connID = connIDs[idx]
}
conn, connOK = m.conns[connID]
}
m.pmut.RUnlock()
if !ok {
if !connOK {
return nil, fmt.Errorf("requestGlobal: no such device: %s", deviceID)
}
l.Debugf("%v REQ(out): %s: %q / %q b=%d o=%d s=%d h=%x wh=%x ft=%t", m, deviceID, folder, name, blockNo, offset, size, hash, weakHash, fromTemporary)
return nc.Request(ctx, folder, name, blockNo, offset, size, hash, weakHash, fromTemporary)
return conn.Request(ctx, folder, name, blockNo, offset, size, hash, weakHash, fromTemporary)
}
func (m *model) ScanFolders() map[string]error {
@ -2447,11 +2499,13 @@ func (m *model) numHashers(folder string) int {
// generateClusterConfig returns a ClusterConfigMessage that is correct and the
// set of folder passwords for the given peer device
func (m *model) generateClusterConfig(device protocol.DeviceID) (protocol.ClusterConfig, map[string]string) {
var message protocol.ClusterConfig
m.fmut.RLock()
defer m.fmut.RUnlock()
return m.generateClusterConfigFRLocked(device)
}
func (m *model) generateClusterConfigFRLocked(device protocol.DeviceID) (protocol.ClusterConfig, map[string]string) {
var message protocol.ClusterConfig
folders := m.cfg.FolderList()
passwords := make(map[string]string, len(folders))
for _, folderCfg := range folders {
@ -2763,7 +2817,7 @@ func (m *model) availabilityInSnapshotPRlocked(cfg config.FolderConfiguration, s
if state := m.remoteFolderStates[device][cfg.ID]; state != remoteFolderValid {
continue
}
_, ok := m.conn[device]
_, ok := m.deviceConns[device]
if ok {
availabilities = append(availabilities, Availability{ID: device, FromTemporary: false})
}
@ -2933,6 +2987,16 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool {
l.Infoln("Resuming", deviceID)
m.evLogger.Log(events.DeviceResumed, map[string]string{"device": deviceID.String()})
}
// 0: default, <0: no limiting
m.pmut.Lock()
switch {
case toCfg.MaxRequestKiB > 0:
m.connRequestLimiters[deviceID] = util.NewSemaphore(1024 * toCfg.MaxRequestKiB)
case toCfg.MaxRequestKiB == 0:
m.connRequestLimiters[deviceID] = util.NewSemaphore(1024 * defaultPullerPendingKiB)
}
m.pmut.Unlock()
}
// Clean up after removed devices
removedDevices := make([]protocol.DeviceID, 0, len(fromDevices))
@ -2947,14 +3011,18 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool {
m.pmut.RLock()
for _, id := range closeDevices {
delete(clusterConfigDevices, id)
if conn, ok := m.conn[id]; ok {
go conn.Close(errDevicePaused)
if conns, ok := m.deviceConns[id]; ok {
for _, connID := range conns {
go m.conns[connID].Close(errDevicePaused)
}
}
}
for _, id := range removedDevices {
delete(clusterConfigDevices, id)
if conn, ok := m.conn[id]; ok {
go conn.Close(errDeviceRemoved)
if conns, ok := m.deviceConns[id]; ok {
for _, connID := range conns {
go m.conns[connID].Close(errDevicePaused)
}
}
}
m.pmut.RUnlock()
@ -3324,3 +3392,12 @@ type redactedError struct {
error
redacted error
}
func without[E comparable, S ~[]E](s S, e E) S {
for i, x := range s {
if x == e {
return append(s[:i], s[i+1:]...)
}
}
return s
}

View File

@ -287,7 +287,7 @@ func TestDeviceRename(t *testing.T) {
t.Errorf("Device already has a name")
}
m.Closed(conn.ID(), protocol.ErrTimeout)
m.Closed(conn.ConnectionID(), protocol.ErrTimeout)
hello.DeviceName = "tester"
m.AddConnection(conn, hello)
@ -295,7 +295,7 @@ func TestDeviceRename(t *testing.T) {
t.Errorf("Device did not get a name")
}
m.Closed(conn.ID(), protocol.ErrTimeout)
m.Closed(conn.ConnectionID(), protocol.ErrTimeout)
hello.DeviceName = "tester2"
m.AddConnection(conn, hello)
@ -317,7 +317,7 @@ func TestDeviceRename(t *testing.T) {
t.Errorf("Device name not saved in config")
}
m.Closed(conn.ID(), protocol.ErrTimeout)
m.Closed(conn.ConnectionID(), protocol.ErrTimeout)
waiter, err := cfg.Modify(func(cfg *config.Configuration) {
cfg.Options.OverwriteRemoteDevNames = true
@ -903,10 +903,10 @@ func TestIssue5063(t *testing.T) {
defer cancel()
m.pmut.Lock()
for _, c := range m.conn {
for _, c := range m.conns {
conn := c.(*fakeConnection)
conn.CloseCalls(func(_ error) {})
defer m.Closed(c.ID(), errStopped) // to unblock deferred m.Stop()
defer m.Closed(c.ConnectionID(), errStopped) // to unblock deferred m.Stop()
}
m.pmut.Unlock()
@ -2229,7 +2229,7 @@ func TestSharedWithClearedOnDisconnect(t *testing.T) {
t.Error("device still in config")
}
if _, ok := m.conn[device2]; ok {
if _, ok := m.deviceConns[device2]; ok {
t.Error("conn not missing")
}
@ -2964,12 +2964,13 @@ func TestConnCloseOnRestart(t *testing.T) {
br := &testutils.BlockingRW{}
nw := &testutils.NoopRW{}
m.AddConnection(protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, new(protocolmocks.ConnectionInfo), protocol.CompressionNever, nil, m.keyGen), protocol.Hello{})
conn := protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, new(protocolmocks.ConnectionInfo), protocol.CompressionNever, nil, m.keyGen)
m.AddConnection(conn, protocol.Hello{})
m.pmut.RLock()
if len(m.closed) != 1 {
t.Fatalf("Expected just one conn (len(m.conn) == %v)", len(m.conn))
t.Fatalf("Expected just one conn (len(m.conns) == %v)", len(m.conns))
}
closed := m.closed[device1]
closed := m.closed[conn.ConnectionID()]
m.pmut.RUnlock()
waiter, err := w.RemoveDevice(device1)
@ -3064,7 +3065,7 @@ func TestDevicePause(t *testing.T) {
defer sub.Unsubscribe()
m.pmut.RLock()
closed := m.closed[device1]
closed := m.closed[m.deviceConns[device1][0]]
m.pmut.RUnlock()
pauseDevice(t, m.cfg, device1, true)

View File

@ -188,7 +188,7 @@ func (*fakeModel) ClusterConfig(_ DeviceID, _ ClusterConfig) error {
return nil
}
func (*fakeModel) Closed(DeviceID, error) {
func (*fakeModel) Closed(string, error) {
}
func (*fakeModel) DownloadProgress(_ DeviceID, _ string, _ []FileDownloadProgressUpdate) error {

View File

@ -49,7 +49,7 @@ func (t *TestModel) Request(_ DeviceID, folder, name string, _, size int32, offs
return &fakeRequestResponse{buf}, nil
}
func (t *TestModel) Closed(_ DeviceID, err error) {
func (t *TestModel) Closed(_ string, err error) {
t.closedErr = err
close(t.closedCh)
}

View File

@ -155,8 +155,8 @@ func (e encryptedModel) ClusterConfig(deviceID DeviceID, config ClusterConfig) e
return e.model.ClusterConfig(deviceID, config)
}
func (e encryptedModel) Closed(device DeviceID, err error) {
e.model.Closed(device, err)
func (e encryptedModel) Closed(connID string, err error) {
e.model.Closed(connID, err)
}
// The encryptedConnection sits between the model and the encrypted device. It

View File

@ -131,7 +131,7 @@ type Model interface {
// A cluster configuration message was received
ClusterConfig(deviceID DeviceID, config ClusterConfig) error
// The peer device closed the connection or an error occurred
Closed(device DeviceID, err error)
Closed(connID string, err error)
// The peer device sent progress updates for the files it is currently downloading
DownloadProgress(deviceID DeviceID, folder string, updates []FileDownloadProgressUpdate) error
}
@ -941,7 +941,7 @@ func (c *rawConnection) internalClose(err error) {
<-c.dispatcherLoopStopped
c.receiver.Closed(c.ID(), err)
c.receiver.Closed(c.ConnectionID(), err)
})
}

View File

@ -1,13 +1,23 @@
<configuration version="32">
<configuration version="37">
<folder id="default" label="" path="s1/" type="sendreceive" rescanIntervalS="10" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy=""></device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy=""></device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy=""></device>
<device id="7PBCTLL-JJRYBSA-MOWZRKL-MSDMN4N-4US4OMX-SYEXUS4-HSBGNRY-CZXRXAT" introducedBy=""></device>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="7PBCTLL-JJRYBSA-MOWZRKL-MSDMN4N-4US4OMX-SYEXUS4-HSBGNRY-CZXRXAT" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>1</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
@ -24,20 +34,34 @@
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>0</maxConcurrentWrites>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>true</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>0</maxSingleEntrySize>
<maxTotalSize>0</maxTotalSize>
</xattrFilter>
</folder>
<folder id="¯\_(ツ)_/¯ Räksmörgås 动作 Адрес" label="" path="s12-1/" type="sendreceive" rescanIntervalS="10" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy=""></device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy=""></device>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>1</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
@ -54,12 +78,20 @@
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>0</maxConcurrentWrites>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>true</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>0</maxSingleEntrySize>
<maxTotalSize>0</maxTotalSize>
</xattrFilter>
</folder>
<device id="EJHMPAQ-OGCVORE-ISB4IS3-SYYVJXF-TKJGLTU-66DIQPF-GJ5D2GX-GQ3OWQK" name="s4" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22004</address>
@ -68,6 +100,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" name="s1" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22001</address>
@ -76,6 +110,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" name="s2" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22002</address>
@ -84,6 +120,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" name="s3" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22003</address>
@ -92,6 +130,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="7PBCTLL-JJRYBSA-MOWZRKL-MSDMN4N-4US4OMX-SYEXUS4-HSBGNRY-CZXRXAT" name="s4" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22004</address>
@ -100,6 +140,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<gui enabled="true" tls="false" debugging="true">
<address>127.0.0.1:8081</address>
@ -132,7 +174,6 @@
<urURL>https://data.syncthing.net/newdata</urURL>
<urPostInsecurely>false</urPostInsecurely>
<urInitialDelayS>1800</urInitialDelayS>
<restartOnWakeup>true</restartOnWakeup>
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
<upgradeToPreReleases>false</upgradeToPreReleases>
<keepTemporariesH>24</keepTemporariesH>
@ -144,7 +185,6 @@
<overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect>
<tempIndexMinBlocks>10</tempIndexMinBlocks>
<trafficClass>0</trafficClass>
<defaultFolderPath>~</defaultFolderPath>
<setLowPriority>true</setLowPriority>
<maxFolderConcurrency>0</maxFolderConcurrency>
<crashReportingURL>https://crash.syncthing.net/newcrash</crashReportingURL>
@ -155,5 +195,69 @@
<databaseTuning>auto</databaseTuning>
<maxConcurrentIncomingRequestKiB>0</maxConcurrentIncomingRequestKiB>
<announceLANAddresses>true</announceLANAddresses>
<sendFullIndexOnUpgrade>false</sendFullIndexOnUpgrade>
<connectionLimitEnough>0</connectionLimitEnough>
<connectionLimitMax>0</connectionLimitMax>
<insecureAllowOldTLSVersions>false</insecureAllowOldTLSVersions>
<connectionPriorityTcpLan>10</connectionPriorityTcpLan>
<connectionPriorityQuicLan>20</connectionPriorityQuicLan>
<connectionPriorityTcpWan>30</connectionPriorityTcpWan>
<connectionPriorityQuicWan>40</connectionPriorityQuicWan>
<connectionPriorityRelay>50</connectionPriorityRelay>
<connectionPriorityUpgradeThreshold>0</connectionPriorityUpgradeThreshold>
</options>
<defaults>
<folder id="" label="" path="~" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>0</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
<hashers>0</hashers>
<order>random</order>
<ignoreDelete>false</ignoreDelete>
<scanProgressIntervalS>0</scanProgressIntervalS>
<pullerPauseS>0</pullerPauseS>
<maxConflicts>10</maxConflicts>
<disableSparseFiles>false</disableSparseFiles>
<disableTempIndexes>false</disableTempIndexes>
<paused>false</paused>
<weakHashThresholdPct>25</weakHashThresholdPct>
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>false</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>1024</maxSingleEntrySize>
<maxTotalSize>4096</maxTotalSize>
</xattrFilter>
</folder>
<device id="" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>dynamic</address>
<paused>false</paused>
<autoAcceptFolders>false</autoAcceptFolders>
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<ignores></ignores>
</defaults>
</configuration>

View File

@ -1,12 +1,20 @@
<configuration version="32">
<configuration version="37">
<folder id="default" label="" path="s2" type="sendreceive" rescanIntervalS="15" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy=""></device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy=""></device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy=""></device>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>1</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
@ -23,20 +31,34 @@
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>0</maxConcurrentWrites>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>true</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>0</maxSingleEntrySize>
<maxTotalSize>0</maxTotalSize>
</xattrFilter>
</folder>
<folder id="s23" label="" path="s23-2" type="sendreceive" rescanIntervalS="15" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy=""></device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy=""></device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>1</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
@ -53,20 +75,34 @@
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>0</maxConcurrentWrites>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>true</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>0</maxSingleEntrySize>
<maxTotalSize>0</maxTotalSize>
</xattrFilter>
</folder>
<folder id="¯\_(ツ)_/¯ Räksmörgås 动作 Адрес" label="" path="s12-2" type="sendreceive" rescanIntervalS="15" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy=""></device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy=""></device>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>1</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
@ -83,12 +119,20 @@
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>0</maxConcurrentWrites>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>true</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>0</maxSingleEntrySize>
<maxTotalSize>0</maxTotalSize>
</xattrFilter>
</folder>
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU" name="s1" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22001</address>
@ -97,6 +141,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" name="s2" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22002</address>
@ -105,6 +151,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU" name="s3" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://127.0.0.1:22003</address>
@ -113,6 +161,8 @@
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<gui enabled="true" tls="false" debugging="true">
<address>127.0.0.1:8082</address>
@ -144,7 +194,6 @@
<urURL>https://data.syncthing.net/newdata</urURL>
<urPostInsecurely>false</urPostInsecurely>
<urInitialDelayS>1800</urInitialDelayS>
<restartOnWakeup>true</restartOnWakeup>
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
<upgradeToPreReleases>false</upgradeToPreReleases>
<keepTemporariesH>24</keepTemporariesH>
@ -156,7 +205,6 @@
<overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect>
<tempIndexMinBlocks>10</tempIndexMinBlocks>
<trafficClass>0</trafficClass>
<defaultFolderPath>~</defaultFolderPath>
<setLowPriority>true</setLowPriority>
<maxFolderConcurrency>0</maxFolderConcurrency>
<crashReportingURL>https://crash.syncthing.net/newcrash</crashReportingURL>
@ -167,5 +215,69 @@
<databaseTuning>auto</databaseTuning>
<maxConcurrentIncomingRequestKiB>0</maxConcurrentIncomingRequestKiB>
<announceLANAddresses>true</announceLANAddresses>
<sendFullIndexOnUpgrade>false</sendFullIndexOnUpgrade>
<connectionLimitEnough>0</connectionLimitEnough>
<connectionLimitMax>0</connectionLimitMax>
<insecureAllowOldTLSVersions>false</insecureAllowOldTLSVersions>
<connectionPriorityTcpLan>10</connectionPriorityTcpLan>
<connectionPriorityQuicLan>20</connectionPriorityQuicLan>
<connectionPriorityTcpWan>30</connectionPriorityTcpWan>
<connectionPriorityQuicWan>40</connectionPriorityQuicWan>
<connectionPriorityRelay>50</connectionPriorityRelay>
<connectionPriorityUpgradeThreshold>0</connectionPriorityUpgradeThreshold>
</options>
<defaults>
<folder id="" label="" path="~" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC" introducedBy="">
<encryptionPassword></encryptionPassword>
</device>
<minDiskFree unit="%">1</minDiskFree>
<versioning>
<cleanupIntervalS>3600</cleanupIntervalS>
<fsPath></fsPath>
<fsType>basic</fsType>
</versioning>
<copiers>0</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
<hashers>0</hashers>
<order>random</order>
<ignoreDelete>false</ignoreDelete>
<scanProgressIntervalS>0</scanProgressIntervalS>
<pullerPauseS>0</pullerPauseS>
<maxConflicts>10</maxConflicts>
<disableSparseFiles>false</disableSparseFiles>
<disableTempIndexes>false</disableTempIndexes>
<paused>false</paused>
<weakHashThresholdPct>25</weakHashThresholdPct>
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>false</junctionsAsDirs>
<syncOwnership>false</syncOwnership>
<sendOwnership>false</sendOwnership>
<syncXattrs>false</syncXattrs>
<sendXattrs>false</sendXattrs>
<xattrFilter>
<maxSingleEntrySize>1024</maxSingleEntrySize>
<maxTotalSize>4096</maxTotalSize>
</xattrFilter>
</folder>
<device id="" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>dynamic</address>
<paused>false</paused>
<autoAcceptFolders>false</autoAcceptFolders>
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
<untrusted>false</untrusted>
<remoteGUIPort>0</remoteGUIPort>
</device>
<ignores></ignores>
</defaults>
</configuration>