schemaupdater.go 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. // Copyright (C) 2018 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package db
  7. import (
  8. "bytes"
  9. "errors"
  10. "fmt"
  11. "sort"
  12. "strings"
  13. "github.com/syncthing/syncthing/lib/db/backend"
  14. "github.com/syncthing/syncthing/lib/protocol"
  15. )
  16. // List of all dbVersion to dbMinSyncthingVersion pairs for convenience
  17. // 0: v0.14.0
  18. // 1: v0.14.46
  19. // 2: v0.14.48
  20. // 3-5: v0.14.49
  21. // 6: v0.14.50
  22. // 7: v0.14.53
  23. // 8-9: v1.4.0
  24. // 10-11: v1.6.0
  25. // 12-13: v1.7.0
  26. // 14: v1.9.0
  27. const (
  28. dbVersion = 14
  29. dbMinSyncthingVersion = "v1.9.0"
  30. )
  31. var errFolderMissing = errors.New("folder present in global list but missing in keyer index")
  32. type databaseDowngradeError struct {
  33. minSyncthingVersion string
  34. }
  35. func (e *databaseDowngradeError) Error() string {
  36. if e.minSyncthingVersion == "" {
  37. return "newer Syncthing required"
  38. }
  39. return fmt.Sprintf("Syncthing %s required", e.minSyncthingVersion)
  40. }
  41. func UpdateSchema(db *Lowlevel) error {
  42. updater := &schemaUpdater{db}
  43. return updater.updateSchema()
  44. }
  45. type schemaUpdater struct {
  46. *Lowlevel
  47. }
  48. func (db *schemaUpdater) updateSchema() error {
  49. // Updating the schema can touch any and all parts of the database. Make
  50. // sure we do not run GC concurrently with schema migrations.
  51. db.gcMut.Lock()
  52. defer db.gcMut.Unlock()
  53. miscDB := NewMiscDataNamespace(db.Lowlevel)
  54. prevVersion, _, err := miscDB.Int64("dbVersion")
  55. if err != nil {
  56. return err
  57. }
  58. if prevVersion > dbVersion {
  59. err := &databaseDowngradeError{}
  60. if minSyncthingVersion, ok, dbErr := miscDB.String("dbMinSyncthingVersion"); dbErr != nil {
  61. return dbErr
  62. } else if ok {
  63. err.minSyncthingVersion = minSyncthingVersion
  64. }
  65. return err
  66. }
  67. if prevVersion == dbVersion {
  68. return nil
  69. }
  70. type migration struct {
  71. schemaVersion int64
  72. migration func(prevVersion int) error
  73. }
  74. var migrations = []migration{
  75. {1, db.updateSchema0to1},
  76. {2, db.updateSchema1to2},
  77. {3, db.updateSchema2to3},
  78. {5, db.updateSchemaTo5},
  79. {6, db.updateSchema5to6},
  80. {7, db.updateSchema6to7},
  81. {9, db.updateSchemaTo9},
  82. {10, db.updateSchemaTo10},
  83. {11, db.updateSchemaTo11},
  84. {13, db.updateSchemaTo13},
  85. {14, db.updateSchemaTo14},
  86. }
  87. for _, m := range migrations {
  88. if prevVersion < m.schemaVersion {
  89. l.Infof("Migrating database to schema version %d...", m.schemaVersion)
  90. if err := m.migration(int(prevVersion)); err != nil {
  91. return fmt.Errorf("failed migrating to version %v: %w", m.schemaVersion, err)
  92. }
  93. }
  94. }
  95. if err := miscDB.PutInt64("dbVersion", dbVersion); err != nil {
  96. return err
  97. }
  98. if err := miscDB.PutString("dbMinSyncthingVersion", dbMinSyncthingVersion); err != nil {
  99. return err
  100. }
  101. l.Infoln("Compacting database after migration...")
  102. return db.Compact()
  103. }
  104. func (db *schemaUpdater) updateSchema0to1(_ int) error {
  105. t, err := db.newReadWriteTransaction()
  106. if err != nil {
  107. return err
  108. }
  109. defer t.close()
  110. dbi, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  111. if err != nil {
  112. return err
  113. }
  114. defer dbi.Release()
  115. symlinkConv := 0
  116. changedFolders := make(map[string]struct{})
  117. ignAdded := 0
  118. var gk []byte
  119. ro := t.readOnlyTransaction
  120. for dbi.Next() {
  121. folder, ok := db.keyer.FolderFromDeviceFileKey(dbi.Key())
  122. if !ok {
  123. // not having the folder in the index is bad; delete and continue
  124. if err := t.Delete(dbi.Key()); err != nil {
  125. return err
  126. }
  127. continue
  128. }
  129. device, ok := db.keyer.DeviceFromDeviceFileKey(dbi.Key())
  130. if !ok {
  131. // not having the device in the index is bad; delete and continue
  132. if err := t.Delete(dbi.Key()); err != nil {
  133. return err
  134. }
  135. continue
  136. }
  137. name := db.keyer.NameFromDeviceFileKey(dbi.Key())
  138. // Remove files with absolute path (see #4799)
  139. if strings.HasPrefix(string(name), "/") {
  140. if _, ok := changedFolders[string(folder)]; !ok {
  141. changedFolders[string(folder)] = struct{}{}
  142. }
  143. if err := t.Delete(dbi.Key()); err != nil {
  144. return err
  145. }
  146. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  147. if err != nil {
  148. return err
  149. }
  150. fl, err := getGlobalVersionsByKeyBefore11(gk, ro)
  151. if backend.IsNotFound(err) {
  152. // Shouldn't happen, but not critical.
  153. continue
  154. } else if err != nil {
  155. return err
  156. }
  157. _, _ = fl.pop(device)
  158. if len(fl.Versions) == 0 {
  159. err = t.Delete(gk)
  160. } else {
  161. err = t.Put(gk, mustMarshal(&fl))
  162. }
  163. if err != nil {
  164. return err
  165. }
  166. continue
  167. }
  168. // Change SYMLINK_FILE and SYMLINK_DIRECTORY types to the current SYMLINK
  169. // type (previously SYMLINK_UNKNOWN). It does this for all devices, both
  170. // local and remote, and does not reset delta indexes. It shouldn't really
  171. // matter what the symlink type is, but this cleans it up for a possible
  172. // future when SYMLINK_FILE and SYMLINK_DIRECTORY are no longer understood.
  173. var f protocol.FileInfo
  174. if err := f.Unmarshal(dbi.Value()); err != nil {
  175. // probably can't happen
  176. continue
  177. }
  178. if f.Type == protocol.FileInfoTypeDeprecatedSymlinkDirectory || f.Type == protocol.FileInfoTypeDeprecatedSymlinkFile {
  179. f.Type = protocol.FileInfoTypeSymlink
  180. bs, err := f.Marshal()
  181. if err != nil {
  182. panic("can't happen: " + err.Error())
  183. }
  184. if err := t.Put(dbi.Key(), bs); err != nil {
  185. return err
  186. }
  187. symlinkConv++
  188. }
  189. // Add invalid files to global list
  190. if f.IsInvalid() {
  191. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  192. if err != nil {
  193. return err
  194. }
  195. fl, err := getGlobalVersionsByKeyBefore11(gk, ro)
  196. if err != nil && !backend.IsNotFound(err) {
  197. return err
  198. }
  199. i := 0
  200. i = sort.Search(len(fl.Versions), func(j int) bool {
  201. return fl.Versions[j].Invalid
  202. })
  203. for ; i < len(fl.Versions); i++ {
  204. ordering := fl.Versions[i].Version.Compare(f.Version)
  205. shouldInsert := ordering == protocol.Equal
  206. if !shouldInsert {
  207. shouldInsert, err = shouldInsertBefore(ordering, folder, fl.Versions[i].Device, true, f, ro)
  208. if err != nil {
  209. return err
  210. }
  211. }
  212. if shouldInsert {
  213. nv := FileVersionDeprecated{
  214. Device: device,
  215. Version: f.Version,
  216. Invalid: true,
  217. }
  218. fl.insertAt(i, nv)
  219. if err := t.Put(gk, mustMarshal(&fl)); err != nil {
  220. return err
  221. }
  222. if _, ok := changedFolders[string(folder)]; !ok {
  223. changedFolders[string(folder)] = struct{}{}
  224. }
  225. ignAdded++
  226. break
  227. }
  228. }
  229. }
  230. if err := t.Checkpoint(); err != nil {
  231. return err
  232. }
  233. }
  234. dbi.Release()
  235. if err != dbi.Error() {
  236. return err
  237. }
  238. return t.Commit()
  239. }
  240. // updateSchema1to2 introduces a sequenceKey->deviceKey bucket for local items
  241. // to allow iteration in sequence order (simplifies sending indexes).
  242. func (db *schemaUpdater) updateSchema1to2(_ int) error {
  243. t, err := db.newReadWriteTransaction()
  244. if err != nil {
  245. return err
  246. }
  247. defer t.close()
  248. var sk []byte
  249. var dk []byte
  250. for _, folderStr := range db.ListFolders() {
  251. folder := []byte(folderStr)
  252. var putErr error
  253. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, true, func(f protocol.FileIntf) bool {
  254. sk, putErr = db.keyer.GenerateSequenceKey(sk, folder, f.SequenceNo())
  255. if putErr != nil {
  256. return false
  257. }
  258. dk, putErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], []byte(f.FileName()))
  259. if putErr != nil {
  260. return false
  261. }
  262. putErr = t.Put(sk, dk)
  263. return putErr == nil
  264. })
  265. if putErr != nil {
  266. return putErr
  267. }
  268. if err != nil {
  269. return err
  270. }
  271. }
  272. return t.Commit()
  273. }
  274. // updateSchema2to3 introduces a needKey->nil bucket for locally needed files.
  275. func (db *schemaUpdater) updateSchema2to3(_ int) error {
  276. t, err := db.newReadWriteTransaction()
  277. if err != nil {
  278. return err
  279. }
  280. defer t.close()
  281. var nk []byte
  282. var dk []byte
  283. for _, folderStr := range db.ListFolders() {
  284. folder := []byte(folderStr)
  285. var putErr error
  286. err := withGlobalBefore11(folder, true, func(f protocol.FileIntf) bool {
  287. name := []byte(f.FileName())
  288. dk, putErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], name)
  289. if putErr != nil {
  290. return false
  291. }
  292. var v protocol.Vector
  293. haveFile, ok, err := t.getFileTrunc(dk, true)
  294. if err != nil {
  295. putErr = err
  296. return false
  297. }
  298. if ok {
  299. v = haveFile.FileVersion()
  300. }
  301. fv := FileVersionDeprecated{
  302. Version: f.FileVersion(),
  303. Invalid: f.IsInvalid(),
  304. Deleted: f.IsDeleted(),
  305. }
  306. if !needDeprecated(fv, ok, v) {
  307. return true
  308. }
  309. nk, putErr = t.keyer.GenerateNeedFileKey(nk, folder, []byte(f.FileName()))
  310. if putErr != nil {
  311. return false
  312. }
  313. putErr = t.Put(nk, nil)
  314. return putErr == nil
  315. }, t.readOnlyTransaction)
  316. if putErr != nil {
  317. return putErr
  318. }
  319. if err != nil {
  320. return err
  321. }
  322. }
  323. return t.Commit()
  324. }
  325. // updateSchemaTo5 resets the need bucket due to bugs existing in the v0.14.49
  326. // release candidates (dbVersion 3 and 4)
  327. // https://github.com/syncthing/syncthing/issues/5007
  328. // https://github.com/syncthing/syncthing/issues/5053
  329. func (db *schemaUpdater) updateSchemaTo5(prevVersion int) error {
  330. if prevVersion != 3 && prevVersion != 4 {
  331. return nil
  332. }
  333. t, err := db.newReadWriteTransaction()
  334. if err != nil {
  335. return err
  336. }
  337. var nk []byte
  338. for _, folderStr := range db.ListFolders() {
  339. nk, err = db.keyer.GenerateNeedFileKey(nk, []byte(folderStr), nil)
  340. if err != nil {
  341. return err
  342. }
  343. if err := t.deleteKeyPrefix(nk[:keyPrefixLen+keyFolderLen]); err != nil {
  344. return err
  345. }
  346. }
  347. if err := t.Commit(); err != nil {
  348. return err
  349. }
  350. return db.updateSchema2to3(2)
  351. }
  352. func (db *schemaUpdater) updateSchema5to6(_ int) error {
  353. // For every local file with the Invalid bit set, clear the Invalid bit and
  354. // set LocalFlags = FlagLocalIgnored.
  355. t, err := db.newReadWriteTransaction()
  356. if err != nil {
  357. return err
  358. }
  359. defer t.close()
  360. var dk []byte
  361. for _, folderStr := range db.ListFolders() {
  362. folder := []byte(folderStr)
  363. var iterErr error
  364. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, false, func(f protocol.FileIntf) bool {
  365. if !f.IsInvalid() {
  366. return true
  367. }
  368. fi := f.(protocol.FileInfo)
  369. fi.RawInvalid = false
  370. fi.LocalFlags = protocol.FlagLocalIgnored
  371. bs, _ := fi.Marshal()
  372. dk, iterErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], []byte(fi.Name))
  373. if iterErr != nil {
  374. return false
  375. }
  376. if iterErr = t.Put(dk, bs); iterErr != nil {
  377. return false
  378. }
  379. iterErr = t.Checkpoint()
  380. return iterErr == nil
  381. })
  382. if iterErr != nil {
  383. return iterErr
  384. }
  385. if err != nil {
  386. return err
  387. }
  388. }
  389. return t.Commit()
  390. }
  391. // updateSchema6to7 checks whether all currently locally needed files are really
  392. // needed and removes them if not.
  393. func (db *schemaUpdater) updateSchema6to7(_ int) error {
  394. t, err := db.newReadWriteTransaction()
  395. if err != nil {
  396. return err
  397. }
  398. defer t.close()
  399. var gk []byte
  400. var nk []byte
  401. for _, folderStr := range db.ListFolders() {
  402. folder := []byte(folderStr)
  403. var delErr error
  404. err := withNeedLocalBefore11(folder, false, func(f protocol.FileIntf) bool {
  405. name := []byte(f.FileName())
  406. gk, delErr = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  407. if delErr != nil {
  408. return false
  409. }
  410. svl, err := t.Get(gk)
  411. if err != nil {
  412. // If there is no global list, we hardly need it.
  413. key, err := t.keyer.GenerateNeedFileKey(nk, folder, name)
  414. if err != nil {
  415. delErr = err
  416. return false
  417. }
  418. delErr = t.Delete(key)
  419. return delErr == nil
  420. }
  421. var fl VersionListDeprecated
  422. err = fl.Unmarshal(svl)
  423. if err != nil {
  424. // This can't happen, but it's ignored everywhere else too,
  425. // so lets not act on it.
  426. return true
  427. }
  428. globalFV := FileVersionDeprecated{
  429. Version: f.FileVersion(),
  430. Invalid: f.IsInvalid(),
  431. Deleted: f.IsDeleted(),
  432. }
  433. if localFV, haveLocalFV := fl.Get(protocol.LocalDeviceID[:]); !needDeprecated(globalFV, haveLocalFV, localFV.Version) {
  434. key, err := t.keyer.GenerateNeedFileKey(nk, folder, name)
  435. if err != nil {
  436. delErr = err
  437. return false
  438. }
  439. delErr = t.Delete(key)
  440. }
  441. return delErr == nil
  442. }, t.readOnlyTransaction)
  443. if delErr != nil {
  444. return delErr
  445. }
  446. if err != nil {
  447. return err
  448. }
  449. if err := t.Checkpoint(); err != nil {
  450. return err
  451. }
  452. }
  453. return t.Commit()
  454. }
  455. func (db *schemaUpdater) updateSchemaTo9(prev int) error {
  456. // Loads and rewrites all files with blocks, to deduplicate block lists.
  457. t, err := db.newReadWriteTransaction()
  458. if err != nil {
  459. return err
  460. }
  461. defer t.close()
  462. if err := db.rewriteFiles(t); err != nil {
  463. return err
  464. }
  465. db.recordTime(indirectGCTimeKey)
  466. return t.Commit()
  467. }
  468. func (db *schemaUpdater) rewriteFiles(t readWriteTransaction) error {
  469. it, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  470. if err != nil {
  471. return err
  472. }
  473. defer it.Release()
  474. for it.Next() {
  475. intf, err := t.unmarshalTrunc(it.Value(), false)
  476. if backend.IsNotFound(err) {
  477. // Unmarshal error due to missing parts (block list), probably
  478. // due to a bad migration in a previous RC. Drop this key, as
  479. // getFile would anyway return this as a "not found" in the
  480. // normal flow of things.
  481. if err := t.Delete(it.Key()); err != nil {
  482. return err
  483. }
  484. continue
  485. } else if err != nil {
  486. return err
  487. }
  488. fi := intf.(protocol.FileInfo)
  489. if fi.Blocks == nil {
  490. continue
  491. }
  492. if err := t.putFile(it.Key(), fi); err != nil {
  493. return err
  494. }
  495. if err := t.Checkpoint(); err != nil {
  496. return err
  497. }
  498. }
  499. it.Release()
  500. return it.Error()
  501. }
  502. func (db *schemaUpdater) updateSchemaTo10(_ int) error {
  503. // Rewrites global lists to include a Deleted flag.
  504. t, err := db.newReadWriteTransaction()
  505. if err != nil {
  506. return err
  507. }
  508. defer t.close()
  509. var buf []byte
  510. for _, folderStr := range db.ListFolders() {
  511. folder := []byte(folderStr)
  512. buf, err = t.keyer.GenerateGlobalVersionKey(buf, folder, nil)
  513. if err != nil {
  514. return err
  515. }
  516. buf = globalVersionKey(buf).WithoutName()
  517. dbi, err := t.NewPrefixIterator(buf)
  518. if err != nil {
  519. return err
  520. }
  521. defer dbi.Release()
  522. for dbi.Next() {
  523. var vl VersionListDeprecated
  524. if err := vl.Unmarshal(dbi.Value()); err != nil {
  525. return err
  526. }
  527. changed := false
  528. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  529. for i, fv := range vl.Versions {
  530. buf, err = t.keyer.GenerateDeviceFileKey(buf, folder, fv.Device, name)
  531. if err != nil {
  532. return err
  533. }
  534. f, ok, err := t.getFileTrunc(buf, true)
  535. if !ok {
  536. return errEntryFromGlobalMissing
  537. }
  538. if err != nil {
  539. return err
  540. }
  541. if f.IsDeleted() {
  542. vl.Versions[i].Deleted = true
  543. changed = true
  544. }
  545. }
  546. if changed {
  547. if err := t.Put(dbi.Key(), mustMarshal(&vl)); err != nil {
  548. return err
  549. }
  550. if err := t.Checkpoint(); err != nil {
  551. return err
  552. }
  553. }
  554. }
  555. dbi.Release()
  556. }
  557. // Trigger metadata recalc
  558. if err := t.deleteKeyPrefix([]byte{KeyTypeFolderMeta}); err != nil {
  559. return err
  560. }
  561. return t.Commit()
  562. }
  563. func (db *schemaUpdater) updateSchemaTo11(_ int) error {
  564. // Populates block list map for every folder.
  565. t, err := db.newReadWriteTransaction()
  566. if err != nil {
  567. return err
  568. }
  569. defer t.close()
  570. var dk []byte
  571. for _, folderStr := range db.ListFolders() {
  572. folder := []byte(folderStr)
  573. var putErr error
  574. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, true, func(fi protocol.FileIntf) bool {
  575. f := fi.(FileInfoTruncated)
  576. if f.IsDirectory() || f.IsDeleted() || f.IsSymlink() || f.IsInvalid() || f.BlocksHash == nil {
  577. return true
  578. }
  579. name := []byte(f.FileName())
  580. dk, putErr = db.keyer.GenerateBlockListMapKey(dk, folder, f.BlocksHash, name)
  581. if putErr != nil {
  582. return false
  583. }
  584. if putErr = t.Put(dk, nil); putErr != nil {
  585. return false
  586. }
  587. putErr = t.Checkpoint()
  588. return putErr == nil
  589. })
  590. if putErr != nil {
  591. return putErr
  592. }
  593. if err != nil {
  594. return err
  595. }
  596. }
  597. return t.Commit()
  598. }
  599. func (db *schemaUpdater) updateSchemaTo13(prev int) error {
  600. // Loads and rewrites all files, to deduplicate version vectors.
  601. t, err := db.newReadWriteTransaction()
  602. if err != nil {
  603. return err
  604. }
  605. defer t.close()
  606. if prev < 12 {
  607. if err := db.rewriteFiles(t); err != nil {
  608. return err
  609. }
  610. }
  611. if err := db.rewriteGlobals(t); err != nil {
  612. return err
  613. }
  614. return t.Commit()
  615. }
  616. func (db *schemaUpdater) updateSchemaTo14(_ int) error {
  617. // Checks for missing blocks and marks those entries as requiring a
  618. // rehash/being invalid. The db is checked/repaired afterwards, i.e.
  619. // no care is taken to get metadata and sequences right.
  620. // If the corresponding files changed on disk compared to the global
  621. // version, this will cause a conflict.
  622. var key, gk []byte
  623. for _, folderStr := range db.ListFolders() {
  624. folder := []byte(folderStr)
  625. meta := newMetadataTracker(db.keyer)
  626. meta.counts.Created = 0 // Recalculate metadata afterwards
  627. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  628. if err != nil {
  629. return err
  630. }
  631. defer t.close()
  632. key, err = t.keyer.GenerateDeviceFileKey(key, folder, protocol.LocalDeviceID[:], nil)
  633. it, err := t.NewPrefixIterator(key)
  634. if err != nil {
  635. return err
  636. }
  637. defer it.Release()
  638. for it.Next() {
  639. var fi protocol.FileInfo
  640. if err := fi.Unmarshal(it.Value()); err != nil {
  641. return err
  642. }
  643. if len(fi.Blocks) > 0 || len(fi.BlocksHash) == 0 {
  644. continue
  645. }
  646. key = t.keyer.GenerateBlockListKey(key, fi.BlocksHash)
  647. _, err := t.Get(key)
  648. if err == nil {
  649. continue
  650. }
  651. fi.SetMustRescan(protocol.LocalDeviceID.Short())
  652. if err = t.putFile(it.Key(), fi); err != nil {
  653. return err
  654. }
  655. gk, err = t.keyer.GenerateGlobalVersionKey(gk, folder, []byte(fi.Name))
  656. if err != nil {
  657. return err
  658. }
  659. key, _, err = t.updateGlobal(gk, key, folder, protocol.LocalDeviceID[:], fi, meta)
  660. if err != nil {
  661. return err
  662. }
  663. }
  664. it.Release()
  665. if err = t.Commit(); err != nil {
  666. return err
  667. }
  668. t.close()
  669. }
  670. return nil
  671. }
  672. func (db *schemaUpdater) rewriteGlobals(t readWriteTransaction) error {
  673. it, err := t.NewPrefixIterator([]byte{KeyTypeGlobal})
  674. if err != nil {
  675. return err
  676. }
  677. defer it.Release()
  678. for it.Next() {
  679. var vl VersionListDeprecated
  680. if err := vl.Unmarshal(it.Value()); err != nil {
  681. // If we crashed during an earlier migration, some version
  682. // lists might already be in the new format: Skip those.
  683. var nvl VersionList
  684. if nerr := nvl.Unmarshal(it.Value()); nerr == nil {
  685. continue
  686. }
  687. return err
  688. }
  689. if len(vl.Versions) == 0 {
  690. if err := t.Delete(it.Key()); err != nil {
  691. return err
  692. }
  693. }
  694. newVl, err := convertVersionList(vl)
  695. if err != nil {
  696. return err
  697. }
  698. if err := t.Put(it.Key(), mustMarshal(&newVl)); err != nil {
  699. return err
  700. }
  701. if err := t.Checkpoint(); err != nil {
  702. return err
  703. }
  704. }
  705. it.Release()
  706. return it.Error()
  707. }
  708. func convertVersionList(vl VersionListDeprecated) (VersionList, error) {
  709. var newVl VersionList
  710. var newPos, oldPos int
  711. var lastVersion protocol.Vector
  712. for _, fv := range vl.Versions {
  713. if fv.Invalid {
  714. break
  715. }
  716. oldPos++
  717. if len(newVl.RawVersions) > 0 && lastVersion.Equal(fv.Version) {
  718. newVl.RawVersions[newPos].Devices = append(newVl.RawVersions[newPos].Devices, fv.Device)
  719. continue
  720. }
  721. newPos = len(newVl.RawVersions)
  722. newVl.RawVersions = append(newVl.RawVersions, newFileVersion(fv.Device, fv.Version, false, fv.Deleted))
  723. lastVersion = fv.Version
  724. }
  725. if oldPos == len(vl.Versions) {
  726. return newVl, nil
  727. }
  728. if len(newVl.RawVersions) == 0 {
  729. fv := vl.Versions[oldPos]
  730. newVl.RawVersions = []FileVersion{newFileVersion(fv.Device, fv.Version, true, fv.Deleted)}
  731. oldPos++
  732. }
  733. newPos = 0
  734. outer:
  735. for _, fv := range vl.Versions[oldPos:] {
  736. for _, nfv := range newVl.RawVersions[newPos:] {
  737. switch nfv.Version.Compare(fv.Version) {
  738. case protocol.Equal:
  739. newVl.RawVersions[newPos].InvalidDevices = append(newVl.RawVersions[newPos].InvalidDevices, fv.Device)
  740. lastVersion = fv.Version
  741. continue outer
  742. case protocol.Lesser:
  743. newVl.insertAt(newPos, newFileVersion(fv.Device, fv.Version, true, fv.Deleted))
  744. lastVersion = fv.Version
  745. continue outer
  746. case protocol.ConcurrentLesser, protocol.ConcurrentGreater:
  747. // The version is invalid, i.e. it looses anyway,
  748. // no need to check/get the conflicting file.
  749. }
  750. newPos++
  751. }
  752. // Couldn't insert into any existing versions
  753. newVl.RawVersions = append(newVl.RawVersions, newFileVersion(fv.Device, fv.Version, true, fv.Deleted))
  754. lastVersion = fv.Version
  755. newPos++
  756. }
  757. return newVl, nil
  758. }
  759. func getGlobalVersionsByKeyBefore11(key []byte, t readOnlyTransaction) (VersionListDeprecated, error) {
  760. bs, err := t.Get(key)
  761. if err != nil {
  762. return VersionListDeprecated{}, err
  763. }
  764. var vl VersionListDeprecated
  765. if err := vl.Unmarshal(bs); err != nil {
  766. return VersionListDeprecated{}, err
  767. }
  768. return vl, nil
  769. }
  770. func withGlobalBefore11(folder []byte, truncate bool, fn Iterator, t readOnlyTransaction) error {
  771. key, err := t.keyer.GenerateGlobalVersionKey(nil, folder, nil)
  772. if err != nil {
  773. return err
  774. }
  775. dbi, err := t.NewPrefixIterator(key)
  776. if err != nil {
  777. return err
  778. }
  779. defer dbi.Release()
  780. var dk []byte
  781. for dbi.Next() {
  782. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  783. var vl VersionListDeprecated
  784. if err := vl.Unmarshal(dbi.Value()); err != nil {
  785. return err
  786. }
  787. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, vl.Versions[0].Device, name)
  788. if err != nil {
  789. return err
  790. }
  791. f, ok, err := t.getFileTrunc(dk, truncate)
  792. if err != nil {
  793. return err
  794. }
  795. if !ok {
  796. continue
  797. }
  798. if !fn(f) {
  799. return nil
  800. }
  801. }
  802. if err != nil {
  803. return err
  804. }
  805. return dbi.Error()
  806. }
  807. func withNeedLocalBefore11(folder []byte, truncate bool, fn Iterator, t readOnlyTransaction) error {
  808. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  809. if err != nil {
  810. return err
  811. }
  812. dbi, err := t.NewPrefixIterator(key.WithoutName())
  813. if err != nil {
  814. return err
  815. }
  816. defer dbi.Release()
  817. var keyBuf []byte
  818. var f protocol.FileIntf
  819. var ok bool
  820. for dbi.Next() {
  821. keyBuf, f, ok, err = getGlobalBefore11(keyBuf, folder, t.keyer.NameFromGlobalVersionKey(dbi.Key()), truncate, t)
  822. if err != nil {
  823. return err
  824. }
  825. if !ok {
  826. continue
  827. }
  828. if !fn(f) {
  829. return nil
  830. }
  831. }
  832. return dbi.Error()
  833. }
  834. func getGlobalBefore11(keyBuf, folder, file []byte, truncate bool, t readOnlyTransaction) ([]byte, protocol.FileIntf, bool, error) {
  835. keyBuf, err := t.keyer.GenerateGlobalVersionKey(keyBuf, folder, file)
  836. if err != nil {
  837. return nil, nil, false, err
  838. }
  839. bs, err := t.Get(keyBuf)
  840. if backend.IsNotFound(err) {
  841. return keyBuf, nil, false, nil
  842. } else if err != nil {
  843. return nil, nil, false, err
  844. }
  845. var vl VersionListDeprecated
  846. if err := vl.Unmarshal(bs); err != nil {
  847. return nil, nil, false, err
  848. }
  849. if len(vl.Versions) == 0 {
  850. return nil, nil, false, nil
  851. }
  852. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, vl.Versions[0].Device, file)
  853. if err != nil {
  854. return nil, nil, false, err
  855. }
  856. fi, ok, err := t.getFileTrunc(keyBuf, truncate)
  857. if err != nil || !ok {
  858. return keyBuf, nil, false, err
  859. }
  860. return keyBuf, fi, true, nil
  861. }
  862. func (vl *VersionListDeprecated) String() string {
  863. var b bytes.Buffer
  864. var id protocol.DeviceID
  865. b.WriteString("{")
  866. for i, v := range vl.Versions {
  867. if i > 0 {
  868. b.WriteString(", ")
  869. }
  870. copy(id[:], v.Device)
  871. fmt.Fprintf(&b, "{%v, %v}", v.Version, id)
  872. }
  873. b.WriteString("}")
  874. return b.String()
  875. }
  876. func (vl *VersionListDeprecated) pop(device []byte) (FileVersionDeprecated, int) {
  877. for i, v := range vl.Versions {
  878. if bytes.Equal(v.Device, device) {
  879. vl.Versions = append(vl.Versions[:i], vl.Versions[i+1:]...)
  880. return v, i
  881. }
  882. }
  883. return FileVersionDeprecated{}, -1
  884. }
  885. func (vl *VersionListDeprecated) Get(device []byte) (FileVersionDeprecated, bool) {
  886. for _, v := range vl.Versions {
  887. if bytes.Equal(v.Device, device) {
  888. return v, true
  889. }
  890. }
  891. return FileVersionDeprecated{}, false
  892. }
  893. func (vl *VersionListDeprecated) insertAt(i int, v FileVersionDeprecated) {
  894. vl.Versions = append(vl.Versions, FileVersionDeprecated{})
  895. copy(vl.Versions[i+1:], vl.Versions[i:])
  896. vl.Versions[i] = v
  897. }
  898. func needDeprecated(global FileVersionDeprecated, haveLocal bool, localVersion protocol.Vector) bool {
  899. // We never need an invalid file.
  900. if global.Invalid {
  901. return false
  902. }
  903. // We don't need a deleted file if we don't have it.
  904. if global.Deleted && !haveLocal {
  905. return false
  906. }
  907. // We don't need the global file if we already have the same version.
  908. if haveLocal && localVersion.GreaterEqual(global.Version) {
  909. return false
  910. }
  911. return true
  912. }