Re: [v4.9 Regression] vfs,mm: fix a dead loop in truncate_inode_pages_range()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;

[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]