mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +00:00
Add LocalFlags to FileInfo (#4952)
We have the invalid bit to indicate that a file isn't good. That's enough for remote devices. For ourselves, it would be good to know sometimes why the file isn't good - because it's an unsupported type, because it matches an ignore pattern, or because we detected the data is bad and we need to rescan it. Or, and this is the main future reason for the PR, because it's a change detected on a receive only device. We will want something like the invalid flag for those changes, but marking them as invalid today means the scanner will rehash them. Hence something more fine grained is required. This introduces a LocalFlags fields to the FileInfo where we can stash things that we care about locally. For example, FlagLocalUnsupported = 1 << 0 // The kind is unsupported, e.g. symlinks on Windows FlagLocalIgnored = 1 << 1 // Matches local ignore patterns FlagLocalMustRescan = 1 << 2 // Doesn't match content on disk, must be rechecked fully The LocalFlags fields isn't sent over the wire; instead the Invalid attribute is calculated based on the flags at index sending time. It's on the FileInfo anyway because that's what we serialize to database etc. The actual Invalid flag should after this just be considered when building the global state and figuring out availability for remote devices. It is not used for local file index entries.
This commit is contained in:
parent
6df3940c26
commit
b1b68ceedb
@ -1497,13 +1497,16 @@ func (f jsonFileInfo) MarshalJSON() ([]byte, error) {
|
||||
"size": f.Size,
|
||||
"permissions": fmt.Sprintf("%#o", f.Permissions),
|
||||
"deleted": f.Deleted,
|
||||
"invalid": f.Invalid,
|
||||
"invalid": protocol.FileInfo(f).IsInvalid(),
|
||||
"ignored": protocol.FileInfo(f).IsIgnored(),
|
||||
"mustRescan": protocol.FileInfo(f).MustRescan(),
|
||||
"noPermissions": f.NoPermissions,
|
||||
"modified": protocol.FileInfo(f).ModTime(),
|
||||
"modifiedBy": f.ModifiedBy.String(),
|
||||
"sequence": f.Sequence,
|
||||
"numBlocks": len(f.Blocks),
|
||||
"version": jsonVersionVector(f.Version),
|
||||
"localFlags": f.LocalFlags,
|
||||
})
|
||||
}
|
||||
|
||||
@ -1516,11 +1519,16 @@ func (f jsonDBFileInfo) MarshalJSON() ([]byte, error) {
|
||||
"size": f.Size,
|
||||
"permissions": fmt.Sprintf("%#o", f.Permissions),
|
||||
"deleted": f.Deleted,
|
||||
"invalid": f.Invalid,
|
||||
"invalid": db.FileInfoTruncated(f).IsInvalid(),
|
||||
"ignored": db.FileInfoTruncated(f).IsIgnored(),
|
||||
"mustRescan": db.FileInfoTruncated(f).MustRescan(),
|
||||
"noPermissions": f.NoPermissions,
|
||||
"modified": db.FileInfoTruncated(f).ModTime(),
|
||||
"modifiedBy": f.ModifiedBy.String(),
|
||||
"sequence": f.Sequence,
|
||||
"numBlocks": nil, // explicitly unknown
|
||||
"version": jsonVersionVector(f.Version),
|
||||
"localFlags": f.LocalFlags,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -96,11 +96,8 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
||||
return true
|
||||
})
|
||||
|
||||
f3.Permissions = f1.Permissions
|
||||
f3.Deleted = f1.Deleted
|
||||
f3.Invalid = f1.Invalid
|
||||
f1.Deleted = true
|
||||
f2.Invalid = true
|
||||
f2.LocalFlags = protocol.FlagLocalMustRescan // one of the invalid markers
|
||||
|
||||
// Should remove
|
||||
err = m.Update([]protocol.FileInfo{f1, f2, f3})
|
||||
@ -145,14 +142,11 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
||||
}
|
||||
|
||||
f1.Deleted = false
|
||||
f1.Invalid = false
|
||||
f1.Permissions = 0
|
||||
f1.LocalFlags = 0
|
||||
f2.Deleted = false
|
||||
f2.Invalid = false
|
||||
f2.Permissions = 0
|
||||
f2.LocalFlags = 0
|
||||
f3.Deleted = false
|
||||
f3.Invalid = false
|
||||
f3.Permissions = 0
|
||||
f3.LocalFlags = 0
|
||||
}
|
||||
|
||||
func TestBlockFinderLookup(t *testing.T) {
|
||||
|
@ -61,7 +61,7 @@ func (vl VersionList) update(folder, device []byte, file protocol.FileInfo, db *
|
||||
nv := FileVersion{
|
||||
Device: device,
|
||||
Version: file.Version,
|
||||
Invalid: file.Invalid,
|
||||
Invalid: file.IsInvalid(),
|
||||
}
|
||||
for i, v := range vl.Versions {
|
||||
switch v.Version.Compare(file.Version) {
|
||||
|
@ -115,8 +115,9 @@ func (db *Instance) updateFiles(folder, device []byte, fs []protocol.FileInfo, m
|
||||
err = ef.Unmarshal(bs)
|
||||
}
|
||||
|
||||
// The Invalid flag might change without the version being bumped.
|
||||
if err == nil && ef.Version.Equal(f.Version) && ef.Invalid == f.Invalid {
|
||||
// Local flags or the invalid bit might change without the version
|
||||
// being bumped. The IsInvalid() method handles both.
|
||||
if err == nil && ef.Version.Equal(f.Version) && ef.IsInvalid() == f.IsInvalid() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
const dbVersion = 4
|
||||
const dbVersion = 5
|
||||
|
||||
func (db *Instance) updateSchema() {
|
||||
miscDB := NewNamespacedKV(db, string(KeyTypeMiscData))
|
||||
@ -23,8 +23,6 @@ func (db *Instance) updateSchema() {
|
||||
return
|
||||
}
|
||||
|
||||
l.Infof("Updating database schema version from %v to %v...", prevVersion, dbVersion)
|
||||
|
||||
if prevVersion < 1 {
|
||||
db.updateSchema0to1()
|
||||
}
|
||||
@ -38,6 +36,9 @@ func (db *Instance) updateSchema() {
|
||||
if prevVersion == 3 {
|
||||
db.updateSchema3to4()
|
||||
}
|
||||
if prevVersion < 5 {
|
||||
db.updateSchema4to5()
|
||||
}
|
||||
|
||||
miscDB.PutInt64("dbVersion", dbVersion)
|
||||
}
|
||||
@ -94,7 +95,7 @@ func (db *Instance) updateSchema0to1() {
|
||||
}
|
||||
|
||||
// Add invalid files to global list
|
||||
if f.Invalid {
|
||||
if f.IsInvalid() {
|
||||
gk = db.globalKeyInto(gk, folder, name)
|
||||
if t.updateGlobal(gk, folder, device, f, meta) {
|
||||
if _, ok := changedFolders[string(folder)]; !ok {
|
||||
@ -172,3 +173,33 @@ func (db *Instance) updateSchema3to4() {
|
||||
|
||||
db.updateSchema2to3()
|
||||
}
|
||||
|
||||
func (db *Instance) updateSchema4to5() {
|
||||
// For every local file with the Invalid bit set, clear the Invalid bit and
|
||||
// set LocalFlags = FlagLocalIgnored.
|
||||
|
||||
t := db.newReadWriteTransaction()
|
||||
defer t.close()
|
||||
|
||||
var dk []byte
|
||||
|
||||
for _, folderStr := range db.ListFolders() {
|
||||
folder := []byte(folderStr)
|
||||
db.withHave(folder, protocol.LocalDeviceID[:], nil, false, func(f FileIntf) bool {
|
||||
if !f.IsInvalid() {
|
||||
return true
|
||||
}
|
||||
|
||||
fi := f.(protocol.FileInfo)
|
||||
fi.RawInvalid = false
|
||||
fi.LocalFlags = protocol.FlagLocalIgnored
|
||||
bs, _ := fi.Marshal()
|
||||
|
||||
dk = db.deviceKeyInto(dk, folder, protocol.LocalDeviceID[:], []byte(fi.Name))
|
||||
t.Put(dk, bs)
|
||||
|
||||
t.checkFlush()
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ func TestDropIndexIDs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidFiles(t *testing.T) {
|
||||
func TestIgnoredFiles(t *testing.T) {
|
||||
ldb, err := openJSONS("testdata/v0.14.48-ignoredfiles.db.jsons")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -192,27 +192,42 @@ func TestInvalidFiles(t *testing.T) {
|
||||
// },
|
||||
// })
|
||||
|
||||
// Local files should have the "ignored" bit in addition to just being
|
||||
// generally invalid if we want to look at the simulation of that bit.
|
||||
|
||||
fi, ok := fs.Get(protocol.LocalDeviceID, "foo")
|
||||
if !ok {
|
||||
t.Fatal("foo should exist")
|
||||
}
|
||||
if !fi.Invalid {
|
||||
if !fi.IsInvalid() {
|
||||
t.Error("foo should be invalid")
|
||||
}
|
||||
if !fi.IsIgnored() {
|
||||
t.Error("foo should be ignored")
|
||||
}
|
||||
|
||||
fi, ok = fs.Get(protocol.LocalDeviceID, "bar")
|
||||
if !ok {
|
||||
t.Fatal("bar should exist")
|
||||
}
|
||||
if fi.Invalid {
|
||||
if fi.IsInvalid() {
|
||||
t.Error("bar should not be invalid")
|
||||
}
|
||||
if fi.IsIgnored() {
|
||||
t.Error("bar should not be ignored")
|
||||
}
|
||||
|
||||
// Remote files have the invalid bit as usual, and the IsInvalid() method
|
||||
// should pick this up too.
|
||||
|
||||
fi, ok = fs.Get(protocol.DeviceID{42}, "baz")
|
||||
if !ok {
|
||||
t.Fatal("baz should exist")
|
||||
}
|
||||
if !fi.Invalid {
|
||||
if !fi.IsInvalid() {
|
||||
t.Error("baz should be invalid")
|
||||
}
|
||||
if !fi.IsInvalid() {
|
||||
t.Error("baz should be invalid")
|
||||
}
|
||||
|
||||
@ -220,7 +235,10 @@ func TestInvalidFiles(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("quux should exist")
|
||||
}
|
||||
if fi.Invalid {
|
||||
if fi.IsInvalid() {
|
||||
t.Error("quux should not be invalid")
|
||||
}
|
||||
if fi.IsInvalid() {
|
||||
t.Error("quux should not be invalid")
|
||||
}
|
||||
}
|
||||
@ -245,13 +263,13 @@ func init() {
|
||||
},
|
||||
remoteDevice0: {
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(7)},
|
||||
},
|
||||
remoteDevice1: {
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: invalid, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: invalid, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func (t readWriteTransaction) insertFile(fk, folder, device []byte, file protoco
|
||||
// file. If the device is already present in the list, the version is updated.
|
||||
// If the file does not have an entry in the global list, it is created.
|
||||
func (t readWriteTransaction) updateGlobal(gk, folder, device []byte, file protocol.FileInfo, meta *metadataTracker) bool {
|
||||
l.Debugf("update global; folder=%q device=%v file=%q version=%v invalid=%v", folder, protocol.DeviceIDFromBytes(device), file.Name, file.Version, file.Invalid)
|
||||
l.Debugf("update global; folder=%q device=%v file=%q version=%v invalid=%v", folder, protocol.DeviceIDFromBytes(device), file.Name, file.Version, file.IsInvalid())
|
||||
|
||||
var fl VersionList
|
||||
if svl, err := t.Get(gk, nil); err == nil {
|
||||
|
@ -147,7 +147,7 @@ func (s *FileSet) Update(device protocol.DeviceID, fs []protocol.FileInfo) {
|
||||
for _, nf := range oldFs {
|
||||
dk = s.db.deviceKeyInto(dk, folder, device[:], []byte(osutil.NormalizedFilename(nf.Name)))
|
||||
ef, ok := s.db.getFile(dk)
|
||||
if ok && ef.Version.Equal(nf.Version) && ef.Invalid == nf.Invalid {
|
||||
if ok && ef.Version.Equal(nf.Version) && ef.IsInvalid() == nf.IsInvalid() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ func (l fileList) String() string {
|
||||
func TestGlobalSet(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local0 := fileList{
|
||||
protocol.FileInfo{Name: "a", Sequence: 1, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
@ -332,20 +332,20 @@ func TestGlobalSet(t *testing.T) {
|
||||
func TestNeedWithInvalid(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
localHave := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
}
|
||||
remote0Have := fileList{
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(7)},
|
||||
}
|
||||
remote1Have := fileList{
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
}
|
||||
|
||||
expectedNeed := fileList{
|
||||
@ -369,16 +369,16 @@ func TestNeedWithInvalid(t *testing.T) {
|
||||
func TestUpdateToInvalid(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
folder := "test)"
|
||||
folder := "test"
|
||||
s := db.NewFileSet(folder, fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
f := db.NewBlockFinder(ldb)
|
||||
|
||||
localHave := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), LocalFlags: protocol.FlagLocalIgnored},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Invalid: true},
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, LocalFlags: protocol.FlagLocalIgnored},
|
||||
}
|
||||
|
||||
replace(s, protocol.LocalDeviceID, localHave)
|
||||
@ -391,10 +391,13 @@ func TestUpdateToInvalid(t *testing.T) {
|
||||
}
|
||||
|
||||
oldBlockHash := localHave[1].Blocks[0].Hash
|
||||
localHave[1].Invalid = true
|
||||
|
||||
localHave[1].LocalFlags = protocol.FlagLocalIgnored
|
||||
localHave[1].Blocks = nil
|
||||
localHave[4].Invalid = false
|
||||
|
||||
localHave[4].LocalFlags = 0
|
||||
localHave[4].Blocks = genBlocks(3)
|
||||
|
||||
s.Update(protocol.LocalDeviceID, append(fileList{}, localHave[1], localHave[4]))
|
||||
|
||||
have = fileList(haveList(s, protocol.LocalDeviceID))
|
||||
@ -425,19 +428,19 @@ func TestUpdateToInvalid(t *testing.T) {
|
||||
func TestInvalidAvailability(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
remote0Have := fileList{
|
||||
protocol.FileInfo{Name: "both", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "r1only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "r1only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: "r0only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "none", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "none", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
}
|
||||
remote1Have := fileList{
|
||||
protocol.FileInfo{Name: "both", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "r1only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "r0only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "none", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "r0only", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
protocol.FileInfo{Name: "none", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1004}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
}
|
||||
|
||||
replace(s, remoteDevice0, remote0Have)
|
||||
@ -463,7 +466,7 @@ func TestInvalidAvailability(t *testing.T) {
|
||||
func TestGlobalReset(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local := []protocol.FileInfo{
|
||||
{Name: "a", Sequence: 1, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
|
||||
@ -501,7 +504,7 @@ func TestGlobalReset(t *testing.T) {
|
||||
func TestNeed(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local := []protocol.FileInfo{
|
||||
{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
|
||||
@ -539,7 +542,7 @@ func TestNeed(t *testing.T) {
|
||||
func TestSequence(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local1 := []protocol.FileInfo{
|
||||
{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
|
||||
@ -623,7 +626,7 @@ func TestGlobalNeedWithInvalid(t *testing.T) {
|
||||
|
||||
rem0 := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, RawInvalid: true},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: remoteDevice0.Short(), Value: 1002}}}},
|
||||
}
|
||||
@ -632,8 +635,8 @@ func TestGlobalNeedWithInvalid(t *testing.T) {
|
||||
rem1 := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true, ModifiedS: 10},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, RawInvalid: true},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, RawInvalid: true, ModifiedS: 10},
|
||||
}
|
||||
replace(s, remoteDevice1, rem1)
|
||||
|
||||
@ -690,7 +693,7 @@ func TestCommitted(t *testing.T) {
|
||||
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local := []protocol.FileInfo{
|
||||
{Name: string("file"), Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
|
||||
@ -736,7 +739,7 @@ func BenchmarkUpdateOneFile(b *testing.B) {
|
||||
os.RemoveAll("testdata/benchmarkupdate.db")
|
||||
}()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
replace(m, protocol.LocalDeviceID, local0)
|
||||
l := local0[4:5]
|
||||
|
||||
@ -751,7 +754,7 @@ func BenchmarkUpdateOneFile(b *testing.B) {
|
||||
func TestIndexID(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
// The Index ID for some random device is zero by default.
|
||||
id := s.IndexID(remoteDevice0)
|
||||
@ -783,7 +786,7 @@ func TestIndexID(t *testing.T) {
|
||||
func TestDropFiles(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
m := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
local0 := fileList{
|
||||
protocol.FileInfo{Name: "a", Sequence: 1, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
@ -846,11 +849,11 @@ func TestDropFiles(t *testing.T) {
|
||||
func TestIssue4701(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
localHave := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Invalid: true},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, LocalFlags: protocol.FlagLocalIgnored},
|
||||
}
|
||||
|
||||
s.Update(protocol.LocalDeviceID, localHave)
|
||||
@ -862,7 +865,7 @@ func TestIssue4701(t *testing.T) {
|
||||
t.Errorf("Expected 1 global file, got %v", c.Files)
|
||||
}
|
||||
|
||||
localHave[1].Invalid = false
|
||||
localHave[1].LocalFlags = 0
|
||||
s.Update(protocol.LocalDeviceID, localHave)
|
||||
|
||||
if c := s.LocalSize(); c.Files != 2 {
|
||||
@ -872,8 +875,8 @@ func TestIssue4701(t *testing.T) {
|
||||
t.Errorf("Expected 2 global files, got %v", c.Files)
|
||||
}
|
||||
|
||||
localHave[0].Invalid = true
|
||||
localHave[1].Invalid = true
|
||||
localHave[0].LocalFlags = protocol.FlagLocalIgnored
|
||||
localHave[1].LocalFlags = protocol.FlagLocalIgnored
|
||||
s.Update(protocol.LocalDeviceID, localHave)
|
||||
|
||||
if c := s.LocalSize(); c.Files != 0 {
|
||||
@ -887,16 +890,16 @@ func TestIssue4701(t *testing.T) {
|
||||
func TestWithHaveSequence(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
folder := "test)"
|
||||
folder := "test"
|
||||
s := db.NewFileSet(folder, fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
// The files must not be in alphabetical order
|
||||
localHave := fileList{
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Invalid: true},
|
||||
protocol.FileInfo{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, RawInvalid: true},
|
||||
protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1003}}}, Blocks: genBlocks(7)},
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), Invalid: true},
|
||||
protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(5), RawInvalid: true},
|
||||
}
|
||||
|
||||
replace(s, protocol.LocalDeviceID, localHave)
|
||||
@ -1018,7 +1021,7 @@ func TestIssue5007(t *testing.T) {
|
||||
t.Fatalf("Local need incorrect;\n A: %v !=\n E: %v", need[0], fs[0])
|
||||
}
|
||||
|
||||
fs[0].Invalid = true
|
||||
fs[0].LocalFlags = protocol.FlagLocalIgnored
|
||||
s.Update(protocol.LocalDeviceID, fs)
|
||||
|
||||
if need := needList(s, protocol.LocalDeviceID); len(need) != 0 {
|
||||
|
@ -17,8 +17,19 @@ import (
|
||||
)
|
||||
|
||||
func (f FileInfoTruncated) String() string {
|
||||
return fmt.Sprintf("File{Name:%q, Permissions:0%o, Modified:%v, Version:%v, Length:%d, Deleted:%v, Invalid:%v, NoPermissions:%v, BlockSize:%d}",
|
||||
f.Name, f.Permissions, f.ModTime(), f.Version, f.Size, f.Deleted, f.Invalid, f.NoPermissions, f.RawBlockSize)
|
||||
switch f.Type {
|
||||
case protocol.FileInfoTypeDirectory:
|
||||
return fmt.Sprintf("Directory{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions)
|
||||
case protocol.FileInfoTypeFile:
|
||||
return fmt.Sprintf("File{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Length:%d, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, BlockSize:%d}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Size, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.RawBlockSize)
|
||||
case protocol.FileInfoTypeSymlink, protocol.FileInfoTypeDeprecatedSymlinkDirectory, protocol.FileInfoTypeDeprecatedSymlinkFile:
|
||||
return fmt.Sprintf("Symlink{Name:%q, Type:%v, Sequence:%d, Version:%v, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, SymlinkTarget:%q}",
|
||||
f.Name, f.Type, f.Sequence, f.Version, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.SymlinkTarget)
|
||||
default:
|
||||
panic("mystery file type detected")
|
||||
}
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) IsDeleted() bool {
|
||||
@ -26,7 +37,15 @@ func (f FileInfoTruncated) IsDeleted() bool {
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) IsInvalid() bool {
|
||||
return f.Invalid
|
||||
return f.RawInvalid || f.LocalFlags&protocol.LocalInvalidFlags != 0
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) IsIgnored() bool {
|
||||
return f.LocalFlags&protocol.FlagLocalIgnored != 0
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) MustRescan() bool {
|
||||
return f.LocalFlags&protocol.FlagLocalMustRescan != 0
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) IsDirectory() bool {
|
||||
@ -79,15 +98,15 @@ func (f FileInfoTruncated) FileVersion() protocol.Vector {
|
||||
return f.Version
|
||||
}
|
||||
|
||||
func (f FileInfoTruncated) ConvertToInvalidFileInfo(invalidatedBy protocol.ShortID) protocol.FileInfo {
|
||||
func (f FileInfoTruncated) ConvertToIgnoredFileInfo(by protocol.ShortID) protocol.FileInfo {
|
||||
return protocol.FileInfo{
|
||||
Name: f.Name,
|
||||
Type: f.Type,
|
||||
ModifiedS: f.ModifiedS,
|
||||
ModifiedNs: f.ModifiedNs,
|
||||
ModifiedBy: invalidatedBy,
|
||||
Invalid: true,
|
||||
ModifiedBy: by,
|
||||
Version: f.Version,
|
||||
RawBlockSize: f.RawBlockSize,
|
||||
LocalFlags: protocol.FlagLocalIgnored,
|
||||
}
|
||||
}
|
||||
|
@ -66,13 +66,15 @@ type FileInfoTruncated struct {
|
||||
ModifiedNs int32 `protobuf:"varint,11,opt,name=modified_ns,json=modifiedNs,proto3" json:"modified_ns,omitempty"`
|
||||
ModifiedBy github_com_syncthing_syncthing_lib_protocol.ShortID `protobuf:"varint,12,opt,name=modified_by,json=modifiedBy,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.ShortID" json:"modified_by"`
|
||||
Deleted bool `protobuf:"varint,6,opt,name=deleted,proto3" json:"deleted,omitempty"`
|
||||
Invalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
RawInvalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
NoPermissions bool `protobuf:"varint,8,opt,name=no_permissions,json=noPermissions,proto3" json:"no_permissions,omitempty"`
|
||||
Version protocol.Vector `protobuf:"bytes,9,opt,name=version" json:"version"`
|
||||
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
RawBlockSize int32 `protobuf:"varint,13,opt,name=block_size,json=blockSize,proto3" json:"block_size,omitempty"`
|
||||
// repeated BlockInfo Blocks = 16
|
||||
SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
|
||||
// see bep.proto
|
||||
LocalFlags uint32 `protobuf:"varint,1000,opt,name=local_flags,json=localFlags,proto3" json:"local_flags,omitempty"`
|
||||
}
|
||||
|
||||
func (m *FileInfoTruncated) Reset() { *m = FileInfoTruncated{} }
|
||||
@ -236,10 +238,10 @@ func (m *FileInfoTruncated) MarshalTo(dAtA []byte) (int, error) {
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
dAtA[i] = 0x38
|
||||
i++
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
@ -292,6 +294,13 @@ func (m *FileInfoTruncated) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintStructs(dAtA, i, uint64(len(m.SymlinkTarget)))
|
||||
i += copy(dAtA[i:], m.SymlinkTarget)
|
||||
}
|
||||
if m.LocalFlags != 0 {
|
||||
dAtA[i] = 0xc0
|
||||
i++
|
||||
dAtA[i] = 0x3e
|
||||
i++
|
||||
i = encodeVarintStructs(dAtA, i, uint64(m.LocalFlags))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@ -462,7 +471,7 @@ func (m *FileInfoTruncated) ProtoSize() (n int) {
|
||||
if m.Deleted {
|
||||
n += 2
|
||||
}
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
n += 2
|
||||
}
|
||||
if m.NoPermissions {
|
||||
@ -486,6 +495,9 @@ func (m *FileInfoTruncated) ProtoSize() (n int) {
|
||||
if l > 0 {
|
||||
n += 2 + l + sovStructs(uint64(l))
|
||||
}
|
||||
if m.LocalFlags != 0 {
|
||||
n += 2 + sovStructs(uint64(m.LocalFlags))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -913,7 +925,7 @@ func (m *FileInfoTruncated) Unmarshal(dAtA []byte) error {
|
||||
m.Deleted = bool(v != 0)
|
||||
case 7:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Invalid", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field RawInvalid", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@ -930,7 +942,7 @@ func (m *FileInfoTruncated) Unmarshal(dAtA []byte) error {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Invalid = bool(v != 0)
|
||||
m.RawInvalid = bool(v != 0)
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NoPermissions", wireType)
|
||||
@ -1086,6 +1098,25 @@ func (m *FileInfoTruncated) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
m.SymlinkTarget = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 1000:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field LocalFlags", wireType)
|
||||
}
|
||||
m.LocalFlags = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowStructs
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.LocalFlags |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipStructs(dAtA[iNdEx:])
|
||||
@ -1510,45 +1541,47 @@ var (
|
||||
func init() { proto.RegisterFile("structs.proto", fileDescriptorStructs) }
|
||||
|
||||
var fileDescriptorStructs = []byte{
|
||||
// 630 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcf, 0x6a, 0xdb, 0x4c,
|
||||
0x10, 0xb7, 0x62, 0xc9, 0xb1, 0x47, 0x76, 0xbe, 0x64, 0x09, 0x41, 0x18, 0x3e, 0x5b, 0x18, 0x0a,
|
||||
0xa2, 0x50, 0xb9, 0x4d, 0xe8, 0xa5, 0xbd, 0xb9, 0x21, 0x10, 0x28, 0x6d, 0x59, 0x87, 0x9c, 0x0a,
|
||||
0xc6, 0x92, 0xd6, 0xce, 0x12, 0x79, 0xd7, 0xd1, 0xae, 0x52, 0x94, 0x27, 0xe9, 0x31, 0x4f, 0xd0,
|
||||
0xa7, 0xe8, 0x21, 0xc7, 0x9e, 0x7b, 0x08, 0xad, 0xfb, 0x22, 0x45, 0xbb, 0x92, 0xa2, 0xf4, 0xd4,
|
||||
0xde, 0xe6, 0x37, 0xff, 0x67, 0x7e, 0x33, 0xd0, 0x13, 0x32, 0x49, 0x43, 0x29, 0xfc, 0x75, 0xc2,
|
||||
0x25, 0x47, 0x5b, 0x51, 0xd0, 0x7f, 0xb6, 0xa4, 0xf2, 0x22, 0x0d, 0xfc, 0x90, 0xaf, 0xc6, 0x4b,
|
||||
0xbe, 0xe4, 0x63, 0x65, 0x0a, 0xd2, 0x85, 0x42, 0x0a, 0x28, 0x49, 0x87, 0xf4, 0x5f, 0xd6, 0xdc,
|
||||
0x45, 0xc6, 0x42, 0x79, 0x41, 0xd9, 0xb2, 0x26, 0xc5, 0x34, 0xd0, 0x19, 0x42, 0x1e, 0x8f, 0x03,
|
||||
0xb2, 0xd6, 0x61, 0xa3, 0x2b, 0xb0, 0x4f, 0x68, 0x4c, 0xce, 0x49, 0x22, 0x28, 0x67, 0xe8, 0x39,
|
||||
0x6c, 0x5f, 0x6b, 0xd1, 0x31, 0x5c, 0xc3, 0xb3, 0x0f, 0x77, 0xfd, 0x32, 0xc8, 0x3f, 0x27, 0xa1,
|
||||
0xe4, 0xc9, 0xc4, 0xbc, 0xbb, 0x1f, 0x36, 0x70, 0xe9, 0x86, 0x0e, 0xa0, 0x15, 0x91, 0x6b, 0x1a,
|
||||
0x12, 0x67, 0xcb, 0x35, 0xbc, 0x2e, 0x2e, 0x10, 0x72, 0x60, 0x9b, 0xb2, 0xeb, 0x79, 0x4c, 0x23,
|
||||
0xa7, 0xe9, 0x1a, 0x5e, 0x1b, 0x97, 0x70, 0x74, 0x02, 0x76, 0x51, 0xee, 0x2d, 0x15, 0x12, 0xbd,
|
||||
0x80, 0x76, 0x91, 0x4b, 0x38, 0x86, 0xdb, 0xf4, 0xec, 0xc3, 0xff, 0xfc, 0x28, 0xf0, 0x6b, 0x5d,
|
||||
0x15, 0x25, 0x2b, 0xb7, 0x57, 0xe6, 0xe7, 0xdb, 0x61, 0x63, 0xf4, 0xc5, 0x84, 0xbd, 0xdc, 0xeb,
|
||||
0x94, 0x2d, 0xf8, 0x59, 0x92, 0xb2, 0x70, 0x2e, 0x49, 0x84, 0x10, 0x98, 0x6c, 0xbe, 0x22, 0xaa,
|
||||
0xfd, 0x0e, 0x56, 0x32, 0x7a, 0x0a, 0xa6, 0xcc, 0xd6, 0xba, 0xc3, 0x9d, 0xc3, 0x83, 0x87, 0x91,
|
||||
0xaa, 0xf0, 0x6c, 0x4d, 0xb0, 0xf2, 0xc9, 0xe3, 0x05, 0xbd, 0x21, 0xaa, 0xe9, 0x26, 0x56, 0x32,
|
||||
0x72, 0xc1, 0x5e, 0x93, 0x64, 0x45, 0x85, 0xee, 0xd2, 0x74, 0x0d, 0xaf, 0x87, 0xeb, 0x2a, 0xf4,
|
||||
0x3f, 0xc0, 0x8a, 0x47, 0x74, 0x41, 0x49, 0x34, 0x13, 0x8e, 0xa5, 0x62, 0x3b, 0xa5, 0x66, 0x9a,
|
||||
0x2f, 0x23, 0x22, 0x31, 0x91, 0x24, 0x72, 0x5a, 0x7a, 0x19, 0x05, 0xac, 0xaf, 0x69, 0xfb, 0xd1,
|
||||
0x9a, 0xd0, 0x13, 0xd8, 0x61, 0x7c, 0x56, 0xaf, 0xdb, 0x56, 0x0e, 0x3d, 0xc6, 0x3f, 0xd4, 0x2a,
|
||||
0xd7, 0x18, 0xeb, 0xfc, 0x1d, 0x63, 0x7d, 0x68, 0x0b, 0x72, 0x95, 0x12, 0x16, 0x12, 0x07, 0x54,
|
||||
0xa7, 0x15, 0x46, 0x43, 0xb0, 0xab, 0x39, 0x98, 0x70, 0x6c, 0xd7, 0xf0, 0x2c, 0x5c, 0x8d, 0xf6,
|
||||
0x4e, 0xa0, 0x8f, 0x35, 0x87, 0x20, 0x73, 0xba, 0xae, 0xe1, 0x99, 0x93, 0xd7, 0x79, 0x81, 0xef,
|
||||
0xf7, 0xc3, 0xa3, 0x7f, 0xb8, 0x41, 0x7f, 0x7a, 0xc1, 0x13, 0x79, 0x7a, 0xfc, 0x90, 0x7d, 0x92,
|
||||
0xa1, 0x31, 0x40, 0x10, 0xf3, 0xf0, 0x72, 0xa6, 0x28, 0xe8, 0xe5, 0xd5, 0x27, 0xbb, 0x9b, 0xfb,
|
||||
0x61, 0x17, 0xcf, 0x3f, 0x4d, 0x72, 0xc3, 0x94, 0xde, 0x10, 0xdc, 0x09, 0x4a, 0x31, 0x5f, 0x92,
|
||||
0xc8, 0x56, 0x31, 0x65, 0x97, 0x33, 0x39, 0x4f, 0x96, 0x44, 0x3a, 0x7b, 0x8a, 0xf7, 0x5e, 0xa1,
|
||||
0x3d, 0x53, 0xca, 0xe2, 0x60, 0xbe, 0x1a, 0xd0, 0x7a, 0xc3, 0x53, 0x26, 0x05, 0xda, 0x07, 0x6b,
|
||||
0x41, 0x63, 0x22, 0xd4, 0x99, 0x58, 0x58, 0x83, 0x9c, 0xe7, 0x88, 0x26, 0x6a, 0x69, 0x94, 0x08,
|
||||
0x75, 0x2e, 0x16, 0xae, 0xab, 0xd4, 0xee, 0x74, 0x66, 0xa1, 0x2e, 0xc4, 0xc2, 0x15, 0xae, 0x93,
|
||||
0x6c, 0x2a, 0x53, 0x45, 0xf2, 0x3e, 0x58, 0x41, 0x26, 0x49, 0x79, 0x18, 0x1a, 0x3c, 0xe2, 0xa1,
|
||||
0xf5, 0x07, 0x0f, 0x7d, 0x68, 0xeb, 0x3f, 0x3a, 0x3d, 0x56, 0x13, 0x75, 0x71, 0x85, 0x47, 0xef,
|
||||
0xa1, 0xa3, 0xa7, 0x98, 0x12, 0x89, 0x3c, 0x68, 0x85, 0x0a, 0x14, 0xbf, 0x03, 0xf9, 0xef, 0x68,
|
||||
0x73, 0xc1, 0x7b, 0x61, 0xcf, 0xdb, 0x0b, 0x13, 0x92, 0xff, 0x88, 0x1a, 0xac, 0x89, 0x4b, 0x38,
|
||||
0xd9, 0xbf, 0xfb, 0x39, 0x68, 0xdc, 0x6d, 0x06, 0xc6, 0xb7, 0xcd, 0xc0, 0xf8, 0xb1, 0x19, 0x34,
|
||||
0x6e, 0x7f, 0x0d, 0x8c, 0xa0, 0xa5, 0x98, 0x3a, 0xfa, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x28, 0xfa,
|
||||
0x1e, 0x63, 0x9b, 0x04, 0x00, 0x00,
|
||||
// 663 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcd, 0x6a, 0xdb, 0x40,
|
||||
0x10, 0xb6, 0x62, 0xf9, 0x6f, 0x6c, 0xa7, 0xc9, 0x12, 0x82, 0x30, 0xd4, 0x16, 0x86, 0x82, 0x28,
|
||||
0xd4, 0x6e, 0x13, 0x7a, 0x69, 0x6f, 0x6a, 0x08, 0x18, 0x4a, 0x5b, 0xd6, 0x21, 0xa7, 0x82, 0xd1,
|
||||
0xcf, 0xda, 0x59, 0x22, 0x6b, 0x1d, 0xed, 0x3a, 0x41, 0x79, 0x92, 0x1e, 0xf3, 0x30, 0x3d, 0xe4,
|
||||
0xd8, 0x73, 0x0f, 0x26, 0x75, 0x2f, 0x7d, 0x8c, 0xb2, 0xbb, 0x92, 0xa2, 0xf6, 0xd4, 0xde, 0xe6,
|
||||
0x9b, 0x9f, 0x9d, 0x6f, 0x66, 0xbe, 0x85, 0x2e, 0x17, 0xc9, 0x3a, 0x10, 0x7c, 0xb4, 0x4a, 0x98,
|
||||
0x60, 0x68, 0x27, 0xf4, 0x7b, 0x2f, 0x16, 0x54, 0x5c, 0xac, 0xfd, 0x51, 0xc0, 0x96, 0xe3, 0x05,
|
||||
0x5b, 0xb0, 0xb1, 0x0a, 0xf9, 0xeb, 0xb9, 0x42, 0x0a, 0x28, 0x4b, 0x97, 0xf4, 0x5e, 0x97, 0xd2,
|
||||
0x79, 0x1a, 0x07, 0xe2, 0x82, 0xc6, 0x8b, 0x92, 0x15, 0x51, 0x5f, 0xbf, 0x10, 0xb0, 0x68, 0xec,
|
||||
0x93, 0x95, 0x2e, 0x1b, 0x5e, 0x41, 0xfb, 0x94, 0x46, 0xe4, 0x9c, 0x24, 0x9c, 0xb2, 0x18, 0xbd,
|
||||
0x84, 0xc6, 0xb5, 0x36, 0x2d, 0xc3, 0x36, 0x9c, 0xf6, 0xd1, 0xde, 0x28, 0x2f, 0x1a, 0x9d, 0x93,
|
||||
0x40, 0xb0, 0xc4, 0x35, 0xef, 0x37, 0x83, 0x0a, 0xce, 0xd3, 0xd0, 0x21, 0xd4, 0x43, 0x72, 0x4d,
|
||||
0x03, 0x62, 0xed, 0xd8, 0x86, 0xd3, 0xc1, 0x19, 0x42, 0x16, 0x34, 0x68, 0x7c, 0xed, 0x45, 0x34,
|
||||
0xb4, 0xaa, 0xb6, 0xe1, 0x34, 0x71, 0x0e, 0x87, 0xa7, 0xd0, 0xce, 0xda, 0xbd, 0xa7, 0x5c, 0xa0,
|
||||
0x57, 0xd0, 0xcc, 0xde, 0xe2, 0x96, 0x61, 0x57, 0x9d, 0xf6, 0xd1, 0x93, 0x51, 0xe8, 0x8f, 0x4a,
|
||||
0xac, 0xb2, 0x96, 0x45, 0xda, 0x1b, 0xf3, 0xcb, 0xdd, 0xa0, 0x32, 0x7c, 0x30, 0x61, 0x5f, 0x66,
|
||||
0x4d, 0xe2, 0x39, 0x3b, 0x4b, 0xd6, 0x71, 0xe0, 0x09, 0x12, 0x22, 0x04, 0x66, 0xec, 0x2d, 0x89,
|
||||
0xa2, 0xdf, 0xc2, 0xca, 0x46, 0xcf, 0xc1, 0x14, 0xe9, 0x4a, 0x33, 0xdc, 0x3d, 0x3a, 0x7c, 0x1c,
|
||||
0xa9, 0x28, 0x4f, 0x57, 0x04, 0xab, 0x1c, 0x59, 0xcf, 0xe9, 0x2d, 0x51, 0xa4, 0xab, 0x58, 0xd9,
|
||||
0xc8, 0x86, 0xf6, 0x8a, 0x24, 0x4b, 0xca, 0x35, 0x4b, 0xd3, 0x36, 0x9c, 0x2e, 0x2e, 0xbb, 0xd0,
|
||||
0x53, 0x80, 0x25, 0x0b, 0xe9, 0x9c, 0x92, 0x70, 0xc6, 0xad, 0x9a, 0xaa, 0x6d, 0xe5, 0x9e, 0xa9,
|
||||
0x5c, 0x46, 0x48, 0x22, 0x22, 0x48, 0x68, 0xd5, 0xf5, 0x32, 0x32, 0x88, 0x9c, 0xc7, 0x35, 0x35,
|
||||
0x64, 0xc4, 0xdd, 0xdd, 0x6e, 0x06, 0x80, 0xbd, 0x9b, 0x89, 0xf6, 0x16, 0x6b, 0x43, 0xcf, 0x60,
|
||||
0x37, 0x66, 0xb3, 0x32, 0x8f, 0xa6, 0x7a, 0xaa, 0x1b, 0xb3, 0x4f, 0x25, 0x26, 0xa5, 0x0b, 0xb6,
|
||||
0xfe, 0xed, 0x82, 0x3d, 0x68, 0x72, 0x72, 0xb5, 0x26, 0x71, 0x40, 0x2c, 0x50, 0xcc, 0x0b, 0x8c,
|
||||
0x06, 0xd0, 0x2e, 0xe6, 0x8a, 0xb9, 0xd5, 0xb6, 0x0d, 0xa7, 0x86, 0x8b, 0x51, 0x3f, 0x70, 0xf4,
|
||||
0xb9, 0x94, 0xe0, 0xa7, 0x56, 0xc7, 0x36, 0x1c, 0xd3, 0x7d, 0x2b, 0x1b, 0x7c, 0xdf, 0x0c, 0x8e,
|
||||
0xff, 0x43, 0x93, 0xa3, 0xe9, 0x05, 0x4b, 0xc4, 0xe4, 0xe4, 0xf1, 0x75, 0x37, 0x45, 0x63, 0x00,
|
||||
0x3f, 0x62, 0xc1, 0xe5, 0x4c, 0x9d, 0xa4, 0x2b, 0xbb, 0xbb, 0x7b, 0xdb, 0xcd, 0xa0, 0x83, 0xbd,
|
||||
0x1b, 0x57, 0x06, 0xa6, 0xf4, 0x96, 0xe0, 0x96, 0x9f, 0x9b, 0x72, 0x49, 0x3c, 0x5d, 0x46, 0x34,
|
||||
0xbe, 0x9c, 0x09, 0x2f, 0x59, 0x10, 0x61, 0xed, 0x2b, 0x1d, 0x74, 0x33, 0xef, 0x99, 0x72, 0xca,
|
||||
0x83, 0x46, 0x2c, 0xf0, 0xa2, 0xd9, 0x3c, 0xf2, 0x16, 0xdc, 0xfa, 0xd5, 0x50, 0x17, 0x05, 0xe5,
|
||||
0x3b, 0x95, 0xae, 0x4c, 0x62, 0x5f, 0x0d, 0xa8, 0xbf, 0x63, 0xeb, 0x58, 0x70, 0x74, 0x00, 0xb5,
|
||||
0x39, 0x8d, 0x08, 0x57, 0xc2, 0xaa, 0x61, 0x0d, 0xe4, 0x43, 0x21, 0x4d, 0xd4, 0x5a, 0x29, 0xe1,
|
||||
0x4a, 0x60, 0x35, 0x5c, 0x76, 0xa9, 0xed, 0xea, 0xde, 0x5c, 0x69, 0xaa, 0x86, 0x0b, 0x5c, 0x96,
|
||||
0x85, 0xa9, 0x42, 0x85, 0x2c, 0x0e, 0xa0, 0xe6, 0xa7, 0x82, 0xe4, 0x52, 0xd2, 0xe0, 0x8f, 0x4b,
|
||||
0xd5, 0xff, 0xba, 0x54, 0x0f, 0x9a, 0xfa, 0xe7, 0x4d, 0x4e, 0xd4, 0xcc, 0x1d, 0x5c, 0xe0, 0xe1,
|
||||
0x47, 0x68, 0xe9, 0x29, 0xa6, 0x44, 0x20, 0x07, 0xea, 0x81, 0x02, 0xd9, 0x6f, 0x03, 0xf9, 0xdb,
|
||||
0x74, 0x38, 0x53, 0x46, 0x16, 0x97, 0xf4, 0x82, 0x84, 0xc8, 0x5f, 0xa5, 0x06, 0xab, 0xe2, 0x1c,
|
||||
0xba, 0x07, 0xf7, 0x3f, 0xfa, 0x95, 0xfb, 0x6d, 0xdf, 0xf8, 0xb6, 0xed, 0x1b, 0x0f, 0xdb, 0x7e,
|
||||
0xe5, 0xee, 0x67, 0xdf, 0xf0, 0xeb, 0xea, 0x96, 0xc7, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9a,
|
||||
0x4b, 0x16, 0x44, 0xcd, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
@ -31,14 +31,16 @@ message FileInfoTruncated {
|
||||
int32 modified_ns = 11;
|
||||
uint64 modified_by = 12 [(gogoproto.customtype) = "github.com/syncthing/syncthing/lib/protocol.ShortID", (gogoproto.nullable) = false];
|
||||
bool deleted = 6;
|
||||
bool invalid = 7;
|
||||
bool invalid = 7 [(gogoproto.customname) = "RawInvalid"];
|
||||
bool no_permissions = 8;
|
||||
protocol.Vector version = 9 [(gogoproto.nullable) = false];
|
||||
int64 sequence = 10;
|
||||
int32 block_size = 13 [(gogoproto.customname) = "RawBlockSize"];
|
||||
|
||||
// repeated BlockInfo Blocks = 16
|
||||
string symlink_target = 17;
|
||||
|
||||
// see bep.proto
|
||||
uint32 local_flags = 1000;
|
||||
}
|
||||
|
||||
// For each folder and device we keep one of these to track the current
|
||||
|
@ -60,7 +60,7 @@ func (f *sendOnlyFolder) pull() bool {
|
||||
|
||||
if ignores.ShouldIgnore(intf.FileName()) {
|
||||
file := intf.(protocol.FileInfo)
|
||||
file.Invalidate(f.shortID)
|
||||
file.SetIgnored(f.shortID)
|
||||
batch = append(batch, file)
|
||||
batchSizeBytes += file.ProtoSize()
|
||||
l.Debugln(f, "Handling ignored file", file)
|
||||
|
@ -269,7 +269,7 @@ func (f *sendReceiveFolder) pullerIteration(ignores *ignore.Matcher, ignoresChan
|
||||
|
||||
switch {
|
||||
case ignores.ShouldIgnore(file.Name):
|
||||
file.Invalidate(f.shortID)
|
||||
file.SetIgnored(f.shortID)
|
||||
l.Debugln(f, "Handling ignored file", file)
|
||||
dbUpdateChan <- dbUpdateJob{file, dbUpdateInvalidate}
|
||||
changed++
|
||||
@ -297,7 +297,7 @@ func (f *sendReceiveFolder) pullerIteration(ignores *ignore.Matcher, ignoresChan
|
||||
l.Debugln(f, "Needed file is unavailable", file)
|
||||
|
||||
case runtime.GOOS == "windows" && file.IsSymlink():
|
||||
file.Invalidate(f.shortID)
|
||||
file.SetUnsupported(f.shortID)
|
||||
l.Debugln(f, "Invalidating symlink (unsupported)", file.Name)
|
||||
dbUpdateChan <- dbUpdateJob{file, dbUpdateInvalidate}
|
||||
changed++
|
||||
|
@ -862,6 +862,11 @@ func (m *Model) handleIndex(deviceID protocol.DeviceID, folder string, fs []prot
|
||||
if !update {
|
||||
files.Drop(deviceID)
|
||||
}
|
||||
for i := range fs {
|
||||
// The local flags should never be transmitted over the wire. Make
|
||||
// sure they look like they weren't.
|
||||
fs[i].LocalFlags = 0
|
||||
}
|
||||
files.Update(deviceID, fs)
|
||||
|
||||
events.Default.Log(events.RemoteIndexUpdated, map[string]interface{}{
|
||||
@ -1389,7 +1394,7 @@ func (m *Model) recheckFile(deviceID protocol.DeviceID, folderFs fs.Filesystem,
|
||||
// The hashes provided part of the request match what we expect to find according
|
||||
// to what we have in the database, yet the content we've read off the filesystem doesn't
|
||||
// Something is fishy, invalidate the file and rescan it.
|
||||
cf.Invalidate(m.shortID)
|
||||
cf.SetMustRescan(m.shortID)
|
||||
|
||||
// Update the index and tell others
|
||||
// The file will temporarily become invalid, which is ok as the content is messed up.
|
||||
@ -1736,6 +1741,10 @@ func sendIndexTo(prevSequence int64, conn protocol.Connection, folder string, fs
|
||||
|
||||
f = fi.(protocol.FileInfo)
|
||||
|
||||
// Mark the file as invalid if any of the local bad stuff flags are set.
|
||||
f.RawInvalid = f.IsInvalid()
|
||||
f.LocalFlags = 0 // never sent externally
|
||||
|
||||
if dropSymlinks && f.IsSymlink() {
|
||||
// Do not send index entries with symlinks to clients that can't
|
||||
// handle it. Fixes issue #3802. Once both sides are upgraded, a
|
||||
@ -2064,23 +2073,23 @@ func (m *Model) internalScanFolderSubdirs(ctx context.Context, folder string, su
|
||||
}
|
||||
|
||||
switch {
|
||||
case !f.IsInvalid() && ignores.Match(f.Name).IsIgnored():
|
||||
// File was valid at last pass but has been ignored. Set invalid bit.
|
||||
l.Debugln("setting invalid bit on ignored", f)
|
||||
nf := f.ConvertToInvalidFileInfo(m.id.Short())
|
||||
case !f.IsIgnored() && ignores.Match(f.Name).IsIgnored():
|
||||
// File was not ignored at last pass but has been ignored.
|
||||
l.Debugln("marking file as ignored", f)
|
||||
nf := f.ConvertToIgnoredFileInfo(m.id.Short())
|
||||
batch = append(batch, nf)
|
||||
batchSizeBytes += nf.ProtoSize()
|
||||
changes++
|
||||
|
||||
case f.IsInvalid() && !ignores.Match(f.Name).IsIgnored():
|
||||
case f.IsIgnored() && !ignores.Match(f.Name).IsIgnored():
|
||||
// Successfully scanned items are already un-ignored during
|
||||
// the scan, so check whether it is deleted.
|
||||
fallthrough
|
||||
case !f.IsInvalid() && !f.IsDeleted():
|
||||
// The file is valid and not deleted. Lets check if it's
|
||||
// still here.
|
||||
// Simply stating it wont do as there are tons of corner
|
||||
// cases (e.g. parent dir->simlink, missing permissions)
|
||||
case !f.IsIgnored() && !f.IsDeleted():
|
||||
// The file is not ignored and not deleted. Lets check if
|
||||
// it's still here. Simply stat:ing it wont do as there are
|
||||
// tons of corner cases (e.g. parent dir->symlink, missing
|
||||
// permissions)
|
||||
if !osutil.IsDeleted(mtimefs, f.Name) {
|
||||
return true
|
||||
}
|
||||
@ -2099,7 +2108,7 @@ func (m *Model) internalScanFolderSubdirs(ctx context.Context, folder string, su
|
||||
// counter makes sure we are in conflict with any
|
||||
// other existing versions, which will be resolved
|
||||
// by the normal pulling mechanisms.
|
||||
if f.IsInvalid() {
|
||||
if f.IsIgnored() {
|
||||
nf.Version = nf.Version.DropOthers(m.shortID)
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
|
||||
fc.indexFn = func(folder string, fs []protocol.FileInfo) {
|
||||
for _, f := range fs {
|
||||
if f.Name == name {
|
||||
if f.Invalid {
|
||||
if f.IsInvalid() {
|
||||
goodIdx <- struct{}{}
|
||||
} else {
|
||||
t.Fatal("Received index with non-invalid temporary file")
|
||||
@ -348,7 +348,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
if _, ok := expected[f.Name]; !ok {
|
||||
t.Errorf("Unexpected file %v was added to index", f.Name)
|
||||
}
|
||||
if !f.Invalid {
|
||||
if !f.IsInvalid() {
|
||||
t.Errorf("File %v wasn't marked as invalid", f.Name)
|
||||
}
|
||||
delete(expected, f.Name)
|
||||
@ -382,7 +382,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
if _, ok := expected[f.Name]; !ok {
|
||||
t.Fatalf("Unexpected file %v was updated in index", f.Name)
|
||||
}
|
||||
if f.Invalid {
|
||||
if f.IsInvalid() {
|
||||
t.Errorf("File %v is still marked as invalid", f.Name)
|
||||
}
|
||||
// The unignored files should only have a local version,
|
||||
@ -446,10 +446,10 @@ func TestIssue4841(t *testing.T) {
|
||||
|
||||
// Setup file from remote that was ignored locally
|
||||
m.updateLocals(defaultFolderConfig.ID, []protocol.FileInfo{{
|
||||
Name: "foo",
|
||||
Type: protocol.FileInfoTypeFile,
|
||||
Invalid: true,
|
||||
Version: protocol.Vector{}.Update(device2.Short()),
|
||||
Name: "foo",
|
||||
Type: protocol.FileInfoTypeFile,
|
||||
LocalFlags: protocol.FlagLocalIgnored,
|
||||
Version: protocol.Vector{}.Update(device2.Short()),
|
||||
}})
|
||||
<-received
|
||||
|
||||
|
@ -302,13 +302,18 @@ type FileInfo struct {
|
||||
ModifiedNs int32 `protobuf:"varint,11,opt,name=modified_ns,json=modifiedNs,proto3" json:"modified_ns,omitempty"`
|
||||
ModifiedBy ShortID `protobuf:"varint,12,opt,name=modified_by,json=modifiedBy,proto3,customtype=ShortID" json:"modified_by"`
|
||||
Deleted bool `protobuf:"varint,6,opt,name=deleted,proto3" json:"deleted,omitempty"`
|
||||
Invalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
RawInvalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
NoPermissions bool `protobuf:"varint,8,opt,name=no_permissions,json=noPermissions,proto3" json:"no_permissions,omitempty"`
|
||||
Version Vector `protobuf:"bytes,9,opt,name=version" json:"version"`
|
||||
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
RawBlockSize int32 `protobuf:"varint,13,opt,name=block_size,json=blockSize,proto3" json:"block_size,omitempty"`
|
||||
Blocks []BlockInfo `protobuf:"bytes,16,rep,name=Blocks" json:"Blocks"`
|
||||
SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
|
||||
// The local_flags fields stores flags that are relevant to the local
|
||||
// host only. It is not part of the protocol, doesn't get sent or
|
||||
// received (we make sure to zero it), nonetheless we need it on our
|
||||
// struct and to be able to serialize it to/from the database.
|
||||
LocalFlags uint32 `protobuf:"varint,1000,opt,name=local_flags,json=localFlags,proto3" json:"local_flags,omitempty"`
|
||||
}
|
||||
|
||||
func (m *FileInfo) Reset() { *m = FileInfo{} }
|
||||
@ -835,10 +840,10 @@ func (m *FileInfo) MarshalTo(dAtA []byte) (int, error) {
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
dAtA[i] = 0x38
|
||||
i++
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
@ -905,6 +910,13 @@ func (m *FileInfo) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintBep(dAtA, i, uint64(len(m.SymlinkTarget)))
|
||||
i += copy(dAtA[i:], m.SymlinkTarget)
|
||||
}
|
||||
if m.LocalFlags != 0 {
|
||||
dAtA[i] = 0xc0
|
||||
i++
|
||||
dAtA[i] = 0x3e
|
||||
i++
|
||||
i = encodeVarintBep(dAtA, i, uint64(m.LocalFlags))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@ -1422,7 +1434,7 @@ func (m *FileInfo) ProtoSize() (n int) {
|
||||
if m.Deleted {
|
||||
n += 2
|
||||
}
|
||||
if m.Invalid {
|
||||
if m.RawInvalid {
|
||||
n += 2
|
||||
}
|
||||
if m.NoPermissions {
|
||||
@ -1452,6 +1464,9 @@ func (m *FileInfo) ProtoSize() (n int) {
|
||||
if l > 0 {
|
||||
n += 2 + l + sovBep(uint64(l))
|
||||
}
|
||||
if m.LocalFlags != 0 {
|
||||
n += 2 + sovBep(uint64(m.LocalFlags))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -2797,7 +2812,7 @@ func (m *FileInfo) Unmarshal(dAtA []byte) error {
|
||||
m.Deleted = bool(v != 0)
|
||||
case 7:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Invalid", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field RawInvalid", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@ -2814,7 +2829,7 @@ func (m *FileInfo) Unmarshal(dAtA []byte) error {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Invalid = bool(v != 0)
|
||||
m.RawInvalid = bool(v != 0)
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NoPermissions", wireType)
|
||||
@ -3001,6 +3016,25 @@ func (m *FileInfo) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
m.SymlinkTarget = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 1000:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field LocalFlags", wireType)
|
||||
}
|
||||
m.LocalFlags = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBep
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.LocalFlags |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipBep(dAtA[iNdEx:])
|
||||
@ -4220,116 +4254,118 @@ var (
|
||||
func init() { proto.RegisterFile("bep.proto", fileDescriptorBep) }
|
||||
|
||||
var fileDescriptorBep = []byte{
|
||||
// 1762 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x8f, 0xdb, 0xc6,
|
||||
0x15, 0x5f, 0x4a, 0x94, 0x44, 0x3d, 0x69, 0x37, 0xdc, 0xb1, 0xbd, 0x65, 0x99, 0x8d, 0x44, 0x2b,
|
||||
0x76, 0xbc, 0x59, 0x24, 0x6b, 0x37, 0x49, 0x5b, 0xb4, 0x68, 0x0b, 0xe8, 0x0f, 0x77, 0x2d, 0x54,
|
||||
0xa6, 0xd4, 0x91, 0xd6, 0xa9, 0x73, 0x28, 0x41, 0x89, 0x23, 0x2d, 0x61, 0x8a, 0xa3, 0x92, 0xd4,
|
||||
0xda, 0xca, 0x47, 0xd0, 0x27, 0xe8, 0x45, 0x40, 0x80, 0x9e, 0x0a, 0xf4, 0x83, 0xf8, 0x98, 0xf6,
|
||||
0xd0, 0x43, 0x0f, 0x46, 0xb3, 0xbd, 0xf4, 0xd8, 0x4f, 0x50, 0x14, 0x9c, 0x21, 0x25, 0x6a, 0xd7,
|
||||
0x0e, 0x7c, 0xc8, 0x89, 0x33, 0xef, 0xfd, 0xe6, 0x0d, 0xdf, 0x6f, 0x7e, 0xef, 0xcd, 0x40, 0x71,
|
||||
0x48, 0x66, 0x27, 0x33, 0x9f, 0x86, 0x14, 0x49, 0xec, 0x33, 0xa2, 0xae, 0xfa, 0xe9, 0xc4, 0x09,
|
||||
0x2f, 0xe6, 0xc3, 0x93, 0x11, 0x9d, 0x3e, 0x9c, 0xd0, 0x09, 0x7d, 0xc8, 0x3c, 0xc3, 0xf9, 0x98,
|
||||
0xcd, 0xd8, 0x84, 0x8d, 0xf8, 0xc2, 0xda, 0x0c, 0x72, 0x8f, 0x89, 0xeb, 0x52, 0x54, 0x85, 0x92,
|
||||
0x4d, 0x2e, 0x9d, 0x11, 0x31, 0x3d, 0x6b, 0x4a, 0x14, 0x41, 0x13, 0x8e, 0x8a, 0x18, 0xb8, 0xc9,
|
||||
0xb0, 0xa6, 0x24, 0x02, 0x8c, 0x5c, 0x87, 0x78, 0x21, 0x07, 0x64, 0x38, 0x80, 0x9b, 0x18, 0xe0,
|
||||
0x3e, 0xec, 0xc5, 0x80, 0x4b, 0xe2, 0x07, 0x0e, 0xf5, 0x94, 0x2c, 0xc3, 0xec, 0x72, 0xeb, 0x53,
|
||||
0x6e, 0xac, 0x05, 0x90, 0x7f, 0x4c, 0x2c, 0x9b, 0xf8, 0xe8, 0x63, 0x10, 0xc3, 0xc5, 0x8c, 0xef,
|
||||
0xb5, 0xf7, 0xd9, 0x9d, 0x93, 0x24, 0x87, 0x93, 0x27, 0x24, 0x08, 0xac, 0x09, 0x19, 0x2c, 0x66,
|
||||
0x04, 0x33, 0x08, 0xfa, 0x0d, 0x94, 0x46, 0x74, 0x3a, 0xf3, 0x49, 0xc0, 0x02, 0x67, 0xd8, 0x8a,
|
||||
0xc3, 0x1b, 0x2b, 0x9a, 0x1b, 0x0c, 0x4e, 0x2f, 0xa8, 0xd5, 0x61, 0xb7, 0xe9, 0xce, 0x83, 0x90,
|
||||
0xf8, 0x4d, 0xea, 0x8d, 0x9d, 0x09, 0x7a, 0x04, 0x85, 0x31, 0x75, 0x6d, 0xe2, 0x07, 0x8a, 0xa0,
|
||||
0x65, 0x8f, 0x4a, 0x9f, 0xc9, 0x9b, 0x60, 0xa7, 0xcc, 0xd1, 0x10, 0x5f, 0xbd, 0xae, 0xee, 0xe0,
|
||||
0x04, 0x56, 0xfb, 0x73, 0x06, 0xf2, 0xdc, 0x83, 0x0e, 0x20, 0xe3, 0xd8, 0x9c, 0xa2, 0x46, 0xfe,
|
||||
0xea, 0x75, 0x35, 0xd3, 0x6e, 0xe1, 0x8c, 0x63, 0xa3, 0xdb, 0x90, 0x73, 0xad, 0x21, 0x71, 0x63,
|
||||
0x72, 0xf8, 0x04, 0xbd, 0x0f, 0x45, 0x9f, 0x58, 0xb6, 0x49, 0x3d, 0x77, 0xc1, 0x28, 0x91, 0xb0,
|
||||
0x14, 0x19, 0xba, 0x9e, 0xbb, 0x40, 0x9f, 0x02, 0x72, 0x26, 0x1e, 0xf5, 0x89, 0x39, 0x23, 0xfe,
|
||||
0xd4, 0x61, 0x7f, 0x1b, 0x28, 0x22, 0x43, 0xed, 0x73, 0x4f, 0x6f, 0xe3, 0x40, 0x1f, 0xc2, 0x6e,
|
||||
0x0c, 0xb7, 0x89, 0x4b, 0x42, 0xa2, 0xe4, 0x18, 0xb2, 0xcc, 0x8d, 0x2d, 0x66, 0x43, 0x8f, 0xe0,
|
||||
0xb6, 0xed, 0x04, 0xd6, 0xd0, 0x25, 0x66, 0x48, 0xa6, 0x33, 0xd3, 0xf1, 0x6c, 0xf2, 0x92, 0x04,
|
||||
0x4a, 0x9e, 0x61, 0x51, 0xec, 0x1b, 0x90, 0xe9, 0xac, 0xcd, 0x3d, 0xe8, 0x00, 0xf2, 0x33, 0x6b,
|
||||
0x1e, 0x10, 0x5b, 0x29, 0x30, 0x4c, 0x3c, 0x8b, 0x58, 0xe2, 0x0a, 0x08, 0x14, 0xf9, 0x3a, 0x4b,
|
||||
0x2d, 0xe6, 0x48, 0x58, 0x8a, 0x61, 0xb5, 0xff, 0x66, 0x20, 0xcf, 0x3d, 0xe8, 0xa3, 0x35, 0x4b,
|
||||
0xe5, 0xc6, 0x41, 0x84, 0xfa, 0xe7, 0xeb, 0xaa, 0xc4, 0x7d, 0xed, 0x56, 0x8a, 0x35, 0x04, 0x62,
|
||||
0x4a, 0x51, 0x6c, 0x8c, 0x0e, 0xa1, 0x68, 0xd9, 0x76, 0x74, 0x7a, 0x24, 0x50, 0xb2, 0x5a, 0xf6,
|
||||
0xa8, 0x88, 0x37, 0x06, 0xf4, 0xf3, 0x6d, 0x35, 0x88, 0xd7, 0xf5, 0xf3, 0x36, 0x19, 0x44, 0x47,
|
||||
0x31, 0x22, 0x7e, 0xac, 0xe0, 0x1c, 0xdb, 0x4f, 0x8a, 0x0c, 0x4c, 0xbf, 0x77, 0xa1, 0x3c, 0xb5,
|
||||
0x5e, 0x9a, 0x01, 0xf9, 0xe3, 0x9c, 0x78, 0x23, 0xc2, 0xe8, 0xca, 0xe2, 0xd2, 0xd4, 0x7a, 0xd9,
|
||||
0x8f, 0x4d, 0xa8, 0x02, 0xe0, 0x78, 0xa1, 0x4f, 0xed, 0xf9, 0x88, 0xf8, 0x31, 0x57, 0x29, 0x0b,
|
||||
0xfa, 0x29, 0x48, 0x8c, 0x6c, 0xd3, 0xb1, 0x15, 0x49, 0x13, 0x8e, 0xc4, 0x86, 0x1a, 0x27, 0x5e,
|
||||
0x60, 0x54, 0xb3, 0xbc, 0x93, 0x21, 0x2e, 0x30, 0x6c, 0xdb, 0x46, 0xbf, 0x02, 0x35, 0x78, 0xee,
|
||||
0x44, 0x07, 0xc5, 0x23, 0x85, 0x0e, 0xf5, 0x4c, 0x9f, 0x4c, 0xe9, 0xa5, 0xe5, 0x06, 0x4a, 0x91,
|
||||
0x6d, 0xa3, 0x44, 0x88, 0x76, 0x0a, 0x80, 0x63, 0x7f, 0xad, 0x0b, 0x39, 0x16, 0x31, 0x3a, 0x45,
|
||||
0x2e, 0xd6, 0xb8, 0x7a, 0xe3, 0x19, 0x3a, 0x81, 0xdc, 0xd8, 0x71, 0x49, 0xa0, 0x64, 0xd8, 0x19,
|
||||
0xa2, 0x94, 0xd2, 0x1d, 0x97, 0xb4, 0xbd, 0x31, 0x8d, 0x4f, 0x91, 0xc3, 0x6a, 0xe7, 0x50, 0x62,
|
||||
0x01, 0xcf, 0x67, 0xb6, 0x15, 0x92, 0x1f, 0x2c, 0xec, 0x5f, 0x45, 0x90, 0x12, 0xcf, 0xfa, 0xd0,
|
||||
0x85, 0xd4, 0xa1, 0x1f, 0xc7, 0xfd, 0x80, 0x57, 0xf7, 0xc1, 0xcd, 0x78, 0xa9, 0x86, 0x80, 0x40,
|
||||
0x0c, 0x9c, 0xaf, 0x09, 0xab, 0xa7, 0x2c, 0x66, 0x63, 0xa4, 0x41, 0xe9, 0x7a, 0x11, 0xed, 0xe2,
|
||||
0xb4, 0x09, 0x7d, 0x00, 0x30, 0xa5, 0xb6, 0x33, 0x76, 0x88, 0x6d, 0x06, 0x4c, 0x00, 0x59, 0x5c,
|
||||
0x4c, 0x2c, 0x7d, 0xa4, 0x44, 0x72, 0x8f, 0x4a, 0xc8, 0x8e, 0x6b, 0x25, 0x99, 0x46, 0x1e, 0xc7,
|
||||
0xbb, 0xb4, 0x5c, 0x27, 0xa9, 0x90, 0x64, 0x1a, 0x75, 0x3d, 0x8f, 0x6e, 0x15, 0xaf, 0xc4, 0x00,
|
||||
0xbb, 0x1e, 0x4d, 0x17, 0xee, 0x23, 0x28, 0x24, 0x5d, 0x31, 0x3a, 0xcf, 0xad, 0x4a, 0x7a, 0x4a,
|
||||
0x46, 0x21, 0x5d, 0xf7, 0x9b, 0x18, 0x86, 0x54, 0x90, 0xd6, 0x52, 0x04, 0xf6, 0xa7, 0xeb, 0x79,
|
||||
0xd4, 0x8b, 0xd7, 0x79, 0x78, 0x81, 0x52, 0xd2, 0x84, 0xa3, 0x1c, 0x5e, 0xa7, 0x66, 0x44, 0xdb,
|
||||
0x6d, 0x00, 0xc3, 0x85, 0x52, 0x66, 0x5a, 0x7c, 0x2f, 0xd1, 0x62, 0xff, 0x82, 0xfa, 0x61, 0xbb,
|
||||
0xb5, 0x59, 0xd1, 0x58, 0xa0, 0x87, 0x00, 0x43, 0x97, 0x8e, 0x9e, 0x9b, 0x8c, 0xd6, 0xdd, 0x28,
|
||||
0x62, 0x43, 0xbe, 0x7a, 0x5d, 0x2d, 0x63, 0xeb, 0x45, 0x23, 0x72, 0xf4, 0x9d, 0xaf, 0x09, 0x2e,
|
||||
0x0e, 0x93, 0x21, 0xfa, 0x09, 0xe4, 0x99, 0x3d, 0x69, 0x0d, 0xb7, 0x36, 0x09, 0x31, 0x7b, 0x4a,
|
||||
0x00, 0x31, 0x30, 0xe2, 0x2a, 0x58, 0x4c, 0x5d, 0xc7, 0x7b, 0x6e, 0x86, 0x96, 0x3f, 0x21, 0xa1,
|
||||
0xb2, 0xcf, 0x6f, 0x88, 0xd8, 0x3a, 0x60, 0xc6, 0x5f, 0x8a, 0x7f, 0xfa, 0xa6, 0xba, 0x53, 0xf3,
|
||||
0xa0, 0xb8, 0x8e, 0x13, 0x69, 0x90, 0x8e, 0xc7, 0x01, 0x09, 0x99, 0x60, 0xb2, 0x38, 0x9e, 0xad,
|
||||
0x65, 0x90, 0x61, 0x0c, 0x70, 0x19, 0x20, 0x10, 0x2f, 0xac, 0xe0, 0x82, 0x49, 0xa3, 0x8c, 0xd9,
|
||||
0x38, 0x2a, 0xfc, 0x17, 0xc4, 0x7a, 0x6e, 0x32, 0x07, 0x17, 0x86, 0x14, 0x19, 0x1e, 0x5b, 0xc1,
|
||||
0x45, 0xbc, 0xdf, 0xaf, 0x21, 0xcf, 0x0f, 0x02, 0x7d, 0x0e, 0xd2, 0x88, 0xce, 0xbd, 0x70, 0x73,
|
||||
0x39, 0xec, 0xa7, 0x7b, 0x0b, 0xf3, 0xc4, 0x99, 0xad, 0x81, 0xb5, 0x53, 0x28, 0xc4, 0x2e, 0x74,
|
||||
0x7f, 0xdd, 0xf8, 0xc4, 0xc6, 0x9d, 0x6b, 0x9c, 0x6f, 0xdf, 0x16, 0x97, 0x96, 0x3b, 0xe7, 0x3f,
|
||||
0x2f, 0x62, 0x3e, 0xa9, 0xfd, 0x4d, 0x80, 0x02, 0x8e, 0xce, 0x39, 0x08, 0x53, 0xf7, 0x4c, 0x6e,
|
||||
0xeb, 0x9e, 0xd9, 0x54, 0x64, 0x66, 0xab, 0x22, 0x93, 0xa2, 0xca, 0xa6, 0x8a, 0x6a, 0xc3, 0x9c,
|
||||
0xf8, 0x46, 0xe6, 0x72, 0x6f, 0x60, 0x2e, 0x9f, 0x62, 0xee, 0x3e, 0xec, 0x8d, 0x7d, 0x3a, 0x65,
|
||||
0x37, 0x09, 0xf5, 0x2d, 0x7f, 0x11, 0x17, 0xc0, 0x6e, 0x64, 0x1d, 0x24, 0xc6, 0x6d, 0x82, 0xa5,
|
||||
0x6d, 0x82, 0x6b, 0x26, 0x48, 0x98, 0x04, 0x33, 0xea, 0x05, 0xe4, 0xad, 0x39, 0x21, 0x10, 0x6d,
|
||||
0x2b, 0xb4, 0x58, 0x46, 0x65, 0xcc, 0xc6, 0xe8, 0x01, 0x88, 0x23, 0x6a, 0xf3, 0x7c, 0xf6, 0xd2,
|
||||
0x02, 0xd3, 0x7d, 0x9f, 0xfa, 0x4d, 0x6a, 0x13, 0xcc, 0x00, 0xb5, 0x19, 0xc8, 0x2d, 0xfa, 0xc2,
|
||||
0x73, 0xa9, 0x65, 0xf7, 0x7c, 0x3a, 0x89, 0xda, 0xfd, 0x5b, 0xdb, 0x56, 0x0b, 0x0a, 0x73, 0xd6,
|
||||
0xd8, 0x92, 0xc6, 0x75, 0x6f, 0xbb, 0xd1, 0x5c, 0x0f, 0xc4, 0xbb, 0x60, 0x52, 0x9d, 0xf1, 0xd2,
|
||||
0xda, 0x3f, 0x04, 0x50, 0xdf, 0x8e, 0x46, 0x6d, 0x28, 0x71, 0xa4, 0x99, 0x7a, 0xe1, 0x1c, 0xbd,
|
||||
0xcb, 0x46, 0xac, 0xc7, 0xc1, 0x7c, 0x3d, 0x7e, 0xe3, 0xf5, 0x98, 0xea, 0x26, 0xd9, 0x77, 0xeb,
|
||||
0x26, 0x0f, 0x60, 0x97, 0x97, 0x77, 0xf2, 0x18, 0x10, 0xb5, 0xec, 0x51, 0xae, 0x91, 0x91, 0x77,
|
||||
0x70, 0x79, 0xc8, 0xcb, 0x8c, 0xd9, 0x6b, 0x79, 0x10, 0x7b, 0x8e, 0x37, 0xa9, 0x55, 0x21, 0xd7,
|
||||
0x74, 0x29, 0x3b, 0xb0, 0xbc, 0x4f, 0xac, 0x80, 0x7a, 0x09, 0x8f, 0x7c, 0x76, 0xfc, 0xf7, 0x0c,
|
||||
0x94, 0x52, 0x0f, 0x35, 0xf4, 0x08, 0xf6, 0x9a, 0x9d, 0xf3, 0xfe, 0x40, 0xc7, 0x66, 0xb3, 0x6b,
|
||||
0x9c, 0xb6, 0xcf, 0xe4, 0x1d, 0xf5, 0x70, 0xb9, 0xd2, 0x94, 0xe9, 0x06, 0xb4, 0xfd, 0x06, 0xab,
|
||||
0x42, 0xae, 0x6d, 0xb4, 0xf4, 0xdf, 0xcb, 0x82, 0x7a, 0x7b, 0xb9, 0xd2, 0xe4, 0x14, 0x90, 0x5f,
|
||||
0x68, 0x9f, 0x40, 0x99, 0x01, 0xcc, 0xf3, 0x5e, 0xab, 0x3e, 0xd0, 0xe5, 0x8c, 0xaa, 0x2e, 0x57,
|
||||
0xda, 0xc1, 0x75, 0x5c, 0xcc, 0xf9, 0x87, 0x50, 0xc0, 0xfa, 0xef, 0xce, 0xf5, 0xfe, 0x40, 0xce,
|
||||
0xaa, 0x07, 0xcb, 0x95, 0x86, 0x52, 0xc0, 0xa4, 0xa4, 0xee, 0x83, 0x84, 0xf5, 0x7e, 0xaf, 0x6b,
|
||||
0xf4, 0x75, 0x59, 0x54, 0x7f, 0xb4, 0x5c, 0x69, 0xb7, 0xb6, 0x50, 0xb1, 0x4a, 0x7f, 0x06, 0xfb,
|
||||
0xad, 0xee, 0x97, 0x46, 0xa7, 0x5b, 0x6f, 0x99, 0x3d, 0xdc, 0x3d, 0xc3, 0x7a, 0xbf, 0x2f, 0xe7,
|
||||
0xd4, 0xea, 0x72, 0xa5, 0xbd, 0x9f, 0xc2, 0xdf, 0x10, 0xdd, 0x07, 0x20, 0xf6, 0xda, 0xc6, 0x99,
|
||||
0x9c, 0x57, 0x6f, 0x2d, 0x57, 0xda, 0x7b, 0x29, 0x68, 0x44, 0x6a, 0x94, 0x71, 0xb3, 0xd3, 0xed,
|
||||
0xeb, 0x72, 0xe1, 0x46, 0xc6, 0x8c, 0xec, 0xe3, 0x3f, 0x00, 0xba, 0xf9, 0x94, 0x45, 0xf7, 0x40,
|
||||
0x34, 0xba, 0x86, 0x2e, 0xef, 0xf0, 0xfc, 0x6f, 0x22, 0x0c, 0xea, 0x11, 0x54, 0x83, 0x6c, 0xe7,
|
||||
0xab, 0x2f, 0x64, 0x41, 0xfd, 0xf1, 0x72, 0xa5, 0xdd, 0xb9, 0x09, 0xea, 0x7c, 0xf5, 0xc5, 0x31,
|
||||
0x85, 0x52, 0x3a, 0x70, 0x0d, 0xa4, 0x27, 0xfa, 0xa0, 0xde, 0xaa, 0x0f, 0xea, 0xf2, 0x0e, 0xff,
|
||||
0xa5, 0xc4, 0xfd, 0x84, 0x84, 0x16, 0x2b, 0xc2, 0x43, 0xc8, 0x19, 0xfa, 0x53, 0x1d, 0xcb, 0x82,
|
||||
0xba, 0xbf, 0x5c, 0x69, 0xbb, 0x09, 0xc0, 0x20, 0x97, 0xc4, 0x47, 0x15, 0xc8, 0xd7, 0x3b, 0x5f,
|
||||
0xd6, 0x9f, 0xf5, 0xe5, 0x8c, 0x8a, 0x96, 0x2b, 0x6d, 0x2f, 0x71, 0xd7, 0xdd, 0x17, 0xd6, 0x22,
|
||||
0x38, 0xfe, 0x9f, 0x00, 0xe5, 0xf4, 0xf5, 0x8d, 0x2a, 0x20, 0x9e, 0xb6, 0x3b, 0x7a, 0xb2, 0x5d,
|
||||
0xda, 0x17, 0x8d, 0xd1, 0x11, 0x14, 0x5b, 0x6d, 0xac, 0x37, 0x07, 0x5d, 0xfc, 0x2c, 0xc9, 0x25,
|
||||
0x0d, 0x6a, 0x39, 0x3e, 0x13, 0xf8, 0x02, 0xfd, 0x02, 0xca, 0xfd, 0x67, 0x4f, 0x3a, 0x6d, 0xe3,
|
||||
0xb7, 0x26, 0x8b, 0x98, 0x51, 0x1f, 0x2c, 0x57, 0xda, 0xdd, 0x2d, 0x30, 0x99, 0xf9, 0x64, 0x64,
|
||||
0x85, 0xc4, 0xee, 0xf3, 0x1b, 0x26, 0x72, 0x4a, 0x02, 0x6a, 0xc2, 0x7e, 0xb2, 0x74, 0xb3, 0x59,
|
||||
0x56, 0xfd, 0x64, 0xb9, 0xd2, 0x3e, 0xfa, 0xde, 0xf5, 0xeb, 0xdd, 0x25, 0x01, 0xdd, 0x83, 0x42,
|
||||
0x1c, 0x24, 0x51, 0x52, 0x7a, 0x69, 0xbc, 0xe0, 0xf8, 0x2f, 0x02, 0x14, 0xd7, 0xed, 0x2a, 0x22,
|
||||
0xdc, 0xe8, 0x9a, 0x3a, 0xc6, 0x5d, 0x9c, 0x30, 0xb0, 0x76, 0x1a, 0x94, 0x0d, 0xd1, 0x5d, 0x28,
|
||||
0x9c, 0xe9, 0x86, 0x8e, 0xdb, 0xcd, 0xa4, 0x30, 0xd6, 0x90, 0x33, 0xe2, 0x11, 0xdf, 0x19, 0xa1,
|
||||
0x8f, 0xa1, 0x6c, 0x74, 0xcd, 0xfe, 0x79, 0xf3, 0x71, 0x92, 0x3a, 0xdb, 0x3f, 0x15, 0xaa, 0x3f,
|
||||
0x1f, 0x5d, 0x30, 0x3e, 0x8f, 0xa3, 0x1a, 0x7a, 0x5a, 0xef, 0xb4, 0x5b, 0x1c, 0x9a, 0x55, 0x95,
|
||||
0xe5, 0x4a, 0xbb, 0xbd, 0x86, 0xb6, 0xf9, 0x3b, 0x26, 0xc2, 0x1e, 0xdb, 0x50, 0xf9, 0xfe, 0xc6,
|
||||
0x84, 0x34, 0xc8, 0xd7, 0x7b, 0x3d, 0xdd, 0x68, 0x25, 0x7f, 0xbf, 0xf1, 0xd5, 0x67, 0x33, 0xe2,
|
||||
0xd9, 0x11, 0xe2, 0xb4, 0x8b, 0xcf, 0xf4, 0x41, 0xf2, 0xf3, 0x1b, 0xc4, 0x29, 0x8d, 0xae, 0xf7,
|
||||
0xc6, 0xe1, 0xab, 0xef, 0x2a, 0x3b, 0xdf, 0x7e, 0x57, 0xd9, 0x79, 0x75, 0x55, 0x11, 0xbe, 0xbd,
|
||||
0xaa, 0x08, 0xff, 0xba, 0xaa, 0xec, 0xfc, 0xe7, 0xaa, 0x22, 0x7c, 0xf3, 0xef, 0x8a, 0x30, 0xcc,
|
||||
0xb3, 0x46, 0xf6, 0xf9, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe5, 0x17, 0x2b, 0x62, 0xdd, 0x0e,
|
||||
0x00, 0x00,
|
||||
// 1793 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x73, 0xdb, 0xc6,
|
||||
0x15, 0x17, 0x48, 0xf0, 0xdf, 0x23, 0xa5, 0x40, 0x6b, 0x5b, 0x45, 0x11, 0x85, 0x84, 0x19, 0x3b,
|
||||
0x56, 0x34, 0x89, 0xec, 0x26, 0x69, 0x3b, 0xed, 0xb4, 0x9d, 0xe1, 0x1f, 0x48, 0xe6, 0x54, 0x26,
|
||||
0xd9, 0x25, 0xe5, 0xd4, 0x39, 0x14, 0x03, 0x12, 0x4b, 0x0a, 0x63, 0x10, 0xcb, 0x02, 0xa0, 0x64,
|
||||
0xe6, 0x23, 0xf0, 0x13, 0xf4, 0xc2, 0x99, 0xcc, 0xf4, 0xd4, 0x6f, 0xe2, 0x63, 0xda, 0x43, 0x0f,
|
||||
0x3d, 0x68, 0x1a, 0xf5, 0x92, 0x63, 0x3f, 0x41, 0xa7, 0xb3, 0xbb, 0x00, 0x09, 0x4a, 0x76, 0xc6,
|
||||
0x87, 0x9c, 0xb8, 0xfb, 0xde, 0x6f, 0xdf, 0xf2, 0xfd, 0xde, 0xef, 0xbd, 0x05, 0x14, 0x06, 0x64,
|
||||
0x7a, 0x34, 0xf5, 0x69, 0x48, 0x51, 0x9e, 0xff, 0x0c, 0xa9, 0xab, 0x7d, 0x3a, 0x76, 0xc2, 0xf3,
|
||||
0xd9, 0xe0, 0x68, 0x48, 0x27, 0x8f, 0xc7, 0x74, 0x4c, 0x1f, 0x73, 0xcf, 0x60, 0x36, 0xe2, 0x3b,
|
||||
0xbe, 0xe1, 0x2b, 0x71, 0xb0, 0x3a, 0x85, 0xcc, 0x53, 0xe2, 0xba, 0x14, 0x55, 0xa0, 0x68, 0x93,
|
||||
0x0b, 0x67, 0x48, 0x4c, 0xcf, 0x9a, 0x10, 0x55, 0xd2, 0xa5, 0x83, 0x02, 0x06, 0x61, 0x6a, 0x5b,
|
||||
0x13, 0xc2, 0x00, 0x43, 0xd7, 0x21, 0x5e, 0x28, 0x00, 0x29, 0x01, 0x10, 0x26, 0x0e, 0x78, 0x08,
|
||||
0x3b, 0x11, 0xe0, 0x82, 0xf8, 0x81, 0x43, 0x3d, 0x35, 0xcd, 0x31, 0xdb, 0xc2, 0xfa, 0x5c, 0x18,
|
||||
0xab, 0x01, 0x64, 0x9f, 0x12, 0xcb, 0x26, 0x3e, 0xfa, 0x18, 0xe4, 0x70, 0x3e, 0x15, 0x77, 0xed,
|
||||
0x7c, 0x76, 0xef, 0x28, 0xce, 0xe1, 0xe8, 0x19, 0x09, 0x02, 0x6b, 0x4c, 0xfa, 0xf3, 0x29, 0xc1,
|
||||
0x1c, 0x82, 0x7e, 0x07, 0xc5, 0x21, 0x9d, 0x4c, 0x7d, 0x12, 0xf0, 0xc0, 0x29, 0x7e, 0x62, 0xff,
|
||||
0xd6, 0x89, 0xc6, 0x1a, 0x83, 0x93, 0x07, 0xaa, 0x35, 0xd8, 0x6e, 0xb8, 0xb3, 0x20, 0x24, 0x7e,
|
||||
0x83, 0x7a, 0x23, 0x67, 0x8c, 0x9e, 0x40, 0x6e, 0x44, 0x5d, 0x9b, 0xf8, 0x81, 0x2a, 0xe9, 0xe9,
|
||||
0x83, 0xe2, 0x67, 0xca, 0x3a, 0xd8, 0x31, 0x77, 0xd4, 0xe5, 0xd7, 0x57, 0x95, 0x2d, 0x1c, 0xc3,
|
||||
0xaa, 0x7f, 0x4d, 0x41, 0x56, 0x78, 0xd0, 0x1e, 0xa4, 0x1c, 0x5b, 0x50, 0x54, 0xcf, 0x5e, 0x5f,
|
||||
0x55, 0x52, 0xad, 0x26, 0x4e, 0x39, 0x36, 0xba, 0x0b, 0x19, 0xd7, 0x1a, 0x10, 0x37, 0x22, 0x47,
|
||||
0x6c, 0xd0, 0xfb, 0x50, 0xf0, 0x89, 0x65, 0x9b, 0xd4, 0x73, 0xe7, 0x9c, 0x92, 0x3c, 0xce, 0x33,
|
||||
0x43, 0xc7, 0x73, 0xe7, 0xe8, 0x53, 0x40, 0xce, 0xd8, 0xa3, 0x3e, 0x31, 0xa7, 0xc4, 0x9f, 0x38,
|
||||
0xfc, 0xdf, 0x06, 0xaa, 0xcc, 0x51, 0xbb, 0xc2, 0xd3, 0x5d, 0x3b, 0xd0, 0x87, 0xb0, 0x1d, 0xc1,
|
||||
0x6d, 0xe2, 0x92, 0x90, 0xa8, 0x19, 0x8e, 0x2c, 0x09, 0x63, 0x93, 0xdb, 0xd0, 0x13, 0xb8, 0x6b,
|
||||
0x3b, 0x81, 0x35, 0x70, 0x89, 0x19, 0x92, 0xc9, 0xd4, 0x74, 0x3c, 0x9b, 0xbc, 0x22, 0x81, 0x9a,
|
||||
0xe5, 0x58, 0x14, 0xf9, 0xfa, 0x64, 0x32, 0x6d, 0x09, 0x0f, 0xda, 0x83, 0xec, 0xd4, 0x9a, 0x05,
|
||||
0xc4, 0x56, 0x73, 0x1c, 0x13, 0xed, 0x18, 0x4b, 0x42, 0x01, 0x81, 0xaa, 0xdc, 0x64, 0xa9, 0xc9,
|
||||
0x1d, 0x31, 0x4b, 0x11, 0xac, 0xfa, 0xdf, 0x14, 0x64, 0x85, 0x07, 0x7d, 0xb4, 0x62, 0xa9, 0x54,
|
||||
0xdf, 0x63, 0xa8, 0x7f, 0x5d, 0x55, 0xf2, 0xc2, 0xd7, 0x6a, 0x26, 0x58, 0x43, 0x20, 0x27, 0x14,
|
||||
0xc5, 0xd7, 0x68, 0x1f, 0x0a, 0x96, 0x6d, 0xb3, 0xea, 0x91, 0x40, 0x4d, 0xeb, 0xe9, 0x83, 0x02,
|
||||
0x5e, 0x1b, 0xd0, 0x2f, 0x37, 0xd5, 0x20, 0xdf, 0xd4, 0xcf, 0xdb, 0x64, 0xc0, 0x4a, 0x31, 0x24,
|
||||
0x7e, 0xa4, 0xe0, 0x0c, 0xbf, 0x2f, 0xcf, 0x0c, 0x5c, 0xbf, 0xf7, 0xa1, 0x34, 0xb1, 0x5e, 0x99,
|
||||
0x01, 0xf9, 0xf3, 0x8c, 0x78, 0x43, 0xc2, 0xe9, 0x4a, 0xe3, 0xe2, 0xc4, 0x7a, 0xd5, 0x8b, 0x4c,
|
||||
0xa8, 0x0c, 0xe0, 0x78, 0xa1, 0x4f, 0xed, 0xd9, 0x90, 0xf8, 0x11, 0x57, 0x09, 0x0b, 0xfa, 0x39,
|
||||
0xe4, 0x39, 0xd9, 0xa6, 0x63, 0xab, 0x79, 0x5d, 0x3a, 0x90, 0xeb, 0x5a, 0x94, 0x78, 0x8e, 0x53,
|
||||
0xcd, 0xf3, 0x8e, 0x97, 0x38, 0xc7, 0xb1, 0x2d, 0x1b, 0xfd, 0x06, 0xb4, 0xe0, 0xa5, 0xc3, 0x0a,
|
||||
0x25, 0x22, 0x85, 0x0e, 0xf5, 0x4c, 0x9f, 0x4c, 0xe8, 0x85, 0xe5, 0x06, 0x6a, 0x81, 0x5f, 0xa3,
|
||||
0x32, 0x44, 0x2b, 0x01, 0xc0, 0x91, 0xbf, 0xda, 0x81, 0x0c, 0x8f, 0xc8, 0xaa, 0x28, 0xc4, 0x1a,
|
||||
0x75, 0x6f, 0xb4, 0x43, 0x47, 0x90, 0x19, 0x39, 0x2e, 0x09, 0xd4, 0x14, 0xaf, 0x21, 0x4a, 0x28,
|
||||
0xdd, 0x71, 0x49, 0xcb, 0x1b, 0xd1, 0xa8, 0x8a, 0x02, 0x56, 0x3d, 0x83, 0x22, 0x0f, 0x78, 0x36,
|
||||
0xb5, 0xad, 0x90, 0xfc, 0x68, 0x61, 0xaf, 0x64, 0xc8, 0xc7, 0x9e, 0x55, 0xd1, 0xa5, 0x44, 0xd1,
|
||||
0x0f, 0xa3, 0x79, 0x20, 0xba, 0x7b, 0xef, 0x76, 0xbc, 0xc4, 0x40, 0x40, 0x20, 0x07, 0xce, 0xd7,
|
||||
0x84, 0xf7, 0x53, 0x1a, 0xf3, 0x35, 0xd2, 0xa1, 0x78, 0xb3, 0x89, 0xb6, 0x71, 0xd2, 0x84, 0x3e,
|
||||
0x00, 0x98, 0x50, 0xdb, 0x19, 0x39, 0xc4, 0x36, 0x03, 0x2e, 0x80, 0x34, 0x2e, 0xc4, 0x96, 0x1e,
|
||||
0x52, 0x99, 0xdc, 0x59, 0x0b, 0xd9, 0x51, 0xaf, 0xc4, 0x5b, 0x74, 0x00, 0x39, 0xc7, 0xbb, 0xb0,
|
||||
0x5c, 0x27, 0xea, 0x90, 0xfa, 0xce, 0xf5, 0x55, 0x05, 0xb0, 0x75, 0xd9, 0x12, 0x56, 0x1c, 0xbb,
|
||||
0xd9, 0x14, 0xf4, 0xe8, 0x46, 0x33, 0xe7, 0x79, 0xa8, 0x6d, 0x8f, 0x26, 0x1b, 0xf9, 0x09, 0xe4,
|
||||
0xe2, 0x29, 0xc9, 0xea, 0xbb, 0xd1, 0x59, 0xcf, 0xc9, 0x30, 0xa4, 0xab, 0xf9, 0x13, 0xc1, 0x90,
|
||||
0x06, 0xf9, 0x95, 0x34, 0x81, 0xff, 0xf3, 0xd5, 0x9e, 0xcd, 0xe6, 0x55, 0x5e, 0x5e, 0xa0, 0x16,
|
||||
0x75, 0xe9, 0x20, 0x83, 0x57, 0xa9, 0xb6, 0xd9, 0x75, 0x6b, 0xc0, 0x60, 0xae, 0x96, 0xb8, 0x36,
|
||||
0xdf, 0x8b, 0xb5, 0xd9, 0x3b, 0xa7, 0x7e, 0xd8, 0x6a, 0xae, 0x4f, 0xd4, 0xe7, 0xe8, 0x31, 0xc0,
|
||||
0xc0, 0xa5, 0xc3, 0x97, 0x26, 0xa7, 0x79, 0x9b, 0x45, 0xac, 0x2b, 0xd7, 0x57, 0x95, 0x12, 0xb6,
|
||||
0x2e, 0xeb, 0xcc, 0xd1, 0x73, 0xbe, 0x26, 0xb8, 0x30, 0x88, 0x97, 0xe8, 0x67, 0x90, 0xe5, 0xf6,
|
||||
0x78, 0x54, 0xdc, 0x59, 0x27, 0xc4, 0xed, 0x09, 0x41, 0x44, 0x40, 0xc6, 0x55, 0x30, 0x9f, 0xb8,
|
||||
0x8e, 0xf7, 0xd2, 0x0c, 0x2d, 0x7f, 0x4c, 0x42, 0x75, 0x57, 0xbc, 0x18, 0x91, 0xb5, 0xcf, 0x8d,
|
||||
0xac, 0xae, 0x2e, 0x1d, 0x5a, 0xae, 0x39, 0x72, 0xad, 0x71, 0xa0, 0x7e, 0x9f, 0xe3, 0x85, 0x05,
|
||||
0x6e, 0x3b, 0x66, 0xa6, 0x5f, 0xcb, 0x7f, 0xf9, 0xa6, 0xb2, 0x55, 0xf5, 0xa0, 0xb0, 0xba, 0x89,
|
||||
0xa9, 0x96, 0x8e, 0x46, 0x01, 0x09, 0xb9, 0xc4, 0xd2, 0x38, 0xda, 0xad, 0x84, 0x93, 0xe2, 0x1c,
|
||||
0x09, 0xe1, 0x20, 0x90, 0xcf, 0xad, 0xe0, 0x9c, 0x8b, 0xa9, 0x84, 0xf9, 0x9a, 0x8d, 0x8a, 0x4b,
|
||||
0x62, 0xbd, 0x34, 0xb9, 0x43, 0x48, 0x29, 0xcf, 0x0c, 0x4f, 0xad, 0xe0, 0x3c, 0xba, 0xef, 0xb7,
|
||||
0x90, 0x15, 0xa5, 0x42, 0x9f, 0x43, 0x7e, 0x48, 0x67, 0x5e, 0xb8, 0x7e, 0x4e, 0x76, 0x93, 0xd3,
|
||||
0x88, 0x7b, 0xa2, 0xdc, 0x57, 0xc0, 0xea, 0x31, 0xe4, 0x22, 0x17, 0x7a, 0xb8, 0x1a, 0x95, 0x72,
|
||||
0xfd, 0xde, 0x8d, 0xaa, 0x6c, 0xbe, 0x2f, 0x17, 0x96, 0x3b, 0x13, 0x7f, 0x5e, 0xc6, 0x62, 0x53,
|
||||
0xfd, 0xbb, 0x04, 0x39, 0xcc, 0x94, 0x10, 0x84, 0x89, 0x97, 0x29, 0xb3, 0xf1, 0x32, 0xad, 0x7b,
|
||||
0x38, 0xb5, 0xd1, 0xc3, 0x71, 0x1b, 0xa6, 0x13, 0x6d, 0xb8, 0x66, 0x4e, 0x7e, 0x23, 0x73, 0x99,
|
||||
0x37, 0x30, 0x97, 0x4d, 0x30, 0xf7, 0x10, 0x76, 0x46, 0x3e, 0x9d, 0xf0, 0xb7, 0x87, 0xfa, 0x96,
|
||||
0x3f, 0x8f, 0x06, 0xe5, 0x36, 0xb3, 0xf6, 0x63, 0xe3, 0x26, 0xc1, 0xf9, 0x4d, 0x82, 0xab, 0x26,
|
||||
0xe4, 0x31, 0x09, 0xa6, 0xd4, 0x0b, 0xc8, 0x5b, 0x73, 0x42, 0x20, 0xdb, 0x56, 0x68, 0xf1, 0x8c,
|
||||
0x4a, 0x98, 0xaf, 0xd1, 0x23, 0x90, 0x87, 0xd4, 0x16, 0xf9, 0xec, 0x24, 0x25, 0x68, 0xf8, 0x3e,
|
||||
0xf5, 0x1b, 0xd4, 0x26, 0x98, 0x03, 0xaa, 0x53, 0x50, 0x9a, 0xf4, 0xd2, 0x73, 0xa9, 0x65, 0x77,
|
||||
0x7d, 0x3a, 0x66, 0x0f, 0xc4, 0x5b, 0x07, 0x5d, 0x13, 0x72, 0x33, 0x3e, 0x0a, 0xe3, 0x51, 0xf7,
|
||||
0x60, 0x73, 0x34, 0xdd, 0x0c, 0x24, 0xe6, 0x66, 0xdc, 0xbf, 0xd1, 0xd1, 0xea, 0x3f, 0x25, 0xd0,
|
||||
0xde, 0x8e, 0x46, 0x2d, 0x28, 0x0a, 0xa4, 0x99, 0xf8, 0x26, 0x3a, 0x78, 0x97, 0x8b, 0xf8, 0x54,
|
||||
0x84, 0xd9, 0x6a, 0xfd, 0xc6, 0x07, 0x35, 0x31, 0x6f, 0xd2, 0xef, 0x36, 0x6f, 0x1e, 0xc1, 0xb6,
|
||||
0x18, 0x00, 0xf1, 0xe7, 0x83, 0xac, 0xa7, 0x0f, 0x32, 0xf5, 0x94, 0xb2, 0x85, 0x4b, 0x03, 0xd1,
|
||||
0x66, 0xdc, 0x5e, 0xcd, 0x82, 0xdc, 0x75, 0xbc, 0x71, 0xb5, 0x02, 0x99, 0x86, 0x4b, 0x79, 0xc1,
|
||||
0xb2, 0x3e, 0xb1, 0x02, 0xea, 0xc5, 0x3c, 0x8a, 0xdd, 0xe1, 0x3f, 0x52, 0x50, 0x4c, 0x7c, 0xda,
|
||||
0xa1, 0x27, 0xb0, 0xd3, 0x38, 0x3d, 0xeb, 0xf5, 0x0d, 0x6c, 0x36, 0x3a, 0xed, 0xe3, 0xd6, 0x89,
|
||||
0xb2, 0xa5, 0xed, 0x2f, 0x96, 0xba, 0x3a, 0x59, 0x83, 0x36, 0xbf, 0xda, 0x2a, 0x90, 0x69, 0xb5,
|
||||
0x9b, 0xc6, 0x1f, 0x15, 0x49, 0xbb, 0xbb, 0x58, 0xea, 0x4a, 0x02, 0x28, 0x9e, 0xc0, 0x4f, 0xa0,
|
||||
0xc4, 0x01, 0xe6, 0x59, 0xb7, 0x59, 0xeb, 0x1b, 0x4a, 0x4a, 0xd3, 0x16, 0x4b, 0x7d, 0xef, 0x26,
|
||||
0x2e, 0xe2, 0xfc, 0x43, 0xc8, 0x61, 0xe3, 0x0f, 0x67, 0x46, 0xaf, 0xaf, 0xa4, 0xb5, 0xbd, 0xc5,
|
||||
0x52, 0x47, 0x09, 0x60, 0xdc, 0x52, 0x0f, 0x21, 0x8f, 0x8d, 0x5e, 0xb7, 0xd3, 0xee, 0x19, 0x8a,
|
||||
0xac, 0xfd, 0x64, 0xb1, 0xd4, 0xef, 0x6c, 0xa0, 0x22, 0x95, 0xfe, 0x02, 0x76, 0x9b, 0x9d, 0x2f,
|
||||
0xdb, 0xa7, 0x9d, 0x5a, 0xd3, 0xec, 0xe2, 0xce, 0x09, 0x36, 0x7a, 0x3d, 0x25, 0xa3, 0x55, 0x16,
|
||||
0x4b, 0xfd, 0xfd, 0x04, 0xfe, 0x96, 0xe8, 0x3e, 0x00, 0xb9, 0xdb, 0x6a, 0x9f, 0x28, 0x59, 0xed,
|
||||
0xce, 0x62, 0xa9, 0xbf, 0x97, 0x80, 0x32, 0x52, 0x59, 0xc6, 0x8d, 0xd3, 0x4e, 0xcf, 0x50, 0x72,
|
||||
0xb7, 0x32, 0xe6, 0x64, 0x1f, 0xfe, 0x09, 0xd0, 0xed, 0x8f, 0x5f, 0xf4, 0x00, 0xe4, 0x76, 0xa7,
|
||||
0x6d, 0x28, 0x5b, 0x22, 0xff, 0xdb, 0x88, 0x36, 0xf5, 0x08, 0xaa, 0x42, 0xfa, 0xf4, 0xab, 0x2f,
|
||||
0x14, 0x49, 0xfb, 0xe9, 0x62, 0xa9, 0xdf, 0xbb, 0x0d, 0x3a, 0xfd, 0xea, 0x8b, 0x43, 0x0a, 0xc5,
|
||||
0x64, 0xe0, 0x2a, 0xe4, 0x9f, 0x19, 0xfd, 0x5a, 0xb3, 0xd6, 0xaf, 0x29, 0x5b, 0xe2, 0x2f, 0xc5,
|
||||
0xee, 0x67, 0x24, 0xb4, 0x78, 0x13, 0xee, 0x43, 0xa6, 0x6d, 0x3c, 0x37, 0xb0, 0x22, 0x69, 0xbb,
|
||||
0x8b, 0xa5, 0xbe, 0x1d, 0x03, 0xda, 0xe4, 0x82, 0xf8, 0xa8, 0x0c, 0xd9, 0xda, 0xe9, 0x97, 0xb5,
|
||||
0x17, 0x3d, 0x25, 0xa5, 0xa1, 0xc5, 0x52, 0xdf, 0x89, 0xdd, 0x35, 0xf7, 0xd2, 0x9a, 0x07, 0x87,
|
||||
0xff, 0x93, 0xa0, 0x94, 0x7c, 0xf0, 0x51, 0x19, 0xe4, 0xe3, 0xd6, 0xa9, 0x11, 0x5f, 0x97, 0xf4,
|
||||
0xb1, 0x35, 0x3a, 0x80, 0x42, 0xb3, 0x85, 0x8d, 0x46, 0xbf, 0x83, 0x5f, 0xc4, 0xb9, 0x24, 0x41,
|
||||
0x4d, 0xc7, 0xe7, 0x02, 0x9f, 0xa3, 0x5f, 0x41, 0xa9, 0xf7, 0xe2, 0xd9, 0x69, 0xab, 0xfd, 0x7b,
|
||||
0x93, 0x47, 0x4c, 0x69, 0x8f, 0x16, 0x4b, 0xfd, 0xfe, 0x06, 0x98, 0x4c, 0x7d, 0x32, 0xb4, 0x42,
|
||||
0x62, 0xf7, 0xc4, 0x1b, 0xc4, 0x9c, 0x79, 0x09, 0x35, 0x60, 0x37, 0x3e, 0xba, 0xbe, 0x2c, 0xad,
|
||||
0x7d, 0xb2, 0x58, 0xea, 0x1f, 0xfd, 0xe0, 0xf9, 0xd5, 0xed, 0x79, 0x09, 0x3d, 0x80, 0x5c, 0x14,
|
||||
0x24, 0x56, 0x52, 0xf2, 0x68, 0x74, 0xe0, 0xf0, 0x6f, 0x12, 0x14, 0x56, 0xe3, 0x8a, 0x11, 0xde,
|
||||
0xee, 0x98, 0x06, 0xc6, 0x1d, 0x1c, 0x33, 0xb0, 0x72, 0xb6, 0x29, 0x5f, 0xa2, 0xfb, 0x90, 0x3b,
|
||||
0x31, 0xda, 0x06, 0x6e, 0x35, 0xe2, 0xc6, 0x58, 0x41, 0x4e, 0x88, 0x47, 0x7c, 0x67, 0x88, 0x3e,
|
||||
0x86, 0x52, 0xbb, 0x63, 0xf6, 0xce, 0x1a, 0x4f, 0xe3, 0xd4, 0xf9, 0xfd, 0x89, 0x50, 0xbd, 0xd9,
|
||||
0xf0, 0x9c, 0xf3, 0x79, 0xc8, 0x7a, 0xe8, 0x79, 0xed, 0xb4, 0xd5, 0x14, 0xd0, 0xb4, 0xa6, 0x2e,
|
||||
0x96, 0xfa, 0xdd, 0x15, 0x34, 0xfa, 0xe4, 0x61, 0xd8, 0x43, 0x1b, 0xca, 0x3f, 0x3c, 0x98, 0x90,
|
||||
0x0e, 0xd9, 0x5a, 0xb7, 0x6b, 0xb4, 0x9b, 0xf1, 0xbf, 0x5f, 0xfb, 0x6a, 0xd3, 0x29, 0xf1, 0x6c,
|
||||
0x86, 0x38, 0xee, 0xe0, 0x13, 0xa3, 0x1f, 0xff, 0xf9, 0x35, 0xe2, 0x98, 0xb2, 0x0f, 0x80, 0xfa,
|
||||
0xfe, 0xeb, 0xef, 0xca, 0x5b, 0xdf, 0x7e, 0x57, 0xde, 0x7a, 0x7d, 0x5d, 0x96, 0xbe, 0xbd, 0x2e,
|
||||
0x4b, 0xff, 0xbe, 0x2e, 0x6f, 0x7d, 0x7f, 0x5d, 0x96, 0xbe, 0xf9, 0x4f, 0x59, 0x1a, 0x64, 0xf9,
|
||||
0x20, 0xfb, 0xfc, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x41, 0xd9, 0x3a, 0x0f, 0x0f, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
@ -93,22 +93,27 @@ message IndexUpdate {
|
||||
|
||||
message FileInfo {
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
string name = 1;
|
||||
FileInfoType type = 2;
|
||||
int64 size = 3;
|
||||
uint32 permissions = 4;
|
||||
int64 modified_s = 5;
|
||||
int32 modified_ns = 11;
|
||||
uint64 modified_by = 12 [(gogoproto.customtype) = "ShortID", (gogoproto.nullable) = false];
|
||||
bool deleted = 6;
|
||||
bool invalid = 7;
|
||||
bool no_permissions = 8;
|
||||
Vector version = 9 [(gogoproto.nullable) = false];
|
||||
int64 sequence = 10;
|
||||
int32 block_size = 13 [(gogoproto.customname) = "RawBlockSize"];
|
||||
|
||||
string name = 1;
|
||||
FileInfoType type = 2;
|
||||
int64 size = 3;
|
||||
uint32 permissions = 4;
|
||||
int64 modified_s = 5;
|
||||
int32 modified_ns = 11;
|
||||
uint64 modified_by = 12 [(gogoproto.customtype) = "ShortID", (gogoproto.nullable) = false];
|
||||
bool deleted = 6;
|
||||
bool invalid = 7 [(gogoproto.customname) = "RawInvalid"];
|
||||
bool no_permissions = 8;
|
||||
Vector version = 9 [(gogoproto.nullable) = false];
|
||||
int64 sequence = 10;
|
||||
int32 block_size = 13 [(gogoproto.customname) = "RawBlockSize"];
|
||||
repeated BlockInfo Blocks = 16 [(gogoproto.nullable) = false];
|
||||
string symlink_target = 17;
|
||||
|
||||
// The local_flags fields stores flags that are relevant to the local
|
||||
// host only. It is not part of the protocol, doesn't get sent or
|
||||
// received (we make sure to zero it), nonetheless we need it on our
|
||||
// struct and to be able to serialize it to/from the database.
|
||||
uint32 local_flags = 1000;
|
||||
}
|
||||
|
||||
enum FileInfoType {
|
||||
|
@ -28,14 +28,14 @@ func (m Hello) Magic() uint32 {
|
||||
func (f FileInfo) String() string {
|
||||
switch f.Type {
|
||||
case FileInfoTypeDirectory:
|
||||
return fmt.Sprintf("Directory{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Deleted:%v, Invalid:%v, NoPermissions:%v}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Deleted, f.Invalid, f.NoPermissions)
|
||||
return fmt.Sprintf("Directory{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions)
|
||||
case FileInfoTypeFile:
|
||||
return fmt.Sprintf("File{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Length:%d, Deleted:%v, Invalid:%v, NoPermissions:%v, BlockSize:%d, Blocks:%v}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Size, f.Deleted, f.Invalid, f.NoPermissions, f.RawBlockSize, f.Blocks)
|
||||
return fmt.Sprintf("File{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, Length:%d, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, BlockSize:%d, Blocks:%v}",
|
||||
f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.Size, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.RawBlockSize, f.Blocks)
|
||||
case FileInfoTypeSymlink, FileInfoTypeDeprecatedSymlinkDirectory, FileInfoTypeDeprecatedSymlinkFile:
|
||||
return fmt.Sprintf("Symlink{Name:%q, Type:%v, Sequence:%d, Version:%v, Deleted:%v, Invalid:%v, NoPermissions:%v, SymlinkTarget:%q}",
|
||||
f.Name, f.Type, f.Sequence, f.Version, f.Deleted, f.Invalid, f.NoPermissions, f.SymlinkTarget)
|
||||
return fmt.Sprintf("Symlink{Name:%q, Type:%v, Sequence:%d, Version:%v, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, SymlinkTarget:%q}",
|
||||
f.Name, f.Type, f.Sequence, f.Version, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.SymlinkTarget)
|
||||
default:
|
||||
panic("mystery file type detected")
|
||||
}
|
||||
@ -46,13 +46,25 @@ func (f FileInfo) IsDeleted() bool {
|
||||
}
|
||||
|
||||
func (f FileInfo) IsInvalid() bool {
|
||||
return f.Invalid
|
||||
return f.RawInvalid || f.LocalFlags&LocalInvalidFlags != 0
|
||||
}
|
||||
|
||||
func (f FileInfo) IsIgnored() bool {
|
||||
return f.LocalFlags&FlagLocalIgnored != 0
|
||||
}
|
||||
|
||||
func (f FileInfo) MustRescan() bool {
|
||||
return f.LocalFlags&FlagLocalMustRescan != 0
|
||||
}
|
||||
|
||||
func (f FileInfo) IsDirectory() bool {
|
||||
return f.Type == FileInfoTypeDirectory
|
||||
}
|
||||
|
||||
func (f FileInfo) ShouldConflict() bool {
|
||||
return f.LocalFlags&LocalConflictFlags != 0
|
||||
}
|
||||
|
||||
func (f FileInfo) IsSymlink() bool {
|
||||
switch f.Type {
|
||||
case FileInfoTypeSymlink, FileInfoTypeDeprecatedSymlinkDirectory, FileInfoTypeDeprecatedSymlinkFile:
|
||||
@ -149,7 +161,14 @@ func (f FileInfo) IsEmpty() bool {
|
||||
// - target
|
||||
// A directory does not have anything specific to check.
|
||||
func (f FileInfo) IsEquivalent(other FileInfo, ignorePerms bool, ignoreBlocks bool) bool {
|
||||
if f.Name != other.Name || f.Type != other.Type || f.Deleted != other.Deleted || f.Invalid != other.Invalid {
|
||||
if f.MustRescan() || other.MustRescan() {
|
||||
// These are per definition not equivalent because they don't
|
||||
// represent a valid state, even if both happen to have the
|
||||
// MustRescan bit set.
|
||||
return false
|
||||
}
|
||||
|
||||
if f.Name != other.Name || f.Type != other.Type || f.Deleted != other.Deleted || f.IsInvalid() != other.IsInvalid() {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -197,9 +216,23 @@ func BlocksEqual(a, b []BlockInfo) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *FileInfo) Invalidate(invalidatedBy ShortID) {
|
||||
f.Invalid = true
|
||||
f.ModifiedBy = invalidatedBy
|
||||
func (f *FileInfo) SetMustRescan(by ShortID) {
|
||||
f.LocalFlags = FlagLocalMustRescan
|
||||
f.ModifiedBy = by
|
||||
f.Blocks = nil
|
||||
f.Sequence = 0
|
||||
}
|
||||
|
||||
func (f *FileInfo) SetIgnored(by ShortID) {
|
||||
f.LocalFlags = FlagLocalIgnored
|
||||
f.ModifiedBy = by
|
||||
f.Blocks = nil
|
||||
f.Sequence = 0
|
||||
}
|
||||
|
||||
func (f *FileInfo) SetUnsupported(by ShortID) {
|
||||
f.LocalFlags = FlagLocalUnsupported
|
||||
f.ModifiedBy = by
|
||||
f.Blocks = nil
|
||||
f.Sequence = 0
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ func TestWinsConflict(t *testing.T) {
|
||||
// The first should always win over the second
|
||||
{{ModifiedS: 42}, {ModifiedS: 41}},
|
||||
{{ModifiedS: 41}, {ModifiedS: 42, Deleted: true}},
|
||||
{{Deleted: true}, {ModifiedS: 10, Invalid: true}},
|
||||
{{Deleted: true}, {ModifiedS: 10, RawInvalid: true}},
|
||||
{{ModifiedS: 41, Version: Vector{[]Counter{{42, 2}, {43, 1}}}}, {ModifiedS: 41, Version: Vector{[]Counter{{42, 1}, {43, 2}}}}},
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,21 @@ const (
|
||||
FlagShareBits = 0x000000ff
|
||||
)
|
||||
|
||||
// FileInfo.LocalFlags flags
|
||||
const (
|
||||
FlagLocalUnsupported = 1 << 0 // The kind is unsupported, e.g. symlinks on Windows
|
||||
FlagLocalIgnored = 1 << 1 // Matches local ignore patterns
|
||||
FlagLocalMustRescan = 1 << 2 // Doesn't match content on disk, must be rechecked fully
|
||||
|
||||
// Flags that should result in the Invalid bit on outgoing updates
|
||||
LocalInvalidFlags = FlagLocalUnsupported | FlagLocalIgnored | FlagLocalMustRescan
|
||||
|
||||
// Flags that should result in a file being in conflict with its
|
||||
// successor, due to us not having an up to date picture of its state on
|
||||
// disk.
|
||||
LocalConflictFlags = FlagLocalUnsupported | FlagLocalIgnored
|
||||
)
|
||||
|
||||
var (
|
||||
ErrClosed = errors.New("connection closed")
|
||||
ErrTimeout = errors.New("read timeout")
|
||||
@ -535,7 +550,7 @@ func checkFileInfoConsistency(f FileInfo) error {
|
||||
// Directories should have no blocks
|
||||
return errDirectoryHasBlocks
|
||||
|
||||
case !f.Deleted && !f.Invalid && f.Type == FileInfoTypeFile && len(f.Blocks) == 0:
|
||||
case !f.Deleted && !f.IsInvalid() && f.Type == FileInfoTypeFile && len(f.Blocks) == 0:
|
||||
// Non-deleted, non-invalid files should have at least one block
|
||||
return errFileHasNoBlocks
|
||||
}
|
||||
|
@ -391,6 +391,28 @@ func BenchmarkBlockSize(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalFlagBits(t *testing.T) {
|
||||
var f FileInfo
|
||||
if f.IsIgnored() || f.MustRescan() || f.IsInvalid() {
|
||||
t.Error("file should have no weird bits set by default")
|
||||
}
|
||||
|
||||
f.SetIgnored(42)
|
||||
if !f.IsIgnored() || f.MustRescan() || !f.IsInvalid() {
|
||||
t.Error("file should be ignored and invalid")
|
||||
}
|
||||
|
||||
f.SetMustRescan(42)
|
||||
if f.IsIgnored() || !f.MustRescan() || !f.IsInvalid() {
|
||||
t.Error("file should be must-rescan and invalid")
|
||||
}
|
||||
|
||||
f.SetUnsupported(42)
|
||||
if f.IsIgnored() || f.MustRescan() || !f.IsInvalid() {
|
||||
t.Error("file should be invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEquivalent(t *testing.T) {
|
||||
b := func(v bool) *bool {
|
||||
return &v
|
||||
@ -430,8 +452,8 @@ func TestIsEquivalent(t *testing.T) {
|
||||
eq: false,
|
||||
},
|
||||
{
|
||||
a: FileInfo{Invalid: false},
|
||||
b: FileInfo{Invalid: true},
|
||||
a: FileInfo{RawInvalid: false},
|
||||
b: FileInfo{RawInvalid: true},
|
||||
eq: false,
|
||||
},
|
||||
{
|
||||
@ -445,6 +467,31 @@ func TestIsEquivalent(t *testing.T) {
|
||||
eq: false,
|
||||
},
|
||||
|
||||
// Special handling of local flags and invalidity. "MustRescan"
|
||||
// files are never equivalent to each other. Otherwise, equivalence
|
||||
// is based just on whether the file becomes IsInvalid() or not, not
|
||||
// the specific reason or flag bits.
|
||||
{
|
||||
a: FileInfo{LocalFlags: FlagLocalMustRescan},
|
||||
b: FileInfo{LocalFlags: FlagLocalMustRescan},
|
||||
eq: false,
|
||||
},
|
||||
{
|
||||
a: FileInfo{RawInvalid: true},
|
||||
b: FileInfo{RawInvalid: true},
|
||||
eq: true,
|
||||
},
|
||||
{
|
||||
a: FileInfo{LocalFlags: FlagLocalUnsupported},
|
||||
b: FileInfo{LocalFlags: FlagLocalUnsupported},
|
||||
eq: true,
|
||||
},
|
||||
{
|
||||
a: FileInfo{RawInvalid: true},
|
||||
b: FileInfo{LocalFlags: FlagLocalUnsupported},
|
||||
eq: true,
|
||||
},
|
||||
|
||||
// Difference in blocks is not OK
|
||||
{
|
||||
a: FileInfo{Blocks: []BlockInfo{{Hash: []byte{1, 2, 3, 4}}}},
|
||||
|
@ -373,11 +373,12 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn
|
||||
if curFile.IsEquivalent(f, w.IgnorePerms, true) {
|
||||
return nil
|
||||
}
|
||||
if curFile.Invalid {
|
||||
// We do not want to override the global version with the file we
|
||||
// currently have. Keeping only our local counter makes sure we are in
|
||||
// conflict with any other existing versions, which will be resolved by
|
||||
// the normal pulling mechanisms.
|
||||
if curFile.ShouldConflict() {
|
||||
// The old file was invalid for whatever reason and probably not
|
||||
// up to date with what was out there in the cluster. Drop all
|
||||
// others from the version vector to indicate that we haven't
|
||||
// taken their version into account, and possibly cause a
|
||||
// conflict.
|
||||
f.Version = f.Version.DropOthers(w.ShortID)
|
||||
}
|
||||
l.Debugln("rescan:", curFile, info.ModTime().Unix(), info.Mode()&fs.ModePerm)
|
||||
@ -412,11 +413,12 @@ func (w *walker) walkDir(ctx context.Context, relPath string, info fs.FileInfo,
|
||||
if cf.IsEquivalent(f, w.IgnorePerms, true) {
|
||||
return nil
|
||||
}
|
||||
if cf.Invalid {
|
||||
// We do not want to override the global version with the file we
|
||||
// currently have. Keeping only our local counter makes sure we are in
|
||||
// conflict with any other existing versions, which will be resolved by
|
||||
// the normal pulling mechanisms.
|
||||
if cf.ShouldConflict() {
|
||||
// The old file was invalid for whatever reason and probably not
|
||||
// up to date with what was out there in the cluster. Drop all
|
||||
// others from the version vector to indicate that we haven't
|
||||
// taken their version into account, and possibly cause a
|
||||
// conflict.
|
||||
f.Version = f.Version.DropOthers(w.ShortID)
|
||||
}
|
||||
}
|
||||
@ -467,11 +469,12 @@ func (w *walker) walkSymlink(ctx context.Context, relPath string, dchan chan pro
|
||||
if cf.IsEquivalent(f, w.IgnorePerms, true) {
|
||||
return nil
|
||||
}
|
||||
if cf.Invalid {
|
||||
// We do not want to override the global version with the file we
|
||||
// currently have. Keeping only our local counter makes sure we are in
|
||||
// conflict with any other existing versions, which will be resolved by
|
||||
// the normal pulling mechanisms.
|
||||
if cf.ShouldConflict() {
|
||||
// The old file was invalid for whatever reason and probably not
|
||||
// up to date with what was out there in the cluster. Drop all
|
||||
// others from the version vector to indicate that we haven't
|
||||
// taken their version into account, and possibly cause a
|
||||
// conflict.
|
||||
f.Version = f.Version.DropOthers(w.ShortID)
|
||||
}
|
||||
}
|
||||
|
@ -648,10 +648,10 @@ func TestIssue4841(t *testing.T) {
|
||||
Hashers: 2,
|
||||
CurrentFiler: fakeCurrentFiler{
|
||||
"foo": {
|
||||
Name: "foo",
|
||||
Type: protocol.FileInfoTypeFile,
|
||||
Invalid: true,
|
||||
Version: protocol.Vector{}.Update(1),
|
||||
Name: "foo",
|
||||
Type: protocol.FileInfoTypeFile,
|
||||
LocalFlags: protocol.FlagLocalIgnored,
|
||||
Version: protocol.Vector{}.Update(1),
|
||||
},
|
||||
},
|
||||
ShortID: protocol.LocalDeviceID.Short(),
|
||||
|
Loading…
Reference in New Issue
Block a user