aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 17:26:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 17:30:34 -0400
commit0056e65f9e28d83ee1a3fb4f7d0041e838f03c34 (patch)
treed19f284da83ab82dc45b293ca4c06df0bd136dff
parent660fc1f4d88b0f5e4bb936e4a5a9b95b70df9e58 (diff)
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>
-rw-r--r--fs/romfs/inode.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 8e51a2aaa977..60d2f822e87b 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -418,7 +418,8 @@ static int
418romfs_readpage(struct file *file, struct page * page) 418romfs_readpage(struct file *file, struct page * page)
419{ 419{
420 struct inode *inode = page->mapping->host; 420 struct inode *inode = page->mapping->host;
421 loff_t offset, avail, readlen; 421 loff_t offset, size;
422 unsigned long filled;
422 void *buf; 423 void *buf;
423 int result = -EIO; 424 int result = -EIO;
424 425
@@ -430,21 +431,29 @@ romfs_readpage(struct file *file, struct page * page)
430 431
431 /* 32 bit warning -- but not for us :) */ 432 /* 32 bit warning -- but not for us :) */
432 offset = page_offset(page); 433 offset = page_offset(page);
433 if (offset < i_size_read(inode)) { 434 size = i_size_read(inode);
434 avail = inode->i_size-offset; 435 filled = 0;
435 readlen = min_t(unsigned long, avail, PAGE_SIZE); 436 result = 0;
436 if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) { 437 if (offset < size) {
437 if (readlen < PAGE_SIZE) { 438 unsigned long readlen;
438 memset(buf + readlen,0,PAGE_SIZE-readlen); 439
439 } 440 size -= offset;
440 SetPageUptodate(page); 441 readlen = size > PAGE_SIZE ? PAGE_SIZE : size;
441 result = 0; 442
443 filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen);
444
445 if (filled != readlen) {
446 SetPageError(page);
447 filled = 0;
448 result = -EIO;
442 } 449 }
443 } 450 }
444 if (result) { 451
445 memset(buf, 0, PAGE_SIZE); 452 if (filled < PAGE_SIZE)
446 SetPageError(page); 453 memset(buf + filled, 0, PAGE_SIZE-filled);
447 } 454
455 if (!result)
456 SetPageUptodate(page);
448 flush_dcache_page(page); 457 flush_dcache_page(page);
449 458
450 unlock_page(page); 459 unlock_page(page);