-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
irmin-pack: Fix data race in control file reads #2100
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -211,6 +211,23 @@ module Unix = struct | |
| Errors.Closed -> Error `Closed | ||
| Unix.Unix_error (e, s1, s2) -> Error (`Io_misc (e, s1, s2)) | ||
|
||
let page_size = 4096 | ||
|
||
let read_all_to_string t = | ||
let buf = Buffer.create 0 in | ||
let len = page_size in | ||
let bytes = Bytes.create len in | ||
let rec aux ~off = | ||
let nread = Util.really_read t.fd off len bytes in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You still have a data race here if the RW instance updates the file between two short reads, don't you? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two thoughts:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is how my patch functions:
Following your reviews I've changed my code in the following manner:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If you assume an underlying There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that case we will need to add a checksum in the control file (cc @art-w). At least this PR fixes the issue for some file systems. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea it's great to improve the current situation - it's also nice to be clear about the limitations. Are the RO instance re-reading the full files on every "sync"? The only way to get atomic writes in POSIX is via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes.
I see, thanks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you update the comments in the code to reflect that reads might not be atomic - this can be misleading for critical pieces of code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in #2107 |
||
if nread > 0 then ( | ||
Buffer.add_subbytes buf bytes 0 nread; | ||
aux ~off:Int63.(add off (of_int nread))) | ||
in | ||
try | ||
aux ~off:Int63.zero; | ||
Ok (Buffer.contents buf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe, just to be very clear, add a comment about |
||
with Unix.Unix_error (e, s1, s2) -> Error (`Io_misc (e, s1, s2)) | ||
|
||
let read_size t = | ||
match t.closed with | ||
| true -> Error `Closed | ||
|
@@ -220,7 +237,6 @@ module Unix = struct | |
|
||
let readonly t = t.readonly | ||
let path t = t.path | ||
let page_size = 4096 | ||
|
||
let move_file ~src ~dst = | ||
try | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the RW instance updates the file between the
read_size
and theread_to_string
we would have a problem