equalitie / ouisync

A secure peer-to-peer file synchronization app.
https://ouisync.net
Mozilla Public License 2.0
49 stars 9 forks source link

Partially merged directory might get prematurelly garbage collected, breaking subsequent sync #146

Closed madadam closed 1 year ago

madadam commented 1 year ago

Consider two replicas, A and B, where A is initially empty and B has the following content:

\          vv={A: 0, B: 3}
  dir      vv={A: 0, B: 2}
    subdir vv={A: 0, B: 1}

When during sync it can happen that the block of dir is already present in A but the block of subdir is not. Then during merge A first starts merging dir which creates an empty directory in A's branch whose version vector is {A: 0, B: 1} (which is the initial version vector dir was originally created with by B) and then proceeds to merge subdir. But because the block of subdir is missing, this fails and the merge ends. This leaves dir in B's branch (vv = {A: 0, B: 2}) as happens-after the one in A's branch (vv = {A: 0, B: 1}). Then when the trash job starts, it identifies the blocks of A's dir as unreachable and removes then both from the block store and the index. Then later when another merge job starts, it tries to open dir in both branches, but the one in A's branch fails on LocatorNotFound because it was previously garbage collected which fails the whole merge job. This situation is then never resolved and so A never gets synced.