-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
fix(mmap): handle over-allocated files #10526
Conversation
5b0585e
to
0e4bb32
Compare
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
@@ -176,5 +176,53 @@ int main() { | |||
printf("/yolo/sharedoffset.txt content=%s %d\n", buffer + offset, offset); | |||
fclose(fd); | |||
} | |||
|
|||
/** | |||
* 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? |
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
@@ -176,5 +176,53 @@ int main() { | |||
printf("/yolo/sharedoffset.txt content=%s %d\n", buffer + offset, offset); | |||
fclose(fd); | |||
} | |||
|
|||
/** | |||
* 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