-
Notifications
You must be signed in to change notification settings - Fork 3.5k
fix(mmap): handle over-allocated files #10526
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
fix(mmap): handle over-allocated files #10526
Conversation
5b0585e to
0e4bb32
Compare
sbc100
left a comment
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.
Thanks for the fix!
A few style nits in the test but otherwise looks good.
tests/fs/test_mmap.c
Outdated
|
|
||
| char *map; | ||
|
|
||
| map = (char*)mmap(NULL, textsize, PROT_READ, 0, fd, 0); |
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.
these two lines can be a single line.
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.
should be ok now
tests/fs/test_mmap.c
Outdated
| { | ||
| const char* path = "/yolo/expandedfile.txt"; | ||
|
|
||
| int fd = open(path, O_RDWR | O_CREAT, (mode_t)0600); |
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.
Just inline path since its only used once.
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.
should be ok now
tests/fs/test_mmap.c
Outdated
| size_t textsize = 33; | ||
|
|
||
| // multiple calls to write so that the file is expanded | ||
| for(int n=0;n<textsize;n++) { |
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.
space after for and between all the operators.
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.
looking better now?
tests/fs/test_mmap.c
Outdated
| } | ||
|
|
||
| /** | ||
| * MMAP to and expanded file |
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.
Is "expanded file" terminology that is used elsewhere? How about "over-allocated memfs file"?
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.
I chose the term expanded file because the "expansion" is done by a method called expandFileStorage which you can see here:
emscripten/src/library_memfs.js
Line 115 in 0e4bb32
| expandFileStorage: function(node, newCapacity) { |
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.
To me expanded file doesn't hold the right meaning. The expandFileStorage may or may not over-allocate, right? But its the fact the you over-allocate the storage that is key here IIUC, no? I could be wrong.. I didn't write the memfs code so maybe expanded file means more to the authors of this code.
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.
when appending to a file expandFileStorage will increase the buffer size for that file more than the bytes requested to be written. This is to avoid having to increase the buffer for every call to write (which would be very slow). So instead the actual file size is tracked in a separate property called usedBytes.
mmap allocates memory based on the usedBytes, and calls javascripts ArrayBuffer set method on the heap with the files buffer as parameter. The set method has no parameter for the length, and so it copies the full contents of the file buffer. To avoid copying more than the actual file size the file buffer is sliced before calling set, but before this fix, slicing would only occur if the requested length was less than used bytes (which is mostly not the case if mapping the entire file). So instead the criteria for slicing must be if the requested length is less than the length of the file buffer - which is normally more than usedBytes for expanded files.
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.
but yes - expandFileStorage does over-allocate file storage in that sense. Just wouldn't confuse it with over-allocating of heap, since the case here is that mmap writes beyond what it allocated on the heap.
not sure what the best term here is though. Maybe we need more opinions?
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.
I guess you could call it "over-sized" if you prefer? But I think over-allocated is pretty clear and applies to any object that is larger than needs to be to make room for future expansion. We can let @kripken have the final say :)
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.
I don't have a strong opinion on the term, but "over-allocated" does seem pretty reasonable, let's change to that?
Also and should be an in the comment.
0e4bb32 to
9034ec3
Compare
|
thanks for the review @sbc100 :-) Would be great to have this merged. libgit2/libgit2#5345 depends on this |
|
@kripken can you give final lgtm here? |
kripken
left a comment
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.
Nice, thanks @petersalomonsen !
tests/fs/test_mmap.c
Outdated
| } | ||
|
|
||
| /** | ||
| * MMAP to and expanded file |
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.
I don't have a strong opinion on the term, but "over-allocated" does seem pretty reasonable, let's change to that?
Also and should be an in the comment.
fix for files with buffers larger than the file size where contents were written beyond memory allocated for the map fixes emscripten-core#10527
9034ec3 to
cf63447
Compare
|
Thanks for reviewing! |
fix for not writing buffer contents from expanded files beyond allocated memory
fixes #10527