diff --git a/CHANGES.md b/CHANGES.md index 8dd8636a..574da20e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - Lock files are now opened with O_CLOEXEC flag (#394, @vect0r-vicall) - Update to cmdliner.1.1.0 (#382, @MisterDA) - Mirage support: optional dependency to unix (#396, @art-w) +- Fix RO sync: clear LRU for all log updates (#399, @art-w) # 1.6.2 (2023-06-06) diff --git a/bench/dune b/bench/dune index 33a8236a..482b7064 100644 --- a/bench/dune +++ b/bench/dune @@ -26,7 +26,7 @@ (preprocess (pps ppx_repr)) (libraries index index.unix unix cmdliner logs repr ppx_repr common - tezos-base58 optint fmt rusage mtime mtime.clock.os digestif)) + digestif.ocaml tezos-base58 optint fmt rusage mtime mtime.clock.os)) ;; Require the above executables to compile during tests diff --git a/src/index.ml b/src/index.ml index 6dde17a4..37a5f7d0 100644 --- a/src/index.ml +++ b/src/index.ml @@ -310,12 +310,14 @@ struct Log_file.close log; (* check that file is on disk, reopen and reload everything. *) hook `Reload_log_async; + Lru.clear t.lru; t.log_async <- try_load_log t (Layout.log_async ~root:t.root) (* else if the disk offset is greater, reload the newest data. *)) - else if old_offset < h.offset then + else if old_offset < h.offset then ( + Lru.clear t.lru; Log_file.sync_entries ~min:old_offset log (* else if the offset is lesser, that means the [log_async] was - cleared, and the generation should have changed. *) + cleared, and the generation should have changed. *)) else if old_offset > h.offset then ( (* Should never occur, but we can recover by reloading the log from scratch rather than just hard failing. *) @@ -397,6 +399,7 @@ struct Log.debug (fun l -> l "[%s] new entries detected, reading log from disk" (Filename.basename t.root)); + Lru.clear t.lru; Log_file.sync_entries ~min:log_offset log) else (* Here the disk offset should be equal to the known one. A smaller diff --git a/test/issues/dune b/test/issues/dune new file mode 100644 index 00000000..aa34288d --- /dev/null +++ b/test/issues/dune @@ -0,0 +1,4 @@ +(test + (name issue398) + (modules issue398) + (libraries index index.unix)) diff --git a/test/issues/issue398.ml b/test/issues/issue398.ml new file mode 100644 index 00000000..4e5b2d6e --- /dev/null +++ b/test/issues/issue398.ml @@ -0,0 +1,23 @@ +(* See https://github.com/mirage/index/issues/398 *) + +module L = struct + let length = 4 +end + +module I = + Index_unix.Make + (Index.Key.String_fixed (L)) (Index.Value.String_fixed (L)) + (Index.Cache.Noop) + +let () = + let path = "issue398.index" in + let t = I.v path ~log_size:16384 in + let ro = I.v path ~readonly:true ~log_size:16384 in + I.replace t "1234" "aaaa"; + I.flush t; + I.sync ro; + assert (I.find ro "1234" = "aaaa"); + I.replace t "1234" "aaab"; + I.flush t; + I.sync ro; + assert (I.find ro "1234" = "aaab")