Skip to content

Commit c999ff6

Browse files
author
Boaz Harrosh
committed
pnfs-obj: 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. TODO: Change the API to ->__r4w_get_page() so a NULL can be returned without being considered as error, since XOR API treats NULL entries as zero_pages. [Bug since 3.2. Should apply the same way to all Kernels since] CC: Stable Tree <[email protected]> Signed-off-by: Boaz Harrosh <[email protected]>
1 parent 9909d45 commit c999ff6

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

fs/nfs/objlayout/objio_osd.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
489489
struct nfs_write_data *wdata = objios->oir.rpcdata;
490490
struct address_space *mapping = wdata->header->inode->i_mapping;
491491
pgoff_t index = offset / PAGE_SIZE;
492-
struct page *page = find_get_page(mapping, index);
492+
struct page *page;
493+
loff_t i_size = i_size_read(wdata->header->inode);
493494

495+
if (offset >= i_size) {
496+
*uptodate = true;
497+
dprintk("%s: g_zero_page index=0x%lx\n", __func__, index);
498+
return ZERO_PAGE(0);
499+
}
500+
501+
page = find_get_page(mapping, index);
494502
if (!page) {
495503
page = find_or_create_page(mapping, index, GFP_NOFS);
496504
if (unlikely(!page)) {
@@ -510,8 +518,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
510518

511519
static void __r4w_put_page(void *priv, struct page *page)
512520
{
513-
dprintk("%s: index=0x%lx\n", __func__, page->index);
514-
page_cache_release(page);
521+
dprintk("%s: index=0x%lx\n", __func__,
522+
(page == ZERO_PAGE(0)) ? -1UL : page->index);
523+
if (ZERO_PAGE(0) != page)
524+
page_cache_release(page);
515525
return;
516526
}
517527

0 commit comments

Comments
 (0)