On Fri, Jun 8, 2012 at 8:13 PM, Boaz Harrosh <bharrosh@xxxxxxxxxxx> wrote: > > 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 <stable@xxxxxxxxxx> > Signed-off-by: Boaz Harrosh <bharrosh@xxxxxxxxxxx> > --- > fs/nfs/objlayout/objio_osd.c | 24 +++++++++++++++++++++--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c > index b47277b..0e7c833 100644 > --- a/fs/nfs/objlayout/objio_osd.c > +++ b/fs/nfs/objlayout/objio_osd.c > @@ -480,14 +480,28 @@ static void _write_done(struct ore_io_state *ios, void *private) > objlayout_write_done(&objios->oir, status, objios->sync); > } > > +static struct page *g_zero_page; > + Since you don't attach g_zero_page to any file's address space, I think that you can replace it with ZERO_PAGE(0), no? Cheers, Tao > static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) > { > struct objio_state *objios = priv; > struct nfs_write_data *wdata = objios->oir.rpcdata; > struct address_space *mapping = wdata->header->inode->i_mapping; > pgoff_t index = offset / PAGE_SIZE; > - struct page *page = find_get_page(mapping, index); > + struct page *page; > + loff_t i_size = i_size_read(wdata->header->inode); > + > + if (offset >= i_size) { > + if (!g_zero_page) { > + g_zero_page = alloc_page(GFP_NOFS); > + clear_highpage(g_zero_page); > + } > + *uptodate = true; > + dprintk("%s: g_zero_page index=0x%lx\n", __func__, index); > + return g_zero_page; > + } > > + page = find_get_page(mapping, index); > if (!page) { > page = find_or_create_page(mapping, index, GFP_NOFS); > if (unlikely(!page)) { > @@ -507,8 +521,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) > > static void __r4w_put_page(void *priv, struct page *page) > { > - dprintk("%s: index=0x%lx\n", __func__, page->index); > - page_cache_release(page); > + dprintk("%s: index=0x%lx\n", __func__, > + (page == g_zero_page) ? -1UL : page->index); > + if (g_zero_page != page) > + page_cache_release(page); > return; > } > > @@ -615,6 +631,8 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, > static void __exit > objlayout_exit(void) > { > + if (g_zero_page) > + __free_page(g_zero_page); > pnfs_unregister_layoutdriver(&objlayout_type); > printk(KERN_INFO "NFS: %s: Unregistered OSD pNFS Layout Driver\n", > __func__); > -- > 1.7.10.2.677.gb6bc67f > > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html