On Wed, Dec 14, 2016 at 11:27 AM, Joseph Salisbury <joseph.salisbury@xxxxxxxxxxxxx> wrote: > > A kernel bug report was opened against Ubuntu [0]. It was found that > reverting the following commit resolved this bug: > > commit c2a9737f45e27d8263ff9643f994bda9bac0b944 > > [0] http://pad.lv/1649342 Hah. Looks like a rather special corner case for s_maxbytes. I think what is going on is that the read() at the end of the file should return 0, not EINVAL. And nobody normally notices, because nobody ever hits s_maxbytes in any normal situation. Anyway, does this stupid one-liner fix the problem? By definition, if *ppos >= inode->i_sb->s_maxbytes, then we must be at or past the end of the file, and so the read() should return 0. 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. Linus
mm/filemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index 69568388c699..b06517b7f97f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1637,7 +1637,7 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, int error = 0; if (unlikely(*ppos >= inode->i_sb->s_maxbytes)) - return -EINVAL; + return 0; iov_iter_truncate(iter, inode->i_sb->s_maxbytes); index = *ppos >> PAGE_SHIFT;