aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2012-07-20 08:50:27 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2012-08-02 07:58:22 -0400
commit4b74f6ea8417e48bb1fc65880a0574134a8b4745 (patch)
treec0fec691c12f1efa3f8fa74d1b113a88b98d15c7 /fs/exofs
parent66153f6e0f89c75d18e490739b0149dfd2e53b69 (diff)
exofs: Fix __r4w_get_page when offset is beyond i_size
It is very common for the end of the file to be unaligned on stripe size. But since we know it's beyond file's end then the XOR should be preformed with all zeros. Old code used to just read zeros out of the OSD devices, which is a great waist. But what scares me more about this situation is that, we now have pages attached to the file's mapping that are beyond i_size. I don't like the kind of bugs this calls for. Fix both birds, by returning a global ZERO_PAGE, if offset is beyond i_size. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs')
-rw-r--r--fs/exofs/inode.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 9a5ed30b8a35..3b2ee72aecbe 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -574,8 +574,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
574 574
575 if (!pcol->that_locked_page || 575 if (!pcol->that_locked_page ||
576 (pcol->that_locked_page->index != index)) { 576 (pcol->that_locked_page->index != index)) {
577 struct page *page = find_get_page(pcol->inode->i_mapping, index); 577 struct page *page;
578 loff_t i_size = i_size_read(pcol->inode);
578 579
580 if (offset >= i_size) {
581 *uptodate = true;
582 EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index);
583 return ZERO_PAGE(0);
584 }
585
586 page = find_get_page(pcol->inode->i_mapping, index);
579 if (!page) { 587 if (!page) {
580 page = find_or_create_page(pcol->inode->i_mapping, 588 page = find_or_create_page(pcol->inode->i_mapping,
581 index, GFP_NOFS); 589 index, GFP_NOFS);
@@ -604,12 +612,13 @@ static void __r4w_put_page(void *priv, struct page *page)
604{ 612{
605 struct page_collect *pcol = priv; 613 struct page_collect *pcol = priv;
606 614
607 if (pcol->that_locked_page != page) { 615 if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) {
608 EXOFS_DBGMSG("index=0x%lx\n", page->index); 616 EXOFS_DBGMSG("index=0x%lx\n", page->index);
609 page_cache_release(page); 617 page_cache_release(page);
610 return; 618 return;
611 } 619 }
612 EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index); 620 EXOFS_DBGMSG("that_locked_page index=0x%lx\n",
621 ZERO_PAGE(0) == page ? -1 : page->index);
613} 622}
614 623
615static const struct _ore_r4w_op _r4w_op = { 624static const struct _ore_r4w_op _r4w_op = {