On Wed, Dec 14, 2016 at 12:27 PM, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > The EINVAL was always wrong, I think, but it made some (bad) sense > when you think of the issue as being the result of somebody trying to > do something bad. But it isn't actually an error. Here's an example program that I think shows this on pretty much any filesystem. Run with something like strace ./a.out < ./a.out and then look at the final part of the trace, which will look something like lseek(0, 17592186040320, SEEK_SET) = 17592186040320 read(0, 0x7ffe1d2df140, 10) = -1 EINVAL (Invalid argument) lseek(0, 17592186040319, SEEK_SET) = 17592186040319 read(0, "", 10) = 0 and that EINVAL from the first read is just bogus and wrong. We're clearly at a good offset - the lseek() succeeded - and we're clearly past the end of the file, so we should be returning 0 (for that EOF). And the second read succeeds just because we've done a seek to one byte less. I'm not guaranteeing that I got that stupid binary search for the filesystem s_maxsize right, but it worked for me. This is a truly crappy test program, but whatever. Linus --- #define _LARGEFILE64_SOURCE #include <sys/types.h> #include <unistd.h> int main(int argc, char **argv) { char buf[10]; off64_t large_offset = 1000000; off64_t max_offset = (~(unsigned long long)0)>>1; for (;;) { off64_t try_offset = (unsigned long long)(max_offset + large_offset + 1)/2; if (try_offset >= max_offset) break; if (lseek64(0, try_offset, SEEK_SET) < 0) max_offset = try_offset; else large_offset = try_offset; } lseek64(0, large_offset, SEEK_SET); read(0, buf, 10); lseek64(0, large_offset-1, SEEK_SET); read(0, buf, 10); return 0; } -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html