Skip to content
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

Extend supported range requests for large files on 64-bit hosts #59

Closed
wants to merge 1 commit into from
Closed

Conversation

jonathonf
Copy link
Contributor

@jonathonf jonathonf commented Apr 2, 2021

This extends the supported range request sizes and thereby allows download of larger files on 64-bit hosts. Based on initial work by @ghuls (within #31 comments) and @TotallyNotElite (JustTNE@aa5d024)

{
if((file->buffer_pos - want) <= 0){
if(file->buffer_pos <= want){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the type of buffer_pos?

You should use a fixed 64-bit type like uint64_t, or unsigned long long. On 32-bit architectures, size_t is 4 bytes in size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these need to have a real 8-byte size type like uint64_t. I'm very certain size_t will be too small on 32-bit, same goes for off_t. I just tried with gcc -m32:

#include <stdio.h>
#include <sys/types.h>

int main() {
    printf("%lu\n", sizeof(off_t));
}

It's generally a good idea to use fixed-size types, as they're predictable and not compiler-dependent. And in this case, it's even a must, since we also have 32-bit binaries. You can't support big files on 64-bit only.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, by the way, the big issue with the patch in #31.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that just opening a 2GB+ file with a 32-bit build is currently broken, e.g. at

https://github.com/AppImage/zsync2/blob/86cfd3a1d6a27483ec40edd62c1a6bd409cbbe5d/src/zsclient.cpp#L986

so just increasing type size on those systems won't help.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be. But I don't see the point in accepting a pull request that doesn't completely solve an issue, while it claims to do so. Renaming the PR doesn't make things better, really.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR was renamed specifically because you pointed out that it doesn't actually solve the whole issue, yet does still improve things for 64-bit builds (i.e. a 64-bit build can download files larger than 2GB, which, for me at least, makes things better than when #31 was opened in 2018).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument is nonsense. There is no reason not to just swap the types you change anyway for ones that actually work on 32-bit as well. It doesn't have to make 32-bit work entirely... Nobody requested this.

But your PR is really off-putting in that its argument is "at least it's better than nothing". Of course, a full-featured 32-bit fix would be nice. But I'm certain you won't be willing to work on that. At least you could fix the types in the lines you touch anyway, permanently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't have to make 32-bit work entirely... Nobody requested this

I may have misinterpreted this statement:

I don't see the point in accepting a pull request that doesn't completely solve an issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is, if you know an exact set of lines has to be touched in the future because the data types don't work on one platform properly, it really makes sense to just use the future proof data type. I basically had to re-do your changes to change the types to the future proof ones. This resulted in twice the work overall.

@jonathonf jonathonf changed the title Extend supported range requests for large files Extend supported range requests for large files on 64-bit hosts Apr 2, 2021
@TheAssassin
Copy link
Member

I did it myself now, in 1 minute plus 2 minutes of committing. Thanks for bringing this issue up on my desk again, at least.

@jonathonf
Copy link
Contributor Author

Great, thanks. Good to see some incremental improvements.

@jonathonf jonathonf deleted the large-files branch April 3, 2021 00:14
@ghuls
Copy link

ghuls commented Jul 20, 2022

For opening large file with a 32-bit binary, you need to enable 32-bit support large file support.
This should at least work with g++ on Linux.

Add the option -D_LARGE_FILE_SOURCE=1 to gcc compilation.

fseek64() is a C function. To make it available you'll have to define _FILE_OFFSET_BITS=64 before including the system headers. That will more or less define fseek to behave as actually fseek64. Or you could do it in the compiler arguments e.g. gcc -D_FILE_OFFSET_BITS=64, that you are already doing.

Compile your programs with gcc -D_FILE_OFFSET_BITS=64. This forces all file access calls to use the 64 bit variants. Several types change also, e.g. off_t becomes off64_t. It's therefore important to always use the correct types and to not use e.g. int instead of off_t in your C code. For portability with other platforms you should use getconf LFS_CFLAGS which will return -D_FILE_OFFSET_BITS=64 on Linux platforms but might return something else on for e.g. on Solaris. For linking, you should use the link flags that are reported via getconf LFS_LDFLAGS. On Linux systems, you do not need special link flags. Define _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE. With these defines you can use the LFS functions like open64 directly. Use the O_LARGEFILE flag with open to operate on large files.

https://stackoverflow.com/questions/14533836/large-file-support-not-working-in-c-programming

https://stackoverflow.com/questions/965725/large-file-support-in-c

NiLuJe pushed a commit to NiLuJe/zsync2 that referenced this pull request Jan 19, 2024
Apparently, only a few lines have to be changed in order to support
large(r) files on 64-bit machines.

This commit doesn't (yet) fix the issue on 32-bit machines (it also
doesn't test this explicitly). In comparison to AppImageCommunity#59, however, it uses
types that help get this to work on 32-bit machines as well, as it
doesn't use compiler-dependent types, but types that are known to be
large enough even there.

Closes AppImageCommunity#59.

CC AppImageCommunity#31.

(cherry picked from commit a8e2d68)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants