From c4e1ec3d09da72c78e40fa2686c0d557cb8741f3 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 25 May 2015 23:34:54 +0100 Subject: [PATCH] More WIP: refine interleaving argument for Windows. Signed-off-by: Daira Hopwood --- .../magic-folder/remote-to-local-sync.rst | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/docs/proposed/magic-folder/remote-to-local-sync.rst b/docs/proposed/magic-folder/remote-to-local-sync.rst index d169edf8..7340bd8c 100644 --- a/docs/proposed/magic-folder/remote-to-local-sync.rst +++ b/docs/proposed/magic-folder/remote-to-local-sync.rst @@ -264,8 +264,13 @@ Folder. Conflict Detection and Resolution --------------------------------- -In our discussion of design issues for conflict detection and resolution, -we classified various problems as "dragons", which as a convenient +The combination of local filesystems and distributed objects is +an example of shared state concurrency, which is highly error-prone +and can result in race conditions that are complex to analyse. +Unfortunately we have no option but to use shared state in this +situation. + +We call the resulting design issues "dragons", which as a convenient mnemonic we have named after the five classical Greek elements (Earth, Air, Water, Fire and Aether). @@ -439,7 +444,7 @@ interleaving with four as on Unix). The cases are: Its changes end up at ``foo.old``, and ours end up at ``foo`` after being linked there in step 4c. This avoids data loss. -* Interleaving X′: the other process' deletion of ``foo`` precedes +* Interleaving C′: the other process' deletion of ``foo`` precedes our rename of ``foo`` to ``foo.old`` done by `ReplaceFileW`_, but its rename of ``foo.other`` to ``foo`` does not, so we get an ``ERROR_FILE_NOT_FOUND`` error from `ReplaceFileW`_ indicating @@ -448,15 +453,22 @@ interleaving with four as on Unix). The cases are: it has renamed ``foo.other`` to ``foo``) and our changes end up at ``foo.conflicted``. This avoids data loss. -* Interleaving C′: its deletion happens during the call to - `ReplaceFileW`_, causing the latter to fail with an ... error. - We reclassify as a conflict; the old version ends up at - ``foo.old``, the other process' changes end up at ``foo``, and - ours at ``foo.conflicted``. This avoids data loss. - -* Interleaving D′: its rename happens after all internal operations - of `ReplaceFileW`_ have completed, and causes a corresponding event - for ``foo``. Its rename also changes the ``mtime`` for ``foo`` so +* Interleaving D′: the other process' deletion and/or rename happen + during the call to `ReplaceFileW`_, causing the latter to fail. + There are two subcases: + * if the error is ``ERROR_UNABLE_TO_MOVE_REPLACEMENT_2``, then + ``foo`` is renamed to ``foo.old`` and ``.foo.tmp`` remains + at its original name after the call. + * for all other errors, ``foo`` and ``.foo.tmp`` both remain at + their original names after the call. + In both cases, we reclassify as a conflict and rename ``.foo.tmp`` + to ``foo.conflicted``. This avoids data loss. + +* Interleaving E′: the other process' deletion of ``foo`` and attempt + to rename ``foo.other`` to ``foo`` both happen after all internal + operations of `ReplaceFileW`_ have completed. This causes an event + for ``foo`` (the deletion and rename events are merged due to the + pending delay). The rename also changes the ``mtime`` for ``foo`` so that it is different from the ``mtime`` calculated in step 3, and therefore different from the metadata recorded for ``foo`` in the magic folder db. (Assuming no system clock changes, its rename will @@ -467,15 +479,6 @@ interleaving with four as on Unix). The cases are: granularity.) Therefore, an upload will be triggered for ``foo`` after its change, which is correct and avoids data loss. -[FIXME probably wrong -Because the steps on Windows correspond to those on Unix except -for combining two steps, the set of possible interleavings is a -subset of that on Unix. Therefore, the possible outcomes are also -a subset of those on Unix. (The possibility of ending up with two -links at ``foo`` and ``.foo.tmp`` is excluded. Also there is an -additional failure case where 4b′ fails because ``foo.old`` already -exists; this does not cause data loss.)] - .. _`MoveFileExW`: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365240%28v=vs.85%29.aspx We also need to consider what happens if another process opens ``foo`` -- 2.45.2