transactions.go 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. // Copyright (C) 2014 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. "github.com/syncthing/syncthing/lib/osutil"
  11. "github.com/syncthing/syncthing/lib/db/backend"
  12. "github.com/syncthing/syncthing/lib/protocol"
  13. )
  14. var errEntryFromGlobalMissing = errors.New("device present in global list but missing as device/fileinfo entry")
  15. // A readOnlyTransaction represents a database snapshot.
  16. type readOnlyTransaction struct {
  17. backend.ReadTransaction
  18. keyer keyer
  19. }
  20. func (db *Lowlevel) newReadOnlyTransaction() (readOnlyTransaction, error) {
  21. tran, err := db.NewReadTransaction()
  22. if err != nil {
  23. return readOnlyTransaction{}, err
  24. }
  25. return readOnlyTransaction{
  26. ReadTransaction: tran,
  27. keyer: db.keyer,
  28. }, nil
  29. }
  30. func (t readOnlyTransaction) close() {
  31. t.Release()
  32. }
  33. func (t readOnlyTransaction) getFile(folder, device, file []byte) (protocol.FileInfo, bool, error) {
  34. key, err := t.keyer.GenerateDeviceFileKey(nil, folder, device, file)
  35. if err != nil {
  36. return protocol.FileInfo{}, false, err
  37. }
  38. return t.getFileByKey(key)
  39. }
  40. func (t readOnlyTransaction) getFileByKey(key []byte) (protocol.FileInfo, bool, error) {
  41. f, ok, err := t.getFileTrunc(key, false)
  42. if err != nil || !ok {
  43. return protocol.FileInfo{}, false, err
  44. }
  45. return f.(protocol.FileInfo), true, nil
  46. }
  47. func (t readOnlyTransaction) getFileTrunc(key []byte, trunc bool) (FileIntf, bool, error) {
  48. bs, err := t.Get(key)
  49. if backend.IsNotFound(err) {
  50. return nil, false, nil
  51. }
  52. if err != nil {
  53. return nil, false, err
  54. }
  55. f, err := t.unmarshalTrunc(bs, trunc)
  56. if backend.IsNotFound(err) {
  57. return nil, false, nil
  58. }
  59. if err != nil {
  60. return nil, false, err
  61. }
  62. return f, true, nil
  63. }
  64. func (t readOnlyTransaction) unmarshalTrunc(bs []byte, trunc bool) (FileIntf, error) {
  65. if trunc {
  66. var tf FileInfoTruncated
  67. err := tf.Unmarshal(bs)
  68. if err != nil {
  69. return nil, err
  70. }
  71. if err := t.fillTruncated(&tf); err != nil {
  72. return nil, err
  73. }
  74. return tf, nil
  75. }
  76. var fi protocol.FileInfo
  77. if err := fi.Unmarshal(bs); err != nil {
  78. return nil, err
  79. }
  80. if err := t.fillFileInfo(&fi); err != nil {
  81. return nil, err
  82. }
  83. return fi, nil
  84. }
  85. // fillFileInfo follows the (possible) indirection of blocks and version
  86. // vector and fills it out.
  87. func (t readOnlyTransaction) fillFileInfo(fi *protocol.FileInfo) error {
  88. var key []byte
  89. if len(fi.Blocks) == 0 && len(fi.BlocksHash) != 0 {
  90. // The blocks list is indirected and we need to load it.
  91. key = t.keyer.GenerateBlockListKey(key, fi.BlocksHash)
  92. bs, err := t.Get(key)
  93. if err != nil {
  94. return err
  95. }
  96. var bl BlockList
  97. if err := bl.Unmarshal(bs); err != nil {
  98. return err
  99. }
  100. fi.Blocks = bl.Blocks
  101. }
  102. if len(fi.VersionHash) != 0 {
  103. key = t.keyer.GenerateVersionKey(key, fi.VersionHash)
  104. bs, err := t.Get(key)
  105. if err != nil {
  106. return err
  107. }
  108. var v protocol.Vector
  109. if err := v.Unmarshal(bs); err != nil {
  110. return err
  111. }
  112. fi.Version = v
  113. }
  114. return nil
  115. }
  116. // fillTruncated follows the (possible) indirection of version vector and
  117. // fills it.
  118. func (t readOnlyTransaction) fillTruncated(fi *FileInfoTruncated) error {
  119. var key []byte
  120. if len(fi.VersionHash) == 0 {
  121. return nil
  122. }
  123. key = t.keyer.GenerateVersionKey(key, fi.VersionHash)
  124. bs, err := t.Get(key)
  125. if err != nil {
  126. return err
  127. }
  128. var v protocol.Vector
  129. if err := v.Unmarshal(bs); err != nil {
  130. return err
  131. }
  132. fi.Version = v
  133. return nil
  134. }
  135. func (t readOnlyTransaction) getGlobalVersions(keyBuf, folder, file []byte) (VersionList, error) {
  136. var err error
  137. keyBuf, err = t.keyer.GenerateGlobalVersionKey(keyBuf, folder, file)
  138. if err != nil {
  139. return VersionList{}, err
  140. }
  141. return t.getGlobalVersionsByKey(keyBuf)
  142. }
  143. func (t readOnlyTransaction) getGlobalVersionsByKey(key []byte) (VersionList, error) {
  144. bs, err := t.Get(key)
  145. if err != nil {
  146. return VersionList{}, err
  147. }
  148. var vl VersionList
  149. if err := vl.Unmarshal(bs); err != nil {
  150. return VersionList{}, err
  151. }
  152. return vl, nil
  153. }
  154. func (t readOnlyTransaction) getGlobal(keyBuf, folder, file []byte, truncate bool) ([]byte, FileIntf, bool, error) {
  155. vl, err := t.getGlobalVersions(keyBuf, folder, file)
  156. if backend.IsNotFound(err) {
  157. return keyBuf, nil, false, nil
  158. } else if err != nil {
  159. return nil, nil, false, err
  160. }
  161. if len(vl.Versions) == 0 {
  162. return nil, nil, false, nil
  163. }
  164. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, vl.Versions[0].Device, file)
  165. if err != nil {
  166. return nil, nil, false, err
  167. }
  168. fi, ok, err := t.getFileTrunc(keyBuf, truncate)
  169. if err != nil || !ok {
  170. return keyBuf, nil, false, err
  171. }
  172. return keyBuf, fi, true, nil
  173. }
  174. func (t *readOnlyTransaction) withHave(folder, device, prefix []byte, truncate bool, fn Iterator) error {
  175. if len(prefix) > 0 {
  176. unslashedPrefix := prefix
  177. if bytes.HasSuffix(prefix, []byte{'/'}) {
  178. unslashedPrefix = unslashedPrefix[:len(unslashedPrefix)-1]
  179. } else {
  180. prefix = append(prefix, '/')
  181. }
  182. key, err := t.keyer.GenerateDeviceFileKey(nil, folder, device, unslashedPrefix)
  183. if err != nil {
  184. return err
  185. }
  186. if f, ok, err := t.getFileTrunc(key, truncate); err != nil {
  187. return err
  188. } else if ok && !fn(f) {
  189. return nil
  190. }
  191. }
  192. key, err := t.keyer.GenerateDeviceFileKey(nil, folder, device, prefix)
  193. if err != nil {
  194. return err
  195. }
  196. dbi, err := t.NewPrefixIterator(key)
  197. if err != nil {
  198. return err
  199. }
  200. defer dbi.Release()
  201. for dbi.Next() {
  202. name := t.keyer.NameFromDeviceFileKey(dbi.Key())
  203. if len(prefix) > 0 && !bytes.HasPrefix(name, prefix) {
  204. return nil
  205. }
  206. f, err := t.unmarshalTrunc(dbi.Value(), truncate)
  207. if err != nil {
  208. l.Debugln("unmarshal error:", err)
  209. continue
  210. }
  211. if !fn(f) {
  212. return nil
  213. }
  214. }
  215. return dbi.Error()
  216. }
  217. func (t *readOnlyTransaction) withHaveSequence(folder []byte, startSeq int64, fn Iterator) error {
  218. first, err := t.keyer.GenerateSequenceKey(nil, folder, startSeq)
  219. if err != nil {
  220. return err
  221. }
  222. last, err := t.keyer.GenerateSequenceKey(nil, folder, maxInt64)
  223. if err != nil {
  224. return err
  225. }
  226. dbi, err := t.NewRangeIterator(first, last)
  227. if err != nil {
  228. return err
  229. }
  230. defer dbi.Release()
  231. for dbi.Next() {
  232. f, ok, err := t.getFileByKey(dbi.Value())
  233. if err != nil {
  234. return err
  235. }
  236. if !ok {
  237. l.Debugln("missing file for sequence number", t.keyer.SequenceFromSequenceKey(dbi.Key()))
  238. continue
  239. }
  240. if shouldDebug() {
  241. if seq := t.keyer.SequenceFromSequenceKey(dbi.Key()); f.Sequence != seq {
  242. l.Warnf("Sequence index corruption (folder %v, file %v): sequence %d != expected %d", string(folder), f.Name, f.Sequence, seq)
  243. panic("sequence index corruption")
  244. }
  245. }
  246. if !fn(f) {
  247. return nil
  248. }
  249. }
  250. return dbi.Error()
  251. }
  252. func (t *readOnlyTransaction) withGlobal(folder, prefix []byte, truncate bool, fn Iterator) error {
  253. if len(prefix) > 0 {
  254. unslashedPrefix := prefix
  255. if bytes.HasSuffix(prefix, []byte{'/'}) {
  256. unslashedPrefix = unslashedPrefix[:len(unslashedPrefix)-1]
  257. } else {
  258. prefix = append(prefix, '/')
  259. }
  260. if _, f, ok, err := t.getGlobal(nil, folder, unslashedPrefix, truncate); err != nil {
  261. return err
  262. } else if ok && !fn(f) {
  263. return nil
  264. }
  265. }
  266. key, err := t.keyer.GenerateGlobalVersionKey(nil, folder, prefix)
  267. if err != nil {
  268. return err
  269. }
  270. dbi, err := t.NewPrefixIterator(key)
  271. if err != nil {
  272. return err
  273. }
  274. defer dbi.Release()
  275. var dk []byte
  276. for dbi.Next() {
  277. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  278. if len(prefix) > 0 && !bytes.HasPrefix(name, prefix) {
  279. return nil
  280. }
  281. var vl VersionList
  282. if err := vl.Unmarshal(dbi.Value()); err != nil {
  283. return err
  284. }
  285. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, vl.Versions[0].Device, name)
  286. if err != nil {
  287. return err
  288. }
  289. f, ok, err := t.getFileTrunc(dk, truncate)
  290. if err != nil {
  291. return err
  292. }
  293. if !ok {
  294. continue
  295. }
  296. if !fn(f) {
  297. return nil
  298. }
  299. }
  300. if err != nil {
  301. return err
  302. }
  303. return dbi.Error()
  304. }
  305. func (t *readOnlyTransaction) withBlocksHash(folder, hash []byte, iterator Iterator) error {
  306. key, err := t.keyer.GenerateBlockListMapKey(nil, folder, hash, nil)
  307. if err != nil {
  308. return err
  309. }
  310. iter, err := t.NewPrefixIterator(key)
  311. if err != nil {
  312. return err
  313. }
  314. defer iter.Release()
  315. for iter.Next() {
  316. file := string(t.keyer.NameFromBlockListMapKey(iter.Key()))
  317. f, ok, err := t.getFile(folder, protocol.LocalDeviceID[:], []byte(osutil.NormalizedFilename(file)))
  318. if err != nil {
  319. return err
  320. }
  321. if !ok {
  322. continue
  323. }
  324. f.Name = osutil.NativeFilename(f.Name)
  325. if !bytes.Equal(f.BlocksHash, hash) {
  326. l.Warnf("Mismatching block map list hashes: got %x expected %x", f.BlocksHash, hash)
  327. continue
  328. }
  329. if f.IsDeleted() || f.IsInvalid() || f.IsDirectory() || f.IsSymlink() {
  330. l.Warnf("Found something of unexpected type in block list map: %s", f)
  331. continue
  332. }
  333. if !iterator(f) {
  334. break
  335. }
  336. }
  337. return iter.Error()
  338. }
  339. func (t *readOnlyTransaction) availability(folder, file []byte) ([]protocol.DeviceID, error) {
  340. vl, err := t.getGlobalVersions(nil, folder, file)
  341. if backend.IsNotFound(err) {
  342. return nil, nil
  343. }
  344. if err != nil {
  345. return nil, err
  346. }
  347. var devices []protocol.DeviceID
  348. for _, v := range vl.Versions {
  349. if !v.Version.Equal(vl.Versions[0].Version) {
  350. break
  351. }
  352. if v.Invalid {
  353. continue
  354. }
  355. n := protocol.DeviceIDFromBytes(v.Device)
  356. devices = append(devices, n)
  357. }
  358. return devices, nil
  359. }
  360. func (t *readOnlyTransaction) withNeed(folder, device []byte, truncate bool, fn Iterator) error {
  361. if bytes.Equal(device, protocol.LocalDeviceID[:]) {
  362. return t.withNeedLocal(folder, truncate, fn)
  363. }
  364. key, err := t.keyer.GenerateGlobalVersionKey(nil, folder, nil)
  365. if err != nil {
  366. return err
  367. }
  368. dbi, err := t.NewPrefixIterator(key.WithoutName())
  369. if err != nil {
  370. return err
  371. }
  372. defer dbi.Release()
  373. var dk []byte
  374. devID := protocol.DeviceIDFromBytes(device)
  375. for dbi.Next() {
  376. var vl VersionList
  377. if err := vl.Unmarshal(dbi.Value()); err != nil {
  378. return err
  379. }
  380. globalFV := vl.Versions[0]
  381. haveFV, have := vl.Get(device)
  382. if !need(globalFV, have, haveFV.Version) {
  383. continue
  384. }
  385. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  386. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, globalFV.Device, name)
  387. if err != nil {
  388. return err
  389. }
  390. gf, ok, err := t.getFileTrunc(dk, truncate)
  391. if err != nil {
  392. return err
  393. }
  394. if !ok {
  395. return errEntryFromGlobalMissing
  396. }
  397. l.Debugf("need folder=%q device=%v name=%q have=%v invalid=%v haveV=%v globalV=%v globalDev=%v", folder, devID, name, have, haveFV.Invalid, haveFV.Version, globalFV.Version, globalFV.Device)
  398. if !fn(gf) {
  399. return dbi.Error()
  400. }
  401. }
  402. return dbi.Error()
  403. }
  404. func (t *readOnlyTransaction) withNeedLocal(folder []byte, truncate bool, fn Iterator) error {
  405. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  406. if err != nil {
  407. return err
  408. }
  409. dbi, err := t.NewPrefixIterator(key.WithoutName())
  410. if err != nil {
  411. return err
  412. }
  413. defer dbi.Release()
  414. var keyBuf []byte
  415. var f FileIntf
  416. var ok bool
  417. for dbi.Next() {
  418. keyBuf, f, ok, err = t.getGlobal(keyBuf, folder, t.keyer.NameFromGlobalVersionKey(dbi.Key()), truncate)
  419. if err != nil {
  420. return err
  421. }
  422. if !ok {
  423. continue
  424. }
  425. if !fn(f) {
  426. return nil
  427. }
  428. }
  429. return dbi.Error()
  430. }
  431. // A readWriteTransaction is a readOnlyTransaction plus a batch for writes.
  432. // The batch will be committed on close() or by checkFlush() if it exceeds the
  433. // batch size.
  434. type readWriteTransaction struct {
  435. backend.WriteTransaction
  436. readOnlyTransaction
  437. }
  438. func (db *Lowlevel) newReadWriteTransaction() (readWriteTransaction, error) {
  439. tran, err := db.NewWriteTransaction()
  440. if err != nil {
  441. return readWriteTransaction{}, err
  442. }
  443. return readWriteTransaction{
  444. WriteTransaction: tran,
  445. readOnlyTransaction: readOnlyTransaction{
  446. ReadTransaction: tran,
  447. keyer: db.keyer,
  448. },
  449. }, nil
  450. }
  451. func (t readWriteTransaction) Commit() error {
  452. t.readOnlyTransaction.close()
  453. return t.WriteTransaction.Commit()
  454. }
  455. func (t readWriteTransaction) close() {
  456. t.readOnlyTransaction.close()
  457. t.WriteTransaction.Release()
  458. }
  459. // putFile stores a file in the database, taking care of indirected fields.
  460. // Set the truncated flag when putting a file that deliberatly can have an
  461. // empty block list but a non-empty block list hash. This should normally be
  462. // false.
  463. func (t readWriteTransaction) putFile(fkey []byte, fi protocol.FileInfo, truncated bool) error {
  464. var bkey []byte
  465. // Always set the blocks hash when there are blocks. Leave the blocks
  466. // hash alone when there are no blocks and we might be putting a
  467. // "truncated" FileInfo (no blocks, but the hash reference is live).
  468. if len(fi.Blocks) > 0 {
  469. fi.BlocksHash = protocol.BlocksHash(fi.Blocks)
  470. } else if !truncated {
  471. fi.BlocksHash = nil
  472. }
  473. // Indirect the blocks if the block list is large enough.
  474. if len(fi.Blocks) > blocksIndirectionCutoff {
  475. bkey = t.keyer.GenerateBlockListKey(bkey, fi.BlocksHash)
  476. if _, err := t.Get(bkey); backend.IsNotFound(err) {
  477. // Marshal the block list and save it
  478. blocksBs := mustMarshal(&BlockList{Blocks: fi.Blocks})
  479. if err := t.Put(bkey, blocksBs); err != nil {
  480. return err
  481. }
  482. } else if err != nil {
  483. return err
  484. }
  485. fi.Blocks = nil
  486. }
  487. // Indirect the version vector if it's large enough.
  488. if len(fi.Version.Counters) > versionIndirectionCutoff {
  489. fi.VersionHash = protocol.VectorHash(fi.Version)
  490. bkey = t.keyer.GenerateVersionKey(bkey, fi.VersionHash)
  491. if _, err := t.Get(bkey); backend.IsNotFound(err) {
  492. // Marshal the version vector and save it
  493. versionBs := mustMarshal(&fi.Version)
  494. if err := t.Put(bkey, versionBs); err != nil {
  495. return err
  496. }
  497. } else if err != nil {
  498. return err
  499. }
  500. fi.Version = protocol.Vector{}
  501. } else {
  502. fi.VersionHash = nil
  503. }
  504. fiBs := mustMarshal(&fi)
  505. return t.Put(fkey, fiBs)
  506. }
  507. // updateGlobal adds this device+version to the version list for the given
  508. // file. If the device is already present in the list, the version is updated.
  509. // If the file does not have an entry in the global list, it is created.
  510. func (t readWriteTransaction) updateGlobal(gk, keyBuf, folder, device []byte, file protocol.FileInfo, meta *metadataTracker) ([]byte, bool, error) {
  511. deviceID := protocol.DeviceIDFromBytes(device)
  512. l.Debugf("update global; folder=%q device=%v file=%q version=%v invalid=%v", folder, deviceID, file.Name, file.Version, file.IsInvalid())
  513. fl, err := t.getGlobalVersionsByKey(gk)
  514. if err != nil && !backend.IsNotFound(err) {
  515. return nil, false, err
  516. }
  517. fl, removedFV, removedAt, insertedAt, err := fl.update(folder, device, file, t.readOnlyTransaction)
  518. if err != nil {
  519. return nil, false, err
  520. }
  521. name := []byte(file.Name)
  522. l.Debugf(`new global for "%v" after update: %v`, file.Name, fl)
  523. if err := t.Put(gk, mustMarshal(&fl)); err != nil {
  524. return nil, false, err
  525. }
  526. // Only load those from db if actually needed
  527. var gotGlobal, gotOldGlobal bool
  528. var global, oldGlobal FileIntf
  529. globalFV := fl.Versions[0]
  530. var oldGlobalFV FileVersion
  531. haveOldGlobal := false
  532. globalUnaffected := removedAt != 0 && insertedAt != 0
  533. if globalUnaffected {
  534. oldGlobalFV = globalFV
  535. haveOldGlobal = true
  536. } else {
  537. if removedAt == 0 {
  538. oldGlobalFV = removedFV
  539. haveOldGlobal = true
  540. } else if len(fl.Versions) > 1 {
  541. // The previous newest version is now at index 1
  542. oldGlobalFV = fl.Versions[1]
  543. haveOldGlobal = true
  544. }
  545. }
  546. // Check the need of the device that was updated
  547. // Must happen before updating global meta: If this is the first
  548. // item from this device, it will be initialized with the global state.
  549. needBefore := false
  550. if haveOldGlobal {
  551. needBefore = need(oldGlobalFV, removedAt >= 0, removedFV.Version)
  552. }
  553. needNow := need(globalFV, true, fl.Versions[insertedAt].Version)
  554. if needBefore {
  555. if oldGlobal, err = t.updateGlobalGetOldGlobal(keyBuf, folder, name, oldGlobalFV); err != nil {
  556. return nil, false, err
  557. }
  558. gotOldGlobal = true
  559. meta.removeNeeded(deviceID, oldGlobal)
  560. if !needNow && bytes.Equal(device, protocol.LocalDeviceID[:]) {
  561. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, false); err != nil {
  562. return nil, false, err
  563. }
  564. }
  565. }
  566. if needNow {
  567. if global, err = t.updateGlobalGetGlobal(keyBuf, folder, name, file, insertedAt, fl); err != nil {
  568. return nil, false, err
  569. }
  570. gotGlobal = true
  571. meta.addNeeded(deviceID, global)
  572. if !needBefore && bytes.Equal(device, protocol.LocalDeviceID[:]) {
  573. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, true); err != nil {
  574. return nil, false, err
  575. }
  576. }
  577. }
  578. // Update global size counter if necessary
  579. // Necessary here means the first item in the global list was changed,
  580. // even if both new and old are invalid, due to potential change in
  581. // LocalFlags.
  582. // Neither the global state nor the needs of any devices, except the one
  583. // updated, changed.
  584. if globalUnaffected {
  585. return keyBuf, true, nil
  586. }
  587. // Remove the old global from the global size counter
  588. if haveOldGlobal {
  589. if !gotOldGlobal {
  590. if oldGlobal, err = t.updateGlobalGetOldGlobal(keyBuf, folder, name, oldGlobalFV); err != nil {
  591. return nil, false, err
  592. }
  593. gotOldGlobal = true
  594. }
  595. meta.removeFile(protocol.GlobalDeviceID, oldGlobal)
  596. }
  597. // Add the new global to the global size counter
  598. if !gotGlobal {
  599. if global, err = t.updateGlobalGetGlobal(keyBuf, folder, name, file, insertedAt, fl); err != nil {
  600. return nil, false, err
  601. }
  602. gotGlobal = true
  603. }
  604. meta.addFile(protocol.GlobalDeviceID, global)
  605. // If global changed, but both the new and old are invalid, noone needed
  606. // the file before and now -> nothing to do.
  607. if global.IsInvalid() && (!haveOldGlobal || oldGlobal.IsInvalid()) {
  608. return keyBuf, true, nil
  609. }
  610. // check for local (if not already done before)
  611. if !bytes.Equal(device, protocol.LocalDeviceID[:]) {
  612. localFV, haveLocal := fl.Get(protocol.LocalDeviceID[:])
  613. needBefore := false
  614. if haveOldGlobal {
  615. needBefore = need(oldGlobalFV, haveLocal, localFV.Version)
  616. }
  617. needNow := need(globalFV, haveLocal, localFV.Version)
  618. if needBefore {
  619. meta.removeNeeded(protocol.LocalDeviceID, oldGlobal)
  620. if !needNow {
  621. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, false); err != nil {
  622. return nil, false, err
  623. }
  624. }
  625. }
  626. if need(globalFV, haveLocal, localFV.Version) {
  627. meta.addNeeded(protocol.LocalDeviceID, global)
  628. if !needBefore {
  629. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, true); err != nil {
  630. return nil, false, err
  631. }
  632. }
  633. }
  634. }
  635. for _, dev := range meta.devices() {
  636. if bytes.Equal(dev[:], device) {
  637. // Already handled above
  638. continue
  639. }
  640. fv, have := fl.Get(dev[:])
  641. if haveOldGlobal && need(oldGlobalFV, have, fv.Version) {
  642. meta.removeNeeded(dev, oldGlobal)
  643. }
  644. if need(globalFV, have, fv.Version) {
  645. meta.addNeeded(dev, global)
  646. }
  647. }
  648. return keyBuf, true, nil
  649. }
  650. func (t readWriteTransaction) updateGlobalGetGlobal(keyBuf, folder, name []byte, file protocol.FileInfo, insertedAt int, fl VersionList) (FileIntf, error) {
  651. if insertedAt == 0 {
  652. // Inserted a new newest version
  653. return file, nil
  654. }
  655. var err error
  656. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, fl.Versions[0].Device, name)
  657. if err != nil {
  658. return nil, err
  659. }
  660. global, ok, err := t.getFileTrunc(keyBuf, true)
  661. if err != nil {
  662. return nil, err
  663. }
  664. if !ok {
  665. return nil, errEntryFromGlobalMissing
  666. }
  667. return global, nil
  668. }
  669. func (t readWriteTransaction) updateGlobalGetOldGlobal(keyBuf, folder, name []byte, oldGlobalFV FileVersion) (FileIntf, error) {
  670. var err error
  671. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, oldGlobalFV.Device, name)
  672. if err != nil {
  673. return nil, err
  674. }
  675. oldGlobal, ok, err := t.getFileTrunc(keyBuf, true)
  676. if err != nil {
  677. return nil, err
  678. }
  679. if !ok {
  680. return nil, errEntryFromGlobalMissing
  681. }
  682. return oldGlobal, nil
  683. }
  684. func (t readWriteTransaction) updateLocalNeed(keyBuf, folder, name []byte, add bool) ([]byte, error) {
  685. var err error
  686. keyBuf, err = t.keyer.GenerateNeedFileKey(keyBuf, folder, name)
  687. if err != nil {
  688. return nil, err
  689. }
  690. if add {
  691. l.Debugf("local need insert; folder=%q, name=%q", folder, name)
  692. err = t.Put(keyBuf, nil)
  693. } else {
  694. l.Debugf("local need delete; folder=%q, name=%q", folder, name)
  695. err = t.Delete(keyBuf)
  696. }
  697. return keyBuf, err
  698. }
  699. func need(global FileVersion, haveLocal bool, localVersion protocol.Vector) bool {
  700. // We never need an invalid file.
  701. if global.Invalid {
  702. return false
  703. }
  704. // We don't need a deleted file if we don't have it.
  705. if global.Deleted && !haveLocal {
  706. return false
  707. }
  708. // We don't need the global file if we already have the same version.
  709. if haveLocal && localVersion.GreaterEqual(global.Version) {
  710. return false
  711. }
  712. return true
  713. }
  714. // removeFromGlobal removes the device from the global version list for the
  715. // given file. If the version list is empty after this, the file entry is
  716. // removed entirely.
  717. func (t readWriteTransaction) removeFromGlobal(gk, keyBuf, folder, device []byte, file []byte, meta *metadataTracker) ([]byte, error) {
  718. deviceID := protocol.DeviceIDFromBytes(device)
  719. l.Debugf("remove from global; folder=%q device=%v file=%q", folder, deviceID, file)
  720. fl, err := t.getGlobalVersionsByKey(gk)
  721. if backend.IsNotFound(err) {
  722. // We might be called to "remove" a global version that doesn't exist
  723. // if the first update for the file is already marked invalid.
  724. return keyBuf, nil
  725. } else if err != nil {
  726. return nil, err
  727. }
  728. if len(fl.Versions) == 0 {
  729. // Shouldn't ever happen, but doesn't hurt to handle.
  730. return keyBuf, t.Delete(gk)
  731. }
  732. oldGlobalFV := fl.Versions[0]
  733. fl, removedFV, removedAt := fl.pop(device)
  734. if removedAt == -1 {
  735. // There is no version for the given device
  736. return keyBuf, nil
  737. }
  738. var global FileIntf
  739. var gotGlobal, ok bool
  740. // Add potential needs of the removed device
  741. if len(fl.Versions) != 0 && !fl.Versions[0].Invalid && need(fl.Versions[0], false, protocol.Vector{}) && !need(oldGlobalFV, removedAt != -1, removedFV.Version) {
  742. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, fl.Versions[0].Device, file)
  743. if err != nil {
  744. return nil, err
  745. }
  746. global, ok, err = t.getFileTrunc(keyBuf, true)
  747. if err != nil {
  748. return nil, err
  749. } else if !ok {
  750. return nil, errEntryFromGlobalMissing
  751. }
  752. gotGlobal = true
  753. meta.addNeeded(deviceID, global)
  754. if bytes.Equal(protocol.LocalDeviceID[:], device) {
  755. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, file, true); err != nil {
  756. return nil, err
  757. }
  758. }
  759. }
  760. // Global hasn't changed, abort early
  761. if removedAt != 0 {
  762. l.Debugf("new global after remove: %v", fl)
  763. if err := t.Put(gk, mustMarshal(&fl)); err != nil {
  764. return nil, err
  765. }
  766. return keyBuf, nil
  767. }
  768. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, device, file)
  769. if err != nil {
  770. return nil, err
  771. }
  772. f, ok, err := t.getFileTrunc(keyBuf, true)
  773. if err != nil {
  774. return nil, err
  775. } else if !ok {
  776. return nil, errEntryFromGlobalMissing
  777. }
  778. meta.removeFile(protocol.GlobalDeviceID, f)
  779. // Remove potential device needs
  780. if fv, have := fl.Get(protocol.LocalDeviceID[:]); need(removedFV, have, fv.Version) {
  781. meta.removeNeeded(protocol.LocalDeviceID, f)
  782. if keyBuf, err = t.updateLocalNeed(keyBuf, folder, file, false); err != nil {
  783. return nil, err
  784. }
  785. }
  786. for _, dev := range meta.devices() {
  787. if bytes.Equal(dev[:], device) { // Was the previous global
  788. continue
  789. }
  790. if fv, have := fl.Get(dev[:]); need(removedFV, have, fv.Version) {
  791. meta.removeNeeded(deviceID, f)
  792. }
  793. }
  794. // Nothing left, i.e. nothing to add to the global counter below.
  795. if len(fl.Versions) == 0 {
  796. if err := t.Delete(gk); err != nil {
  797. return nil, err
  798. }
  799. return keyBuf, nil
  800. }
  801. // Add to global
  802. if !gotGlobal {
  803. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, fl.Versions[0].Device, file)
  804. if err != nil {
  805. return nil, err
  806. }
  807. global, ok, err = t.getFileTrunc(keyBuf, true)
  808. if err != nil {
  809. return nil, err
  810. }
  811. if !ok {
  812. return nil, errEntryFromGlobalMissing
  813. }
  814. }
  815. meta.addFile(protocol.GlobalDeviceID, global)
  816. l.Debugf("new global after remove: %v", fl)
  817. if err := t.Put(gk, mustMarshal(&fl)); err != nil {
  818. return nil, err
  819. }
  820. return keyBuf, nil
  821. }
  822. func (t readWriteTransaction) deleteKeyPrefix(prefix []byte) error {
  823. dbi, err := t.NewPrefixIterator(prefix)
  824. if err != nil {
  825. return err
  826. }
  827. defer dbi.Release()
  828. for dbi.Next() {
  829. if err := t.Delete(dbi.Key()); err != nil {
  830. return err
  831. }
  832. }
  833. return dbi.Error()
  834. }
  835. func (t *readWriteTransaction) withAllFolderTruncated(folder []byte, fn func(device []byte, f FileInfoTruncated) bool) error {
  836. key, err := t.keyer.GenerateDeviceFileKey(nil, folder, nil, nil)
  837. if err != nil {
  838. return err
  839. }
  840. dbi, err := t.NewPrefixIterator(key.WithoutNameAndDevice())
  841. if err != nil {
  842. return err
  843. }
  844. defer dbi.Release()
  845. var gk, keyBuf []byte
  846. for dbi.Next() {
  847. device, ok := t.keyer.DeviceFromDeviceFileKey(dbi.Key())
  848. if !ok {
  849. // Not having the device in the index is bad. Clear it.
  850. if err := t.Delete(dbi.Key()); err != nil {
  851. return err
  852. }
  853. continue
  854. }
  855. intf, err := t.unmarshalTrunc(dbi.Value(), true)
  856. if err != nil {
  857. return err
  858. }
  859. f := intf.(FileInfoTruncated)
  860. switch f.Name {
  861. case "", ".", "..", "/": // A few obviously invalid filenames
  862. l.Infof("Dropping invalid filename %q from database", f.Name)
  863. name := []byte(f.Name)
  864. gk, err = t.keyer.GenerateGlobalVersionKey(gk, folder, name)
  865. if err != nil {
  866. return err
  867. }
  868. keyBuf, err = t.removeFromGlobal(gk, keyBuf, folder, device, name, nil)
  869. if err != nil {
  870. return err
  871. }
  872. if err := t.Delete(dbi.Key()); err != nil {
  873. return err
  874. }
  875. continue
  876. }
  877. if !fn(device, f) {
  878. return nil
  879. }
  880. }
  881. return dbi.Error()
  882. }
  883. type marshaller interface {
  884. Marshal() ([]byte, error)
  885. }
  886. func mustMarshal(f marshaller) []byte {
  887. bs, err := f.Marshal()
  888. if err != nil {
  889. panic(err)
  890. }
  891. return bs
  892. }