Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

romfs_readpage: don't report errors for pages beyond i_size

We zero-fill them like we are supposed to, and that's all fine. It's
only an error if the 'romfs_copyfrom()' routine isn't able to fill the
data that is supposed to be there.

Most of the patch is really just re-organizing the code a bit, and using
separate variables for the error value and for how much of the page we
actually filled from the filesystem.

Reported-and-tested-by: Chris Fester <cfester@wms.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Matt Waddel <matt.waddel@freescale.com>
Cc: Greg Ungerer <gerg@snapgear.com>
Signed-of-by: Linus Torvalds <torvalds@linux-foundation.org>

+23 -14
+23 -14
fs/romfs/inode.c
··· 418 418 romfs_readpage(struct file *file, struct page * page) 419 419 { 420 420 struct inode *inode = page->mapping->host; 421 - loff_t offset, avail, readlen; 421 + loff_t offset, size; 422 + unsigned long filled; 422 423 void *buf; 423 424 int result = -EIO; 424 425 ··· 431 430 432 431 /* 32 bit warning -- but not for us :) */ 433 432 offset = page_offset(page); 434 - if (offset < i_size_read(inode)) { 435 - avail = inode->i_size-offset; 436 - readlen = min_t(unsigned long, avail, PAGE_SIZE); 437 - if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) { 438 - if (readlen < PAGE_SIZE) { 439 - memset(buf + readlen,0,PAGE_SIZE-readlen); 440 - } 441 - SetPageUptodate(page); 442 - result = 0; 433 + size = i_size_read(inode); 434 + filled = 0; 435 + result = 0; 436 + if (offset < size) { 437 + unsigned long readlen; 438 + 439 + size -= offset; 440 + readlen = size > PAGE_SIZE ? PAGE_SIZE : size; 441 + 442 + filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen); 443 + 444 + if (filled != readlen) { 445 + SetPageError(page); 446 + filled = 0; 447 + result = -EIO; 443 448 } 444 449 } 445 - if (result) { 446 - memset(buf, 0, PAGE_SIZE); 447 - SetPageError(page); 448 - } 450 + 451 + if (filled < PAGE_SIZE) 452 + memset(buf + filled, 0, PAGE_SIZE-filled); 453 + 454 + if (!result) 455 + SetPageUptodate(page); 449 456 flush_dcache_page(page); 450 457 451 458 unlock_page(page);